Terraform:如何将值传递给本地执行中的环境变量?

问题描述 投票:0回答:2

我正在尝试通过使用 locals 和 local-exec 将虚拟机的公共 IP 地址写入文本文件,请参阅下面的代码。

问题是 locals 变量似乎不起作用:

 my_ip=data.azurerm_public_ip.vm-publicip.ip_address

我也尝试在环境中的 local-exec 中传递“data.azurerm_public_ip.vm-publicip.ip_address”,但这也不起作用。

完整代码:

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"
  }
}

当我尝试运行它时,%VM% 工作正常,但 %IP% 无法正常工作。

azure terraform
2个回答
1
投票

使用 terraform 将值传递给 local-exec 中的环境变量

您似乎正在尝试使用

local-exec
配置程序将虚拟机的公共 IP 地址写入文本文件。但是,您的代码中有几个问题需要解决。

首先,在您的

locals
块中,您直接分配值,而不使用
local-exec
配置器。
local-exec
用于在运行 Terraform 的计算机上本地执行命令,而不是在 Terraform 配置本身内执行命令。

其次,正如 Rui Jarimba 在您的

terraform_data
资源中建议的那样,您尝试直接引用
data.azurerm_public_ip.vm-publicip.ip_address
,但您应该通过您定义的
local
变量来引用它。

我根据要求对代码进行了必要的更改

我的演示配置:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "main" {
  name     = "testrg-vk"
  location = "East US2"
}

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 "null_resource" "ansible_inventory" {
  provisioner "local-exec" {
    interpreter = ["pwsh", "-Command"]
    command     = "echo '${local.my_vm} ${local.my_ip}' > ansible_inventory"
  }
}

部署成功:

enter image description here

现在运行命令

type ansible_inventory

enter image description here


0
投票

Terraform 文档指出,provisioner 是最后的手段,您应该在使用它们之前寻求其他替代方案。因此,此评论是关于解决此问题的不同方法根本不使用

local-exec
,因为没有必要使用用另一种语言编写的外部程序来创建包含 Terraform 生成的一些数据的文件。

Terraform 提供程序

hashicorp/local

 包含资源类型 local_file
,它以与 
azurerm_public_ip
 在 Azure API 中管理远程对象类似的方式管理本地磁盘上的文件。您可以使用该资源类型指示 Terraform 根据 Terraform 配置中可用的其他数据创建或更新文件。

例如:

terraform { required_providers { azurerm = { source = "hashicorp/azurerm" } local = { source = "hashicorp/local" } } } 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 "local_file" "ansible_inventory" { file = "${path.module}/ansible_inventory" content = "${local.my_vm} ${data.azurerm_public_ip.vm-publicip.ip_address}" }
当创建

local_file.ansible_inventory

资源时,它将创建
ansible_inventory
文件并将
content
值写入其中。如果您随后更改 
local.my_vm
data.azurerm_public_ip.vm-publicip.ip_address
 的值,提供商将建议使用新信息重写文件。


local_file

文档有以下警告,但类似的情况也适用于
local-exec
方法,所以我认为这与您的情况无关:

使用本地文件时,每次在不存在该文件的新计算机上应用配置时,Terraform 都会检测到该资源已被删除,并将生成一个差异以重新创建该文件。在许多不同用户经常应用配置的环境中或在自动化系统中,这可能会导致差异中的“噪音”。

© www.soinside.com 2019 - 2024. All rights reserved.