Terraform v0.10.4
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
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!
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
$ 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
]
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!
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".
getting this with static allocation too.. which used to work until recently. the az cli shows the allocated address
@nik-shornikov This is the open/latest issue on this: https://github.com/terraform-providers/terraform-provider-azurerm/issues/771
@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"]
}
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"
I am also experiencing the issue even with static IP allocation set. data source with the .ip_address attribute does work though.
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!
Most helpful comment
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_uponattribute - as such this should suffice:which outputs the value:
As the Public IP address isn't available until the VM starts the
depends_onwill 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!