2

我正在寻找一种基于 JSON 值生成 Terraform 代码的方法。想象一下,我有一个具有以下结构的 JSON 文件:

{
  "settings": [
    {
      "conf": [
        {
          "setting": "DeploymentPolicy",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "AllAtOnce"
        },
        {
          "setting": "BatchSize",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "30"
        },
        {
          "setting": "BatchSizeType",
          "namespace": "aws:elasticbeanstalk:command",
          "value": "Percentage"
        }
      ]
    }
  ]
}

我想做的是以下内容:根据 JSON 文件值创建一个工作的 Terraform 资源,例如像这样的 beanstalk 环境:

resource "aws_elastic_beanstalk_environment" "app_prod" {
  name                   = "${aws_elastic_beanstalk_application_version.app.name}-prod"
  application            = aws_elastic_beanstalk_application.app.name
  solution_stack_name    = data.aws_elastic_beanstalk_solution_stack.latest_linux_java.name
  wait_for_ready_timeout = "10m"
  version_label          = aws_elastic_beanstalk_application_version.app.name

  # Elastic beanstalk configuration
  setting {
    name      = "DeploymentPolicy"
    namespace = "aws:elasticbeanstalk:command"
    value     = "AllAtOnce"
  }
  setting {
    name      = "BatchSize"
    namespace = "aws:elasticbeanstalk:command"
    value     = "30"
  }

  ...

}

因此,我必须根据 JSON 值在 HCL(Terraform 配置)中创建设置块。这意味着上面的 JSON 文件应该导致:

  setting {
    name      = "DeploymentPolicy"
    namespace = "aws:elasticbeanstalk:command"
    value     = "AllAtOnce"
  }
  setting {
    name      = "BatchSize"
    namespace = "aws:elasticbeanstalk:command"
    value     = "30"
  }
  setting {
    name      = "BatchSizeType"
    namespace = "aws:elasticbeanstalk:command"
    value     = "Percentage"
  }

如您所见,JSON 和 HCL 的结构非常相似,但并不完全相同。参见例如设置、conf 或设置而不是 JSON 中的名称。

一种可能的方法是读取 JSON 值并将它们存储在数组或映射中。但我不知道如何生成有效的 HCL 并将其注入资源的所需部分。此外,我尝试使用模板,但 Terraform 不支持我需要遍历设置的循环功能。

总结一下:

  • 输入是必须读取的 JSON 文件
  • JSON 包含设置(除了其他信息)
  • 设置的数量可以不同
  • 不知何故,我必须生成一个设置块
  • 不知何故,我必须在资源中注入这个设置块

有谁知道如何做到这一点?还有其他方法吗?非常感谢!

4

1 回答 1

5

假设您的 JSON 对象位于settings.json模块目录内的一个文件中,您可以执行以下操作:

locals {
  environment_settings = jsondecode(file("${path.module}/settings.json")).settings[0].conf[0]
}

resource "aws_elastic_beanstalk_environment" "app_prod" {
  name                   = "${aws_elastic_beanstalk_application_version.app.name}-prod"
  application            = aws_elastic_beanstalk_application.app.name
  solution_stack_name    = data.aws_elastic_beanstalk_solution_stack.latest_linux_java.name
  wait_for_ready_timeout = "10m"
  version_label          = aws_elastic_beanstalk_application_version.app.name

  dynamic "setting" {
    for_each = local.environment_settings
    content {
      namespace = setting.value.namespace
      name      = setting.value.setting
      value     = setting.value.value
    }
  }
}

这个特殊的dynamic是一种创建重复setting块的宏,每个块都与给定的集合中的一个元素相关联for_each

您可以在locals块中使用 Terraform 的表达式语言对输入进行任何转换,以确保该local.environment_settings值包含您将生成的每个setting块的一个元素,然后在content嵌套块中告诉 Terraform 如何setting根据这些元素值填充参数.

于 2020-01-11T01:12:50.137 回答