AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 76970245
Accepted
Rostyslav Malenko
Rostyslav Malenko
Asked: 2023-08-24 22:18:44 +0800 CST2023-08-24 22:18:44 +0800 CST 2023-08-24 22:18:44 +0800 CST

Terraform 模板不会按值替换变量

  • 772

我想按值填充模板,但我的内容与模板相同。

文件中的结果应该是这样的hosts.yaml。模板尚未完成,将进行编辑。

rnd_hetzner:
  hosts:
    rnd.test:
      ansible_port: 22
      ansible_host: 1.1.2.3

模板:

# Ansible Inventory
---

all:
  hosts:
{% for instance, details := instances_ips.value %}
    {{ instance }}:
      ansible_host: {{ details.external_ip }}
{% endfor %}

  children:
    all_servers:
      hosts:
{% for instance, _ := instances_ips.value %}
        {{ instance }}
{% endfor %}

地形

locals {
  instances_ips = {
    "value" : {
      "app-server" : {
        "external_ip" : "1.27.1.1"
      },
      "db-server" : {
        "external_ip" : "1.24.9.1"
      }
    }
  }
}

resource "local_file" "ansible_inventory" {
  content = templatefile("${path.module}/templates/ansible_inventory.tpl",
    {
      instances_ips = jsonencode(local.instances_ips)
    }
  )
  filename = "${path.module}/templates/hosts.yaml"
}
terraform
  • 2 2 个回答
  • 18 Views

2 个回答

  • Voted
  1. Best Answer
    Martin Atkins
    2023-08-25T02:27:55+08:002023-08-25T02:27:55+08:00

    遵循文档中有关如何生成有效 JSON 或 YAML 的建议templatefile,这是一种惯用的方法。

    该模板包含对yamlencode使用 Terraform 自己的表达式语言描述的数据结构的单个调用。这确保结果始终是有效的 YAML,无需特殊转义:

    # Ansible Inventory
    ---
    ${yamlencode({
      hosting = {
        hosts = {
          for inst in instancesips : inst.hostname => {
            ansible_port = 222
            ansible_host = inst.external_ip
          }
        }
      }
    })}
    

    Terraform 配置类似于以下内容:

    data "vultr_instance" "instance_ip" {
      for_each = var.instance
      filter {
        name   = "label"
        values = ["${each.key}.${var.domain}"]
      }
    }
    
    locals {
      ips = {
        for k, v in data.vultr_instance.instance_ip : k =>
        {
          hostname    = v.hostname
          external_ip = v.main_ip
        }
      }
    }
    
    resource "local_file" "ansible_inventory" {
      content = templatefile("${path.module}/templates/ansible_inventory.tpl",
        {
          instancesips = local.ips
        }
      )
      filename = "${path.module}/templates/hosts.yaml"
    }
    

    还值得考虑提供者文档中的警告注释hashicorp/local,它提供了local_file上面使用的资源类型:

    Terraform 主要处理远程资源,这些资源的寿命比单次 Terraform 运行的寿命长,因此本地资源有时可能会违反其假设。这里的资源最好谨慎使用,因为根据本地状态可能会很难在许多不同的本地系统上应用相同的 Terraform 配置,而本地资源可能不普遍可用。有关详细信息,请参阅每个资源中的具体注释。

    具体来说local_file:

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

    在适当的时候忽略这些警告是可以的,但这确实意味着这种 Terraform 配置的行为与 Terraform 用户对其他提供者的期望不匹配:成功运行后期望状态和实际状态应该收敛,因此未来的计划terraform apply将除非所需的状态发生变化,否则为空。local_file.ansible_inventory使用此配置的任何人都需要接受培训,以期望看到 Terraform 建议在新工作目录中的每次运行中创建,即使所需的状态没有以其他方式更改。

    • 1
  2. Rostyslav Malenko
    2023-08-24T23:40:03+08:002023-08-24T23:40:03+08:00

    感谢大家。我找到了解决办法。

    我得到这个 JSON

    instances_ips = {
      "app-server" = {
        "external_ip" = "1.2.3.4"
        "hostname" = "app-server.ja.link"
        "internal_ip" = "10.0.0.4"
      }
      "db-server" = {
        "external_ip" = "4.5.6.7"
        "hostname" = "db-server.ja.link"
        "internal_ip" = "10.0.0.3"
      }
    }
    

    在本地.ips中

    data "vultr_instance" "instance_ip" {
      for_each = var.instance
      filter {
        name   = "label"
        values = ["${each.key}.${var.domain}"]
      }
    }
    
    locals {
      ips = {
        for k, v in data.vultr_instance.instance_ip : k =>
        {
          hostname    = v.hostname
          external_ip = v.main_ip
        }
      }
    }
    
    resource "local_file" "ansible_inventory" {
      content = templatefile("${path.module}/templates/ansible_inventory.tpl",
        {
          instancesips = local.ips
        }
      )
      filename = "${path.module}/templates/hosts.yaml"
    }
    

    我现在的模板是:

    # Ansible Inventory
    ---
    hosting:
      hosts:
      %{~ for inst in instancesips  ~}
        ${inst.hostname}:
          ansible_port: 22
          ansible_host: ${inst.external_ip}
      %{~ endfor ~}
    
    • 0

相关问题

  • 无法从 ALB 模块的多个 ID 中检索单个 EC2 实例 ID

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve