使用 JSON 个值创建 Terraform 资源

Create Terraform resources out of JSON values

我正在寻找一种基于 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 资源,例如像这样的 beantalk 环境:

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的结构非常相似,但不完全相同。参见例如JSON.

中的设置、conf 或设置而不是名称

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

总结一下:

有人知道怎么做吗?还有其他方法吗? 非常感谢!

假设您的 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 block 是一种创建重复 setting 块的宏,每个块都与 for_each 中给出的集合中的一个元素相关联。

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