有什么方法可以在容器定义 JSON 文档中包含 terraform-aws-provider-resource 吗?

is there any way to include terraform-aws-provider-resource in container definition JSON Document?

概览

我正在使用 Terraform 构建 AWS-ECS-Service-container。 地形 aws_ecs_task_definition

example task_definition_kafka.tf

resource "aws_ecs_task_definition" "task_definition_kafka" {
  container_definitions    = file("./task_definition_kafka.json")
}

example task_definition_kafka.json

[
  {    

    "cpu": 256,
    "memory": 768,
    "portMappings": [
      { 
        "hostPort": 7002,
        "containerPort": 7002,
        "protocol": "tcp"
      }
    ],
    "essential": true,
    "environment" : [   
      { "name" : "SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL", "value" : "${aws_ecs_task_definition.aws_ecs_task_definition_kafka.private_ip}:2181" },
    ]
  }
]

主要问题

在上面的 json 文件中,我想使用 ${aws_ecs_task_definition.aws_ecs_task_definiton_kafka.private_ip} 语法从 terraform-aws-provider-resource[=26= 获取 private_ip ]

可能吗?

您可以使用 templatefile 让 Terraform 读取文件 并且 将其解释为 Terraform 模板:

resource "aws_ecs_task_definition" "task_definition_kafka" {
  container_definitions = templatefile("${path.module}/task_definition_kafka.json", {
    kafka_private_ip = aws_ecs_task_definition.aws_ecs_task_definition_kafka.private_ip
  })
}

虽然外部文件被解释为正常 Terraform string template, it looks like your goal is to produce a JSON string in this case, so it's better to use the jsonencode function 而不是使用多个模板指令零碎地构建 JSON 数据。以下是如何按照该建议编写 task_definition_kafka.json

${jsonencode([
  {
    cpu: 256,
    memory: 768,
    portMappings: [
      {
        hostPort: 7002,
        containerPort: 7002,
        protocol: "tcp",
      },
    ],
    essential: true,
    environment: [
      {
        name: "SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL",
        value: kafka_private_ip,
      },
    ],
  },
])}

使用单个 jsonencode 调用一次生成整个 JSON 字符串的主要优点是结果保证是有效的 JSON 语法,而无需采取特殊的努力分别对每个部分进行编码。 jsonencode 可以接受来自 Terraform 语言的任何类型的值并将其转换为等效的 JSON,因此您可以使用 Terraform expressions 使用传递给的模板变量动态生成部分数据结构templatefile 的第二个参数,如上例中的 kafka_private_ip

或者,您可以创建模板数据文件并传递要在 vars 中使用的变量。

例如,

data "template_file" "task-definition-kafka" {
  template = "${file("./task_definition_kafka.json")}"
  vars = {
    kafka_private_ip = "${aws_instance.kafka.private_ip}"
  }
}

resource "aws_ecs_task_definition" "kafka" {
  container_definitions = "${data.template_file.task-definition-kafka.rendered}"
}

因此您的 task_definition_kafka.json 文件将是:

[
  {    

    "cpu": 256,
    "memory": 768,
    "portMappings": [
      { 
        "hostPort": 7002,
        "containerPort": 7002,
        "protocol": "tcp"
      }
    ],
    "essential": true,
    "environment" : [   
      { "name" : "SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL", "value" : "${kafka_private_ip}:2181" },
    ]
  }
]

有关更多信息,您可以查看模板提供商,https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file