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

Standard v1 application gateway with DNS A record: The resource record is missing field 'ipv4Address' #4623

Closed
atikhono opened this issue Oct 15, 2019 · 8 comments · Fixed by #5218

Comments

@atikhono
Copy link

atikhono commented Oct 15, 2019

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

Terraform v0.12.8

  • provider.azurerm v1.35.0

Affected Resource(s)

  • azurerm_dns_a_record
  • azurerm_application_gateway

Terraform Configuration Files

resource "azurerm_public_ip" "appgw" {
  name                = "mylb-public-ip"
  location            = "${azurerm_resource_group.main.location}"
  resource_group_name = "${azurerm_resource_group.main.name}"
  allocation_method   = "Dynamic"
}

resource "azurerm_subnet" "appgw" {
  name                  = "mylb-subnet"
  resource_group_name   = "${azurerm_resource_group.main.name}"
  virtual_network_name  = "${azurerm_virtual_network.main.name}"
  address_prefix        = "10.170.18.0/24"
}

resource "azurerm_application_gateway" "appgw" {
  name                = "mylb"
  location            = "${azurerm_resource_group.main.location}"
  resource_group_name = "${azurerm_resource_group.main.name}"

  sku {
    name     = "Standard_Small"
    tier     = "Standard"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "mylb-ip-configuration"
    subnet_id = "${azurerm_subnet.appgw.id}"
  }
  ...
}

resource "azurerm_dns_a_record" "appgw" {
  name                = "mylb"
  zone_name           = "${azurerm_dns_zone.main.name}"
  resource_group_name = "${azurerm_dns_zone.main.resource_group_name}"
  ttl                 = 300
  records             = [
    "${azurerm_public_ip.appgw.ip_address}"
  ]
}

Debug Output

Panic Output

Expected Behavior

Actual Behavior

azurerm_application_gateway.appgw: Creation complete after 20m57s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxx/providers/Microsoft.Network/applicationGateways/mylb]
azurerm_dns_a_record.appgw: Creating...

Error: Error creating/updating DNS A Record "mylb" (Zone "xxxx.xxxx" / Resource Group "xxx"): dns.RecordSetsClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="BadRequest" Message="The resource record is missing field 'ipv4Address'."

  on main.tf line 620, in resource "azurerm_dns_a_record" "appgw":
 620: resource "azurerm_dns_a_record" "appgw" {

DNS A record resource received "" as an application gateway ipv4Address. This must be related to how dynamic IPs are allocated by Azure (only when the assigned resource is "ready"). It looks like Terraform has successfully created application gateway and the execution continued with DNS A record creation, but the dynamic IP was not yet allocated for the gateway. The behaviour is not changed by adding "depends_on: [azure_application_gateway.appgw]" to azurerm_dns_a_record resource (record creation is not run) -- still the same error.

I except the successful creation of application gateway to have the dynamic IP allocated, so that I could have the DNS record created. What am I doing wrong? Not sure this is a bug in provider, could be Azure API as well... What are the proper steps to create a DNS record for a Standard v1 gateway?

Steps to Reproduce

Just create a v1 app gateway with dynamic IP and a DNS A record for that IP.

  1. terraform apply

Important Factoids

References

@kinihun
Copy link

kinihun commented Oct 17, 2019

Dynamic Public IP Addresses aren't allocated until they're attached to a device (e.g. a Virtual Machine/Load Balancer). Instead you can obtain the IP Address once the the Public IP has been assigned via the azurerm_public_ip Data Source.

I'll suggest adding an explicit dependency on the appgw resource on the dns record resource to delay the creation.

@atikhono
Copy link
Author

atikhono commented Oct 18, 2019

I have tried setting a DNS record dependency on app gateway, and that resulted in the same error, just as I stated in the bug description.

I have contacted Azure support on this issue. They offered 2 more alternatives:

  • Use DNS alias. This is not supported in AzureRM provider yet: Azure DNS Alias records #3624.

  • Create an FQDN for the dynamic IP and then CNAME (instead of A record) for that FQDN. This option failed heavily (note that the app gateway name was changed to mylb in the output below; IRL it's long enough and surely unique):

azurerm_application_gateway.appgw: Creation complete after 17m35s [id=/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/applicationGateways/mylb]

Error: Provider produced inconsistent final plan

When expanding the plan for azurerm_dns_cname_record.appgw_ip to include new
values learned so far during apply, provider "azurerm" produced an invalid new
value for .record: was
cty.StringVal("e242d2a5-0487-4f67-a12c-91cc2fbedba7.cloudapp.net"), but now
cty.StringVal("mylb-xxxxxx.westeurope.cloudapp.azure.com").

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

Consecutive terraform apply:

  # azurerm_dns_cname_record.appgw_ip will be created
  + resource "azurerm_dns_cname_record" "appgw_ip" {
      + id                  = (known after apply)
      + name                = "mylb"
      + record              = "mylb-xxxxx.westeurope.cloudapp.azure.com"
      + resource_group_name = "xxxxx"
      + tags                = (known after apply)
      + ttl                 = 300
      + zone_name           = "xxxxx"
    }

Plan: 6 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_dns_cname_record.appgw_ip: Creating...

Error: Error creating/updating DNS CNAME Record "mylb" (Zone "xxxxx" / Resource Group "connect-dns"): dns.RecordSetsClient#CreateOrUpdate: Failure sending request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status=<nil> <nil>

  on main.tf line 621, in resource "azurerm_dns_cname_record" "appgw_ip":
 621: resource "azurerm_dns_cname_record" "appgw_ip" {

@kinihun
Copy link

kinihun commented Oct 18, 2019 via email

@atikhono
Copy link
Author

@kinihun static IPs are not supported with v1 application gateways. v2 is 10 times more expensive, and we don't need its features.

@tapanhalani
Copy link

@atikhono I am facing exactly the same issue with my azure v1 application gateway and dns records creation. Did you manage to find a solution for this?

@atikhono
Copy link
Author

@tapanhalani Not yet. I'm working with Azure support to resolve this. I will put a workaround there when/if there is some.

@atikhono
Copy link
Author

atikhono commented Nov 11, 2019

@tapanhalani A workaround is to re-read IP address once application gateway has been created:

data "azurerm_public_ip" "appgw" {
  name                = "${azurerm_public_ip.appgw.name}"
  resource_group_name = "${azurerm_resource_group.main.name}"
  depends_on = [
    azurerm_application_gateway.appgw
  ]
}

resource "azurerm_dns_a_record" "appgw" {
  name                = "mylb"
  zone_name           = "${azurerm_dns_zone.main.name}"
  resource_group_name = "${azurerm_dns_zone.main.resource_group_name}"
  ttl                 = 300
  records             = [
    "${data.azurerm_public_ip.appgw.ip_address}"
  ]
}

This is actually somehow referenced in the data source documentation: https://www.terraform.io/docs/providers/azurerm/d/public_ip.html.

There's a drawback to using this workaround:

However, due to the data resource behavior of deferring the read until the apply phase when depending on values that are not yet known, using depends_on with data resources will force the read to always be deferred to the apply phase, and therefore a configuration that uses depends_on with a data resource can never converge.

@ghost
Copy link

ghost commented Mar 29, 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 and limited conversation to collaborators Mar 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
4 participants