Terraform EC2 NIC private_ips 来自自定义模块输出的构建列表

Posted

技术标签:

【中文标题】Terraform EC2 NIC private_ips 来自自定义模块输出的构建列表【英文标题】:Terraform EC2 NIC private_ips build list from custom module outputs 【发布时间】:2021-11-11 17:40:11 【问题描述】:

我有一个自定义子模块,它正在为从 JSON 定义文件加载的唯一 EC2 实例构建各种 AWS 资源。在根模块中,我需要连接每个子模块的输出属性,以将辅助私有 IPv4 地址应用于网络接口资源。网络接口将有 2 个静态 IPv4 地址,外加一个来自 EACH 所构建子模块的 IPv4 地址。

这是我的文件夹结构:

root/
|_
  main.tf
  instances/
  |_
    instance1.json
    instance2.json
    ...
  modules/instance/
  |_
    main.tf
    outputs.tf

root main.tf 文件将使用 for_each 参数将所有 JSON 文件加载到自定义子模块中,如下所示:

locals 
  json_files = fileset("./instances/", "*.json")
  json_data = [for f in local.json_files: jsondecode(file("./instances/$f"))]

module "instance" 
  for_each =  for k,v in local.json_data: k => v 
  source = "../modules/instance"
  server_name = each.value.server_name
  firewall_vip = each.value.firewall_vip
  ...

我试图从子模块中获取一个字符串输出属性,然后将其作为列表应用于aws_network_interface 资源private_ips 属性。

字符串输出属性是一个虚拟 IP,用于通过防火墙到后端实例的特殊路由。 子模块 outputs.tf 文件中的输出属性示例:

output "firewall_vip" 
  description = "The virtual IP to pass through firewall"
  value = "10.0.0.10"

旁注:“firewall_vip”输出属性也在 JSON 文件中为子模块的输入变量定义...所以有没有更简单的方法可以直接从JSON 文件而不是依赖子模块输出?

root 模块 main.tf 文件中,我试图将所有辅助 IP 的列表与Splat expression 连接起来以应用于 NIC(不确定如果这是正确的方法):

resource "aws_network_interface" "firewall" 
  subnet_id = <subnet ID>
  private_ips = concat(["10.0.0.4","10.0.0.5"], module.instance[*].firewall_vip)

我收到一条错误消息:

Error: Incorrect attribute value type
  module.instance is a map of object, known only after apply
Inappropriate value for attribute "private_ips": element 2: string required.

我也尝试过使用For expression 来实现这一点:

resource "aws_network_interface" "firewall" 
  private_ips = concat(["10.0.0.4", "10.0.0.5"], [for k,v in module.instance[*]: v if k == "firewall_vip"])
  ...

我没有收到任何错误,但它也无法识别来自子模块的任何“firewall_vip”输出以附加到列表中。

我是不是走错了路?任何建议都会非常有帮助,因为我仍然是 Terraform 新手。

【问题讨论】:

【参考方案1】:

我意识到我过于复杂了,我可以使用 locals 块来提取 JSON 属性,而不必依赖子模块输出...

root main.tf 文件中:

locals 
  json_data = [for f in fileset("./instances/", "*.json"): jsondecode(file("./instances/$f"))]
  server_vips = local.json_data[*].server_vip


resource "aws_network_inteface" "firewall" 
  private_ips = concat(["10.0.0.4", "10.0.0.5"], local.server_vips)
  ...

【讨论】:

以上是关于Terraform EC2 NIC private_ips 来自自定义模块输出的构建列表的主要内容,如果未能解决你的问题,请参考以下文章

使用 terraform 删除特定资源,即 vm、nic、nsg

使用 Terraform 将自定义 DNS 服务器 IP 添加到 Azure VM NIC

如何通过 Terraform 部署 Open*** EC2 实例? [关闭]

Terraform 重新部署 EC2 实例

使用 terraform 启动 EC2 实例时出错

新AMI发布时,Terraform重新创建EC2实例