I am trying to pass write the public IP address of a VM out to a text file via using locals and local-exec, see below code.
The issue is that the locals variable does not seem to work:
my_ip=data.azurerm_public_ip.vm-publicip.ip_address
I tried passing the "data.azurerm_public_ip.vm-publicip.ip_address" inside local-exec at the environments too, but that also does not work.
Full code:
resource "azurerm_public_ip" "public"{
name = "vm_public_ip"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
allocation_method = "Dynamic"
}
data "azurerm_public_ip" "vm-publicip"{
name = azurerm_public_ip.public.name
resource_group_name = azurerm_resource_group.main.name
}
locals {
my_ip=data.azurerm_public_ip.vm-publicip.ip_address
my_vm="[azure_vm]"
}
resource "terraform_data" "ansible" {
provisioner "local-exec" {
environment = {
VM=local.my_vm
IP=data.azurerm_public_ip.vm-publicip.ip_address
}
command = "echo %VM% %IP% > ansible_inventory"
}
}
When I tried to run it, %VM% worked correctly, but the %IP% not.
2
Answers
It seems like you’re trying to use the
local-exec
provisioner to write the public IP address of a VM to a text file. However, there are a couple of issues in your code that need to be addressed.Firstly, in your
locals
block, you’re assigning values directly without using thelocal-exec
provisioner.local-exec
is used to execute commands locally on the machine running Terraform, not within the Terraform configuration itself.Secondly, As Rui Jarimba suggested in your
terraform_data
resource, you’re trying to referencedata.azurerm_public_ip.vm-publicip.ip_address
directly, but you should be referring to it via thelocal
variable you defined.I made necessary changes in the code as per the requirement
My demo configuration:
Deployment successfully:
now run the command
type ansible_inventory
The Terraform documentation notes that provisioners are a last resort and that you should seek other alternatives before using them. This comment is therefore about a different way to solve this problem not using
local-exec
at all, because it isn’t necessary to use an external program written in another language just to create a file containing some data produced by Terraform.The Terraform provider
hashicorp/local
includes the resource typelocal_file
which manages a file on local disk in a similar way to howazurerm_public_ip
manages a remote object in the Azure API. You can use that resource type to instruct Terraform to create or update a file based on other data available in the Terraform configuration.For example:
When the
local_file.ansible_inventory
resource is created, it will create theansible_inventory
file and write thecontent
value into it. If you subsequently change the value oflocal.my_vm
ordata.azurerm_public_ip.vm-publicip.ip_address
, the provider will propose to rewrite the file with the new information.The
local_file
documentation has the following warning, but a similar situation would’ve been true for thelocal-exec
approach too, so I assume it’s not a concern for your situation: