Reputation: 1233
In my main terraform file I have:
resource "azurerm_resource_group" "rg" {
name = var.rg_name
location = var.location
}
resource "azurerm_public_ip" "public_ip" {
name = "PublicIP"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
domain_name_label = var.domain_name_label
allocation_method = "Dynamic"
}
And in my outputs file I have:
data "azurerm_public_ip" "public_ip" {
name = "PublicIP"
resource_group_name = azurerm_resource_group.rg.name
depends_on = [azurerm_resource_group.rg, azurerm_public_ip.public_ip]
}
output "public_ip" {
value = data.azurerm_public_ip.public_ip.ip_address
}
All the resources including IP get created, however the output is blank. How can I fix this?
Upvotes: 1
Views: 1851
Reputation: 70466
Terraform seems to have updated it's documentation on that matter. I could make it work with the idea described in: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/public_ip.html
The dynamic pip will be empty until assigned to a nic. The trick here is to define data that depends on the pip and virtual machine at the same time. Then you can pipe that into an output and use it anywhere else.
#...
resource "azurerm_public_ip" "example" {
name = "test-pip"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Dynamic"
idle_timeout_in_minutes = 30
}
resource "azurerm_network_interface" "example" {
name = "test-nic"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "testconfiguration1"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Static"
private_ip_address = "10.0.2.5"
public_ip_address_id = azurerm_public_ip.example.id
}
}
resource "azurerm_virtual_machine" "example" {
name = "test-vm"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
network_interface_ids = [azurerm_network_interface.example.id]
# ...
}
# Solution starts here
data "azurerm_public_ip" "example" {
name = azurerm_public_ip.example.name
resource_group_name = azurerm_virtual_machine.example.resource_group_name
}
output "public_ip_address" {
value = data.azurerm_public_ip.example.ip_address
}
Upvotes: 0
Reputation: 11
I had the same issue. The actual problem seems to be the dynamic allocation. The IP address is not known until it is actually used by a VM.
In my case, I could solve the issue by adding the VM (azurerm_linux_virtual_machine.testvm
) to the depends_on list in the data source:
data "azurerm_public_ip" "public_ip" {
name = "PublicIP"
resource_group_name = azurerm_resource_group.rg.name
depends_on = [ azurerm_public_ip.public_ip, azurerm_linux_virtual_machine.testvm ]
}
Unfortunately, this seems not to be documented in https://www.terraform.io/docs/providers/azurerm/d/public_ip.html
Upvotes: 1
Reputation: 8152
Make sure output.tf
contains only output tags
and main.tf
contains resources tags
The following works just fine for me:
Main.tf
resource "azurerm_resource_group" "example" {
name = "resourceGroup1"
location = "West US"
}
resource "azurerm_public_ip" "example" {
name = "acceptanceTestPublicIp1"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
allocation_method = "Static"
tags = {
environment = "Production"
}
}
Output.tf
output "azurerm_public_ip" {
value = azurerm_public_ip.example.ip_address
}
In case you want to have a dependency between resources, use depends_on
inside the resource
tag.
For example:
depends_on = [azurerm_resource_group.example]
Steps to reproduce:
Update-
The reason you get blank public IP is since declaring allocation_method = "Dynamic"
From the docs:
Note
Dynamic
- Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure.
Full working example with dynamic allocation.
Upvotes: 1