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

Bug azurerm_public_ip for ip_address doesn't return on first attempt #310

Closed
bernadinm opened this Issue Sep 6, 2017 · 9 comments

Comments

Projects
None yet
6 participants
@bernadinm
Copy link

bernadinm commented Sep 6, 2017

Terraform Version

Terraform v0.10.4

Issue

Unfortunately the azurerm_public_ip resource doesn't provide the IP address immediately. The only resource available is the fqdn. This is only good if this assumes that the workstation that terraform is running on has access to a DNS server. The issue here is that the operator cannot use the ip_address of the azurerm_public_ip resource in the same terraform apply command. It is only until the user performs a terraform refresh then a terraform apply will it work.

$ terraform state show  azurerm_public_ip.master_public_ip[0]
id                           = /subscriptions/<sub_id>/resourceGroups/deleteme-test/providers/Microsoft.Network/publicIPAddresses/pub-ip-1
domain_name_label            = noder-1
fqdn                         = node-1-1231414124.westus.cloudapp.azure.com
location                     = westus
name                         = pub-ip-1
public_ip_address_allocation = dynamic
resource_group_name          = deleteme-test
$ terraform refresh 
$ terraform state show  azurerm_public_ip.master_public_ip[0]
id                           = /subscriptions/<sub_id>/resourceGroups/deleteme-test/providers/Microsoft.Network/publicIPAddresses/pub-ip-1
domain_name_label            = noder-1
fqdn                         = node-1-1231414124.westus.cloudapp.azure.com
ip_address                   = 40.112.143.145
location                     = westus
name                         = pub-ip-1
public_ip_address_allocation = dynamic
resource_group_name          = deleteme-test

@bernadinm bernadinm changed the title Bug azurerm_public_ip for ip_address Bug azurerm_public_ip for ip_address doesn't return on first attempt Sep 6, 2017

@tombuildsstuff

This comment has been minimized.

Copy link
Contributor

tombuildsstuff commented Sep 6, 2017

Hey @bernadinm

Thanks for opening this issue :)

Unfortunately the underlying Azure infrastructure won't allocate an IP Address to a Dynamic Public IP until it's assigned to a resource in that's running (such as a VM / LB etc) - whereas Static Public IP's will be returned a value even prior to being assigned to something.

That said, you should be able to work around this by using the azurerm_public_ip data source to obtain this value once the required resource has completed provisioning/booted, via:

resource "azurerm_public_ip" "test" {
  # ...
}

resource "azurerm_network_interface" "test" {
  # ...
  ip_configuration {
    public_ip_address_id = "${azurerm_public_ip.test.id}"
  }
}

resource "azurerm_virtual_machine" "test" {
  # ...
  network_interface_ids = ["${azurerm_network_interface.test.id}"]
}

data "azurerm_public_ip" "datasourceip" {
  name = "${azurerm_public_ip.test.name}"
  resource_group_name = "${azurerm_virtual_machine.test.resource_group_name}"
}

output "ip_address" {
  value = "${data.azurerm_public_ip.test.ip_address}"
}

Would it be possible for you to take a look and let me know if that solves your issue?

Thanks!

@bernadinm

This comment has been minimized.

Copy link
Author

bernadinm commented Sep 8, 2017

Thanks for your suggestion. I just tried it on my end and it has the same result as before. It only provides the IP address after a terraform refresh

Results

$ terraform apply
$ terraform console
> data.azurerm_public_ip.master_public_ip.*.ip_address
Resource 'data.azurerm_public_ip.master_public_ip' does not have attribute 'ip_address' for variable 'data.azurerm_public_ip.master_public_ip.*.ip_address'
>
$ terraform refresh
$ terraform console
> data.azurerm_public_ip.master_public_ip.*.ip_address
[
  40.83.217.70,
  13.64.243.177,
  104.40.62.62
]
@tombuildsstuff

This comment has been minimized.

Copy link
Contributor

tombuildsstuff commented Oct 10, 2017

Hi @bernadinm

Apologies for the delay in responding to this issue.

Taking a look at the previous configuration I posted - I noticed I missed out the depends_upon attribute - as such this should suffice:

resource "azurerm_resource_group" "test" {
  name     = "tharvey-devrg3"
  location = "West US 2"
}

resource "azurerm_virtual_network" "test" {
  name                = "acctvn"
  address_space       = ["10.0.0.0/16"]
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_subnet" "test" {
  name                 = "acctsub"
  resource_group_name  = "${azurerm_resource_group.test.name}"
  virtual_network_name = "${azurerm_virtual_network.test.name}"
  address_prefix       = "10.0.2.0/24"
}

resource "azurerm_public_ip" "test" {
  name                         = "tom-pip"
  location                     = "${azurerm_resource_group.test.location}"
  resource_group_name          = "${azurerm_resource_group.test.name}"
  public_ip_address_allocation = "Dynamic"
  idle_timeout_in_minutes      = 30

  tags {
    environment = "test"
  }
}

resource "azurerm_network_interface" "test" {
  name                = "tfni"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"

  ip_configuration {
    name                          = "testconfiguration1"
    subnet_id                     = "${azurerm_subnet.test.id}"
    private_ip_address_allocation = "static"
    private_ip_address            = "10.0.2.5"
    public_ip_address_id          = "${azurerm_public_ip.test.id}"
  }
}

resource "azurerm_virtual_machine" "test" {
  name                  = "acctvm"
  location              = "${azurerm_resource_group.test.location}"
  resource_group_name   = "${azurerm_resource_group.test.name}"
  network_interface_ids = ["${azurerm_network_interface.test.id}"]
  vm_size               = "Standard_F1"

  # Uncomment this line to delete the OS disk automatically when deleting the VM
  # delete_os_disk_on_termination = true


  # Uncomment this line to delete the data disks automatically when deleting the VM
  # delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }
  storage_os_disk {
    name              = "myosdisk1"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }
  os_profile {
    computer_name  = "hostname"
    admin_username = "testadmin"
    admin_password = "Password1234!"
  }
  os_profile_linux_config {
    disable_password_authentication = false
  }
  tags {
    environment = "staging"
  }
}

data "azurerm_public_ip" "test" {
  name                = "${azurerm_public_ip.test.name}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  depends_on          = ["azurerm_virtual_machine.test"]
}

output "ip_address" {
  value = "${data.azurerm_public_ip.test.ip_address}"
}

which outputs the value:

# ...
data.azurerm_public_ip.test: Refreshing state...

Apply complete! Resources: 6 added, 0 changed, 0 destroyed.

Outputs:

ip_address = 52.175.203.134

As the Public IP address isn't available until the VM starts the depends_on will wait for the VM to be fully provisioned before retrieving the state of the Public IP (and retrieving it's IP Address). Would you be able to take another look and see if this solves your issue?

That said - given this functionality is working as designed by Azure (and documented to say as such in the Terraform documentation) - I'm going to close this issue for the moment.

Thanks!

@genevieve

This comment has been minimized.

Copy link
Contributor

genevieve commented Jan 29, 2018

Hey @tombuildsstuff. Is this behavior also expected for statically allocated public IPs?

We are seeing a similar issue on the outputs for an azurerm_public_ip with public_ip_address_alocation = "static".

@nik-shornikov

This comment has been minimized.

Copy link

nik-shornikov commented Jan 29, 2018

getting this with static allocation too.. which used to work until recently. the az cli shows the allocated address

@genevieve

This comment has been minimized.

Copy link
Contributor

genevieve commented Jan 29, 2018

@nik-shornikov This is the open/latest issue on this: #771

@nik-shornikov

This comment has been minimized.

Copy link

nik-shornikov commented Jan 29, 2018

@genevievelesperance theres gotta be some wonky lack of parity in their implementation, because getting the ip via the data workaround worked for me. exactly as above:

resource "azurerm_public_ip" "default" {
  name                         = "dotnetdev-${terraform.workspace}-kube-pip"
  location                     = "${azurerm_resource_group.default.location}"
  resource_group_name          = "${azurerm_resource_group.default.name}"
  public_ip_address_allocation = "static"
}

data "azurerm_public_ip" "default" {
  name                = "dotnetdev-${terraform.workspace}-kube-pip"
  resource_group_name = "${azurerm_resource_group.default.name}"
  depends_on          = ["azurerm_public_ip.default"]
}
@iondulgheru

This comment has been minimized.

Copy link

iondulgheru commented Feb 2, 2018

Upgrading from 1.0.1 to 1.1 caused also for me this issue on the outputs for an azurerm_public_ip with public_ip_address_alocation = "static"

@gregnrobinson

This comment has been minimized.

Copy link

gregnrobinson commented Feb 8, 2018

I am also experiencing the issue even with static IP allocation set. data source with the .ip_address attribute does work though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment