使用 Terraform 创建 Ansible 清单

Create Ansible inventory using Terraform

我正在尝试使用 Terraform 中的 local_file 函数创建 Ansible 清单文件(我愿意接受以不同方式进行的建议)

模块“vm”配置:

resource "azurerm_linux_virtual_machine" "vm" {
  for_each                        = { for edit in local.vm : edit.name => edit }
  name                            = each.value.name
  resource_group_name             = var.vm_rg
  location                        = var.vm_location
  size                            = each.value.size
  admin_username                  = var.vm_username
  admin_password                  = var.vm_password
  disable_password_authentication = false
  network_interface_ids           = [azurerm_network_interface.edit_seat_nic[each.key].id]
  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

output "vm_ips" {
  value = toset([
    for vm_ips in azurerm_linux_virtual_machine.vm : vm_ips.private_ip_address
  ])
}

当我使用上述配置 运行 terraform 计划时,我得到:

Changes to Outputs:
  + test = [
      + "10.1.0.4",
    ]

现在,在我的主 TF 中,local_file 的配置如下:

resource "local_file" "ansible_inventory" {
  filename = "./ansible_inventory/ansible_inventory.ini"
  content = <<EOF
  [vm]
  ${module.vm.vm_ips}
EOF
}

此returns错误如下:

Error: Invalid template interpolation value
on main.tf line 92, in resource "local_file" "ansible_inventory":
90:   content = <<EOF
91:   [vm]
92:   ${module.vm.vm_ips}
93: EOF
module.vm.vm_ips is set of string with 1 element
Cannot include the given value in a string template: string required.

有什么建议可以将输出中的 IP 列表注入本地文件,同时还能格式化文件中的其余文本吗?

如果您希望从 INI 格式的文件静态获取 Ansible 清单,那么您基本上需要在 Terraform 中呈现模板以生成所需的输出。

module/templates/inventory.tmpl:

[vm]
%{ for ip in ips ~}
${ip}
%{ endfor ~}

@mdaniel 的替代建议:

[vm]
${join("\n", ips)}

module/config.tf:

resource "local_file" "ansible_inventory" {
  content = templatefile("${path.module}/templates/inventory.tmpl",
    { ips = module.vm.vm_ips }
  )

  filename        = "${path.module}/ansible_inventory/ansible_inventory.ini"
  file_permission = "0644"
}

还有一些补充说明:

您可以将输出修改为导出属性对象的整个映射,例如:

output "vms" {
  value = azurerm_linux_virtual_machine.vm
}

然后您可以访问有关要填充到清单中的实例的更多信息。您的 templatefile 参数仍将是模块输出,但模板中的 for 表达式会根据您要添加的内容看起来有很大不同。

您还可以利用 YAML or JSON inventory formats for Ansible static inventory. With those, you can then leverage the yamldecode or jsondecode Terraform 函数使 HCL2 数据结构转换更加容易。在那种情况下,对于更复杂的清单,模板文件会变得更清晰一些。