【问题标题】:Terraform nested dynamic block: Unsupported block typeTerraform 嵌套动态块:不支持的块类型
【发布时间】:2020-10-13 02:49:21
【问题描述】:

我正在尝试执行以下操作。

  dynamic "volume" {
    for_each = var.volumes
    content {
      host_path = lookup(volume.value, "host_path", null)
      name      = volume.value.name

      dynamic "efs_volume" {
        for_each = var.efs_volumes
        content {
          name = efs_volume.value.name
          efs_volume_configuration {
            file_system_id     = efs_volume.value.file_system_id
            root_directory     = efs_volume.value.root_directory
            transit_encryption = efs_volume.value.transit_encryption != "ENABLED" ? "" : "ENABLED"
            dynamic "authorization_config" {
              for_each = efs_volume.value.access_point_id != "" ? [1] : []
              content {
                access_point_id = volume.value.access_point_id
              }
            }
          }
        }
      }
    }
  }

它给了我,

错误:不支持的块类型

此处不应出现“efs_volume”类型的块

谁能指出这里有什么问题?我正在使用 terraform 0.12.24。

请注意,我知道 AWS 提供商仍然不支持“authorization_config”,我希望在我看到 github 拉取请求后该功能会尽快推出。因此,我正在准备我的代码兼容性。基本上,我需要将主机和 EFS 卷都挂载到我的 ECS 任务定义中。

编辑

我按照你说的更新了代码。

  dynamic "volume" {
    for_each = var.volumes
    content {
      host_path = lookup(volume.value, "host_path", null)
      name      = volume.value.name

      dynamic "efs_volume_configuration" {
        for_each = lookup(volume.value, "efs_volume_configuration", [])
        content {
          file_system_id = lookup(efs_volume_configuration.value, "file_system_id", null)
          root_directory = lookup(efs_volume_configuration.value, "root_directory", null)
        }
      }
    }
  }```

Now the problem is, 

> efs_volume_configuration

getting added to each volume block. Which actually need to be null.

```      + volume { # forces replacement
          + host_path = "/var/run"
          + name      = "docker-sock-folder"

          + efs_volume_configuration {}
        }
      + volume { # forces replacement
          + host_path = "/var/run/docker/netns"
          + name      = "docker-netns"

          + efs_volume_configuration {}
        }
      + volume { # forces replacement
          + name = "efs_share"

          + efs_volume_configuration {
              + file_system_id = "fs-xxxxxx"
              + root_directory = "/"
            }
        }

编辑

这是我的变量..

  type = list(object({
    name      = string
    host_path = string
    efs_volume_configuration = list(object({
      file_system_id = string
      root_directory = string
    }))
  }))
  description = "Task volume definitions as list of configuration objects"
  default = [
    {
      "name" : "data-folder",
      "host_path" : "/var/lib/data",
      "efs_volume_configuration" = [
        {
          "file_system_id" : "",
          "root_directory" : ""
        }
      ]
    },
    {
      "name" : "docker-sock-folder",
      "host_path" : "/var/run",
      "efs_volume_configuration" = [
        {
          "file_system_id" : "",
          "root_directory" : ""
        }
      ]
    },
    {
      "name" : "efs_share",
      "host_path" : null,
      "efs_volume_configuration" = [
        {
          "file_system_id" : "fs-xxxxxx",
          "root_directory" : "/"
        }
      ]
    }

....

【问题讨论】:

    标签: terraform terraform-provider-aws terraform0.12+


    【解决方案1】:

    对于 ecs 任务定义资源 efs_volume 不是受支持的参数。如果您正在寻找一个完全工作的模块,也许我编写的模块运行良好并发布到 terraform 注册表可能会有所帮助。 https://github.com/umotif-public/terraform-aws-ecs-fargate-task-definition/blob/master/main.tf#L157

    要使用 efs 卷,您可以定义以下动态块:

    dynamic "volume" {
    for_each = var.volume
    content {
      name      = volume.value.name
      host_path = lookup(volume.value, "host_path", null)
    
      dynamic "docker_volume_configuration" {
        for_each = lookup(volume.value, "docker_volume_configuration", [])
        content {
          scope         = lookup(docker_volume_configuration.value, "scope", null)
          autoprovision = lookup(docker_volume_configuration.value, "autoprovision", null)
          driver        = lookup(docker_volume_configuration.value, "driver", null)
          driver_opts   = lookup(docker_volume_configuration.value, "driver_opts", null)
          labels        = lookup(docker_volume_configuration.value, "labels", null)
        }
      }
    
      dynamic "efs_volume_configuration" {
        for_each = lookup(volume.value, "efs_volume_configuration", [])
        content {
          file_system_id = lookup(efs_volume_configuration.value, "file_system_id", null)
          root_directory = lookup(efs_volume_configuration.value, "root_directory", null)
        }
      }
    }
    

    在这种情况下,efs_volume_configuration 是一个支持块。一旦你在你的模块中有了它,你可以通过以下方式传入 efs config:

    module "ecs-task-definition" {
    ...
      volume = [
        {
          name = "efs-html",
          efs_volume_configuration = [
            {
              "file_system_id" : "efs_id",
              "root_directory" : "/usr/share/nginx"
            }
          ]
        }
      ]
    }
    

    重要提示:您至少需要 terraform aws provider v2.64.0 版本。

    【讨论】:

    • 我添加了一个如何将变量传递到模块的示例。希望有帮助
    • 感谢您的支持。您能否检查一下我的编辑部分。更改我的代码后,现在的问题是 efs_volume_configuration {} 被添加到每个卷中,实际上需要为空。
    • 我认为这不是问题。它不应该失败。
    • 对于卷 data-folderdocker-sock-folder 删除 efs_volume_configuration
    • 您应该创建 efs 卷作为模块的一部分或作为 efs 卷的数据源,然后引用 efs id。它不应该在你的变量中硬编码
    猜你喜欢
    • 2021-10-18
    • 2021-11-11
    • 1970-01-01
    • 2019-05-29
    • 2020-09-25
    • 2021-08-25
    • 2020-05-30
    • 2019-10-20
    • 2020-09-06
    相关资源
    最近更新 更多