Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_app_service - way to get 'Custom Domain Verification ID' #7537

Closed
ghost opened this issue Jun 30, 2020 · 21 comments · Fixed by #9378
Closed

azurerm_app_service - way to get 'Custom Domain Verification ID' #7537

ghost opened this issue Jun 30, 2020 · 21 comments · Fixed by #9378

Comments

@ghost
Copy link

ghost commented Jun 30, 2020

This issue was originally opened by @jonsamwell as hashicorp/terraform#25432. It was migrated here as a result of the provider split. The original body of the issue is below.


I need a way to get the Custom Domain Verification ID of an azure web app so that I can automate binding a custom host name.

image

I've looked through all the exported attributes when using azurerm_app_service but I am unable to find a way to get the verification id which I can use to add a TXT record to an Azure DNS zone then bind a custom host name without performing the verification step manually.

This is a big hole in our environment creation process we would like to automate.

Sorry if I missed anything!

Thanks!

@neil-yechenwei
Copy link
Contributor

Thanks for opening this issue. Seems it's an API restriction. So I assume terraform cannot support this property since API doesn't support it after went through the api doc.

@jonsamwell
Copy link

@neil-yechenwei yeah seems like a bit of a hole in the api. I've filled a feature request with azure team so hopefully they will come back with something.

Azure/azure-cli#14142

@tombuildsstuff tombuildsstuff added question upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR labels Jul 2, 2020
@peter-dolkens
Copy link

It's possible to use terraform to provision these already - see the original issue for further details.

@tombuildsstuff
Copy link
Contributor

I don't have one configured to test - but presumably this is this endpoint in the API?

@rluiten
Copy link

rluiten commented Jul 15, 2020

@peter-dolkens when you say they can be provisioned already are you talking about using the "awverify." prefix on the domain and site reference in a CNAME or TXT record.

I have setup the following via terraform and aws provider.
The following domains (domains are hosted by AWS in route53 if it matters)

  • robintest1-dom.ourdomain.com. CNAME robintest1ae.azurewebsites.net
  • awverify.robintest1-dom.ourdomain.com. CNAME awverify.robintest1ae.azurewebsites.net

I still can't bind in terraform using azurerm_app_service_custom_hostname_binding the domain name robintest1-dom.ourdomain.com to our app service named robintest1ae.

Have you got any further information in relation to this ?

@peter-dolkens
Copy link

@rluiten does AWS route53 do any proxying or similar magic? It may simply come down to how long it takes DNS to propagate from AWS

In cloudflare, you can either proxy a record, or pass it through raw, and it normally only takes 30-60s to propagate.

Our stack looks like this:


resource "azurerm_app_service" "app_service" {
    name                            = var.app_service_name
    location                        = var.azure_region
    resource_group_name             = var.resource_group_name
    app_service_plan_id             = var.app_service_plan_id
}

resource "cloudflare_record" "verify_entry" {
    zone_id                         = var.cloudflare_zone_id
    name                            = "awverify.${var.domain_name}"
    type                            = "TXT"
    value                           = "awverify.${azurerm_app_service.app_service.default_site_hostname}"
}

resource "cloudflare_record" "domain_entry" {
    zone_id                         = var.cloudflare_zone_id
    name                            = var.domain_name_prefix
    type                            = "CNAME"
    proxy                           = true
    value                           = azurerm_app_service.app_service.default_site_hostname
}

resource "null_resource" "dns-awverify-pause" {
    provisioner "local-exec" {
        command                     = "sleep 30"
    }
    triggers                        = {
        "before"                    = cloudflare_record.verify_entry.id
    }
}

resource "azurerm_app_service_custom_hostname_binding" "custom_domain" {
    hostname                        = var.domain_name
    app_service_name                = azurerm_app_service.app_service.name
    resource_group_name             = var.resource_group_name

    depends_on                      = [
        azurerm_app_service.app_service,
        cloudflare_record.verify_entry,
        cloudflare_record.domain_entry
    ]
}

@rluiten
Copy link

rluiten commented Jul 16, 2020

Thanks for the response.
What you present is equivalent to what I have setup.
At least I didn't miss understand the pattern.

I don't think my current issue is a propagation problem.

I let it create most of the resources including domains yesterday, so only custom domain didn't create due to error.
Today I run terraform apply and it attempts to create just the the custom domain name binding to app service but it still fails the same way asking for verification id.

I have verified the domain config using https://toolbox.googleapps.com/apps/dig to make sure the CNAME record for both domain and awverify prefixed domain and they appear to be correct. I have tested using TXT type of record for the awverify record same results so far with a delay of an hour before retrying creating the custom domain and still getting failure.

I'd like to thank you also for the delay resource example which I had not encountered before but I am sure it will be useful.

@peter-dolkens
Copy link

@rluiten when you ran yesterday, did it create the awverify records?

If you want, you can email me ([email protected]) and I could take a look at your actual records.

Ideally run it once, let it create the DNS records and fail, and I'll take a look tomorrow to confirm that they look right to me.

Additionally, the official documentation is here: https://docs.microsoft.com/en-us/azure/app-service/manage-custom-dns-migrate-domain

@AdamCoulterOz
Copy link
Contributor

AdamCoulterOz commented Aug 5, 2020

Hey all ... its a property already returned by the REST API, the go-sdk is just not exposing it in the props collection (SiteProperties struct).

type SiteProperties struct {
	// CustomDomainVerificationId - READ-ONLY; Custom domain verification id used in the txt record of custom domains to verify them for use on a app service.
	props.CustomDomainVerificationId *string `json:"customDomainVerificationId,omitempty"`
}

Then we add this this line in the resource, as well as the corresponding schema:

d.Set("custom_domain_verification_id", props.CustomDomainVerificationId

https://github.com/terraform-providers/terraform-provider-azurerm/blob/5ad861ffbab3ee91807695723892c2569e4dec23/azurerm/internal/services/web/resource_arm_app_service.go#L599-L608

@AdamCoulterOz
Copy link
Contributor

@AdamCoulterOz
Copy link
Contributor

FYI @jonsamwell - this probably also closes your issue Azure/azure-cli#14142

@tombuildsstuff
Copy link
Contributor

@AdamCoulterOz unfortunately v45.x of the Azure SDK is sufficiently broken (there's 3 separate regressions in it) that we're blocked from upgrading - so whilst a PR would be great I think we're blocked for a little while longer here unfortunately (we're waiting to find out if v46 of the SDK fixes these regressions)

@AdamCoulterOz
Copy link
Contributor

@tombuildsstuff do those regressions affect this resource?

@tombuildsstuff
Copy link
Contributor

@AdamCoulterOz I don't believe so, however the entire provider is blocked from upgrading to SDK v45.x until those regressions are fixed unfortunately

@Badabum
Copy link

Badabum commented Sep 12, 2020

@tombuildsstuff Any progress on this? As far as I know, sdk v46 is already published

@imod
Copy link

imod commented Sep 14, 2020

there is an open PR to update the azure sdk: #8411

@mossywell
Copy link

@peter-dolkens

Our stack looks like this:

[snip]

resource "cloudflare_record" "verify_entry" {
    zone_id                         = var.cloudflare_zone_id
    name                            = "awverify.${var.domain_name}"
    type                            = "TXT"
    value                           = "awverify.${azurerm_app_service.app_service.default_site_hostname}"
}

resource "cloudflare_record" "domain_entry" {
    zone_id                         = var.cloudflare_zone_id
    name                            = var.domain_name_prefix
    type                            = "CNAME"
    proxy                           = true
    value                           = azurerm_app_service.app_service.default_site_hostname
}

FWIW, in practice, all you need is just the one CNAME:
awverify.www --> my-app-service-funky-name.azurewebsites.net
I've done this using Azure DNS and it is almost instant. (That said, I still give it a good 60 seconds and have never had a failure!)
(And if that's what your obfuscated code is already doing - my bad.)

@palmerandy
Copy link

In case it helps someone else, I found that the value Custom Domain Verification ID is shared across an Azure subscription. That is if you have multiple app service plans with different app services, they will all shared the same Custom Domain Verification ID.

This meant that I could use an environment variable, rather than looking it up.

resource "aws_route53_record" "production_asuid" {
  count   = var.custom_domain_verification_id != "" ? 1 : 0
  zone_id = data.aws_route53_zone.domain.zone_id
  name    = "asuid.${var.application_subdomain}.${data.aws_route53_zone.domain.name}"
  type    = "TXT"
  ttl     = "300"
  records = [var.custom_domain_verification_id]
}

resource "azurerm_app_service_custom_hostname_binding" "production" {
  hostname            = "${var.application_subdomain}.${trimsuffix(data.aws_route53_zone.domain.name, ".")}"
  app_service_name    = "service name"
  resource_group_name = "resource group"

  lifecycle {
     ignore_changes = [
       ssl_state,
       thumbprint, 
       virtual_ip, 
       timeouts,
    ] 
  }

  depends_on = [
        aws_route53_record.production_asuid,
        aws_route53_record.production
    ]
}

# sleep to allow the asuid some time to propogate
resource "time_sleep" "route53_custom_domain_verification_id_propagation" {
    depends_on = [ aws_route53_record.production_asuid ]
    create_duration = "30s"
}

resource "null_resource" "next" {
  depends_on = [time_sleep.route53_custom_domain_verification_id_propagation]
}

I know it doesn't help you when creating from scratch, but it might be helpful as a stopgap until it is supported in the provider.

@LoicGombeaud
Copy link
Contributor

Thanks for this @palmerandy ! I feel a lot less guilty passing the verification ID as a variable to terraform, knowing that it's shared across my whole subscription, and not tied to a specific App Service.

The awverify method didn't work for me, and I didn't see anything related in the error messages I got, so Azure might have disabled it by now.

@tombuildsstuff tombuildsstuff added enhancement and removed upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR labels Nov 26, 2020
@ghost
Copy link
Author

ghost commented Nov 27, 2020

This has been released in version 2.38.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.38.0"
}
# ... other configuration ...

@ghost
Copy link
Author

ghost commented Dec 27, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Dec 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet