1
votes

I am following the example [1] to output the public IP of a new VM created on Azure with Terraform. It works fine when creating only 1 VM, but when I add a counter (default 2), it doesn't output anything.

This is how I am modifying the .tf file:

variable "count" {
    default = "2"
}
...

resource "azurerm_public_ip" "test" {
  name                         = "test-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"
  }
}
...

data "azurerm_public_ip" "test" {
  count               = "${var.count}"
  name                = "${element(azurerm_public_ip.test.*.name, count.index)}"
  resource_group_name = "${azurerm_virtual_machine.test.resource_group_name}"
}

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

After terraform apply:

Outputs:

public_ip_address = [
    ,

]

[1] https://www.terraform.io/docs/providers/azurerm/d/public_ip.html

2

2 Answers

3
votes

The reason that you cannot output the multi public IPs is that you do not create multi public IPs. So when you use ${data.azurerm_public_ip.test.*.ip_address} to output them, there no these resources for you.

For the terraform, you could add the count in the resource azurerm_public_ip to create multi public IPs and output them with azurerm_public_ip.test.*.ip_address like this:

variable "count" {
    default = "2"
}
...

resource "azurerm_public_ip" "test" {
  count                        = "${var.count}"
  name                         = "test-${count.index}-pip"
  location                     = "${azurerm_resource_group.test.location}"
  resource_group_name          = "${azurerm_resource_group.test.name}"
  public_ip_address_allocation = "Static"
  idle_timeout_in_minutes      = 30

  tags {
    environment = "test-${count.index}"
  }
}
...

output "public_ip_address" {
  value = "${azurerm_public_ip.test.*.ip_address}"
}

The screenshot of the result like this:

enter image description here

I did the test just create the public. So I change the allocation method into Static and output it with the resource.

If you want to use the data to reference the public IPs. The code would like this:

data "azurerm_public_ip" "test" {
  count               = "${var.count}"
  name                = "${element(azurerm_public_ip.test.*.name, count.index)}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}

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

Hope this will help you. If you need more help please let me know.

0
votes

So I just ran into the exact same problem with my deployment into Azure. The above solutions worked( Charles Xu's solution), with one caveat... I had to: hard-code the name of the resource group, as well as add a depends on clause to the output block.

I am sure that the above answers are the correct way to go about it however the value of the resource group key in the data object "azurerm_public_ip" needed to be hardcoded...

enter image description here

enter image description here

enter image description here