【问题标题】:Terraform rejecting JSON template_fileTerraform 拒绝 JSON 模板文件
【发布时间】:2019-09-26 13:54:52
【问题描述】:

Terraform 在计划期间拒绝了以下 ECS 任务定义。 JSON 验证并使用内联 container_definitions 工作正常。

我在 Google 上搜索并阅读了一些评论,指出 TF 在 JSON 对象方面存在问题,主要与嵌套有关。我可以通过将 JSON 直接放入任务定义的资源块中的 container_definition 来解决此问题,但我更愿意将其粘贴在模板文件中。

Error: Error running plan: 1 error(s) occurred:

* module.sonarqube.aws_ecs_task_definition.task: ECS Task Definition container_definitions is invalid: Error decoding JSON: json: cannot unmarshal string into Go struct field ContainerDefinition.Memory of type int64

template_file 中引用的 JSON 文档:

   {
        "name": "sonarqube",
        "image": "sonarqube:7.5-community",
        "memory": "2048",
        "logConfiguration": {
            "logDriver": "awslogs",
            "options": {
                "awslogs-group": "${log-group}",
                "awslogs-region": "${region}",
                "awslogs-stream-prefix": "ecs"
            }
        },
        "portMappings": {
            "hostPort": "9000",
            "protocol": "tcp",
            "containerPort": "9000"
        },
        "environment": [
            {
                "name": "sonar.jdbc.password",
                "value": "${password}"
            },
            {
                "name": "sonar.jdbc.url",
                "value": "${url}/${extra_url}"
            },
            {
                "name": "sonar.jdbc.username",
                "value": "${username}"
            }
        ]
    }

相关的 TF 块:

data "template_file" "task-def" {
  template = "${file("${path.module}/task-def.json")}"

  vars = {
    log-group = "/ecs/${var.cluster_name}-${var.name}"
    region    = "${var.region}"
    url       = "jdbc:postgresql://${var.rds_url}${var.extra_url}"
    username  = "${var.username}"
    password  = "${var.password}"
  }
}
resource "aws_ecs_task_definition" "task" {
  family       = "${var.name}"
  network_mode = "bridge"
  cpu          = "1024"
  memory       = "2048"

  execution_role_arn = "${var.ecs-exec-role}"

  container_definitions = "${data.template_file.task-def.rendered}"
}

```

【问题讨论】:

  • "portMappings" 应该是一个对象数组,根据documentation。您已将其设置为对象。值得一试吗?
  • "memory": "2048" 这部分似乎是错误所指的问题。意思是应该改为"memory": 2048,所以值是数字而不是字符串。

标签: terraform


【解决方案1】:

Terraform 期望 Json 格式有点不规范。修复此问题后,它将起作用:

  1. 内存大小和端口号应该是整数,而不是字符串
  2. Terraform 需要“带有对象的数组”,而不是 JSON“对象”
  3. 变量 $extra_url 未导入到 template_file.task-def 中

task-def.json 的固定版本,在 terraform v0.11.13provider.aws v2.9.0 上测试:

[
  {
    "name": "sonarqube"
  },
  {
    "image": "sonarqube:7.5-community"
  },
  {
    "memory": 2048
  },
  {
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "tyu",
        "awslogs-region": "tyu",
        "awslogs-stream-prefix": "ecs"
      }
    }
  },
  {
    "portMappings": [
      {
        "hostPort": 9000
      },
      {
        "protocol": "tcp"
      },
      {
        "containerPort": 9000
      }
    ]
  },
  {
    "environment": [
      {
        "name": "sonar.jdbc.password",
        "value": "${password}"
      },
      {
        "name": "sonar.jdbc.url",
        "value": "${url}/${extra_url}"
      },
      {
        "name": "sonar.jdbc.username",
        "value": "${username}"
      }
    ]
  }
]

template_file.task-def的固定版本:

data "template_file" "task-def" {
  template = "${file("${path.module}/task-def.json")}"

  vars = {
    log-group = "/ecs/${var.cluster_name}-${var.name}"
    region    = "${var.region}"
    url       = "jdbc:postgresql://${var.rds_url}${var.extra_url}"
    username  = "${var.username}"
    password  = "${var.password}"
    extra_url  = "${var.extra_url}"
  }
}

【讨论】:

  • 这停止了 JSON 的解组错误,但是出现了这条新消息。 ClientException: Container names must be unique within a Task Definition.
  • 新错误 - 请提出新问题 :) 使用附加到原始问题的代码,我无法重现此错误。也许您已经在其他地方定义或手动创建了同名容器。
  • 我在任务定义中遇到了类似的错误,但问题是特定于环境块的。我在设置环境变量时错过了 name 和 value 键。
猜你喜欢
  • 1970-01-01
  • 2020-05-19
  • 2021-01-31
  • 2016-10-06
  • 2019-06-04
  • 1970-01-01
  • 2021-08-27
  • 2022-08-10
  • 1970-01-01
相关资源
最近更新 更多