代码之家  ›  专栏  ›  技术社区  ›  Sallyerik

如何在地形数据调用中连接变量?

  •  0
  • Sallyerik  · 技术社区  · 4 年前

    我试图在Terraform数据分配中连接一个声明的变量,以构建一个动态调用。

    具有以下代码:

    # Policy 1
    data "aws_iam_policy_document" "1_s3_access_policy" {
       statement {
         effect = "Allow"
         actions = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:DeleteObject",
         ]
         resources = [
          "arn:aws:s3:::1_s3_access_policy/*",
          "arn:aws:s3:::1_s3_access_policy",
         ]
         principals {
          type        = "AWS"
          identifiers = ["arn:aws:iam::67435677645:user/d2c-user-us-west-1"]
         }
       }
     }
    # policy 2
    data "aws_iam_policy_document" "2_s3_access_policy" {
        statement {
         effect = "Allow"
         actions = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:DeleteObject",
         ]
         resources = [
          "arn:aws:s3:::2_s3_access_policy/*",
          "arn:aws:s3:::2_s3_access_policy",
         ]
         principals {
          type        = "AWS"
          identifiers = ["arn:aws:iam::67435677645:user/d2c-user-us-west-1"]
         }
       }
     }
    # Policy 3
    ...
    variable "s3_bucket_names" {
          type    = list(any)
          default = ["1_s3_access_policy", "2_s3_access_policy", "3_s3_access_policy"]
    }
    
    module "platform-cloud" {
          source              = "./module"
          count               = length(var.s3_bucket_names) //count will be 3
          bucket_name         = var.s3_bucket_names[count.index]
          sse_algorithm       = "aws:kms"
          iam_policy_document =  data.aws_iam_policy_document.${var.s3_bucket_names[count.index]}.json
    }
    

    它因错误而失败:

    Error: Invalid character

    on main.tf line 10, in module "platform-cloud":

    iam_policy_document = data.aws_iam_policy_document.${var.s3_bucket_names[count.index]}.json

    This character is not used within the language.

    是否有方法将变量连接在 地形数据 呼叫

    1 回复  |  直到 4 年前
        1
  •  2
  •   Martin Atkins    4 年前

    Terraform无法以您尝试的方式动态查找资源,因为这意味着资源依赖关系要到评估时才能决定,但Terraform需要在评估任何表达式之前知道正确的依赖关系顺序。

    然而,你 可以 通过使用键创建映射的额外步骤来满足动态选择资源的用例,然后使用键来选择每个资源:

    locals {
      bucket_policies = {
        s3_access_policy_1 = data.aws_iam_policy_document.s3_access_policy_1
        s3_access_policy_2 = data.aws_iam_policy_document.s3_access_policy_2
        s3_access_policy_3 = data.aws_iam_policy_document.s3_access_policy_3
      }
    }
    
    module "platform-cloud" {
      source = "./module"
      count  = length(var.s3_bucket_names) //count will be 3
    
      bucket_name         = var.s3_bucket_names[count.index]
      sse_algorithm       = "aws:kms"
      iam_policy_document = local.bucket_policies[var.s3_bucket_names[count.index]].json
    }
    

    我已将您的数据资源的名称更改为 s3_access_policy_1 而不是 1_s3_access_policy 因为Terraform不允许资源名称以数字开头。Terraform还没有报告该错误消息,因为您有语法错误,但解决语法错误会暴露命名错误。

    现在请注意 module.platform-cloud s iam_policy_document 指的是 local.bucket_policies ,这反过来又取决于所有三个数据资源。Terraform因此明白,在评估模块参数之前,它必须评估所有三个数据资源,从而产生正确的评估顺序。


    虽然与你的问题没有直接关系,但我建议你阅读 When to use for_each instead of count 来决定是否更好地使用 for_each 在您的 module "platform-cloud" 块,而不是 计数 .

        2
  •  1
  •   Marcin    4 年前

    通常情况下,您会按照以下方式进行操作:

    iam_policy_document =  data.aws_iam_policy_document[var.s3_bucket_names[count.index]].json
    

    具体细节取决于 data.aws_iam_policy_document 定义了。但遗憾的是,你的问题中没有提供这样的信息。