【问题标题】:Invalid count argument in terraformterraform 中的无效计数参数
【发布时间】:2021-09-13 21:50:56
【问题描述】:

我有一个包含以下代码的模块。

resource "aws_s3_bucket" "main" {
  bucket = var.bucket_name
  acl    = "private"
  tags   = var.tags

  versioning {
    enabled = var.versioning_enabled
  }
}

resource "aws_s3_bucket_policy" "mod" {
  depends_on = [aws_s3_bucket.main]
  count  = length(var.bucket_policy) > 0 ? 1 : 0
  bucket = aws_s3_bucket.main.id
  policy = var.bucket_policy
}

variable "bucket_policy" {
  default = ""
}

我使用下面的代码调用模块,为了安全起见,我已对其进行了编辑。

module "xxxx-api-s3-firehose" {
  source      = "git::ssh://git@github.com/xxxx/infra-terraform-modules-s3?ref=v1.0.0"
  bucket_name = "reporting-xxxxxx-api-${var.env_suffix}-${var.region}"

  bucket_policy = <<EOF
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "xxx Bucket Permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "${aws_iam_role.xxxxx-api-firehose-role.arn}"
         },
         "Action": [
            "s3:Get*",
            "s3:List*",
            "s3:Put*"
         ],
         "Resource": [
            "arn:aws:s3:::${module.xxxx-api-s3-firehose.bucket_id}",
            "arn:aws:s3:::${module.xxxxx-api-s3-firehose.bucket_id}/*"
         ]
      },
      {
         "Sid": "xx Bucket Permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::${var.account_id}:role/${var.xxxxx}"
         },
         "Action": [
            "s3:Get*",
            "s3:List*",
            "s3:Put*"
         ],
         "Resource": [
            "arn:aws:s3:::${module.xxx-api-s3-firehose.bucket_id}",
            "arn:aws:s3:::${module.xxx-api-s3-firehose.bucket_id}/*"
         ]
      }
   ]
}
EOF

我在运行terraform apply 后收到以下错误。

 Error: Invalid count argument
│ 
│   on xxxxx-backend-dev.xxxx-api-s3-firehose/main.tf line 39, in resource "aws_s3_bucket_policy" "mod":
│   39:   count  = length(var.bucket_policy) > 0 ? 1 : 0
│ 
│ The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the count depends on.
╵

我在多个版本的 terraform 中收到错误,包括最新的 1.0.6。

我不确定是什么问题。有人可以建议吗?

【问题讨论】:

    标签: amazon-web-services count terraform apply depends


    【解决方案1】:

    正如错误消息提示的那样,您不能这样做。您的bucket_policy 长度不是恒定的。您应该能够使用列表来克服这个问题:

    variable "bucket_policy" {
      default = []
    }
    
    resource "aws_s3_bucket_policy" "mod" {
      depends_on = [aws_s3_bucket.main]
      count  = length(var.bucket_policy) > 0 ? 1 : 0
      bucket = aws_s3_bucket.main.id
      policy = var.bucket_policy[0]
    }
    
    

    和

    module "xxxx-api-s3-firehose" {
      source      = "git::ssh://git@github.com/xxxx/infra-terraform-modules-s3?ref=v1.0.0"
      bucket_name = "reporting-xxxxxx-api-${var.env_suffix}-${var.region}"
    
      bucket_policy = [<<EOF
    {
       "Version": "2012-10-17",
       "Statement": [
          {
             "Sid": "xxx Bucket Permissions",
             "Effect": "Allow",
             "Principal": {
                "AWS": "${aws_iam_role.xxxxx-api-firehose-role.arn}"
             },
             "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:Put*"
             ],
             "Resource": [
                "arn:aws:s3:::${module.xxxx-api-s3-firehose.bucket_id}",
                "arn:aws:s3:::${module.xxxxx-api-s3-firehose.bucket_id}/*"
             ]
          },
          {
             "Sid": "xx Bucket Permissions",
             "Effect": "Allow",
             "Principal": {
                "AWS": "arn:aws:iam::${var.account_id}:role/${var.xxxxx}"
             },
             "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:Put*"
             ],
             "Resource": [
                "arn:aws:s3:::${module.xxx-api-s3-firehose.bucket_id}",
                "arn:aws:s3:::${module.xxx-api-s3-firehose.bucket_id}/*"
             ]
          }
       ]
    }
    EOF
    ]
    

    【讨论】:

      【解决方案2】:

      这里的关键问题是您试图将字符串的长度用作count 条件的一部分,但字符串模板包含的值在应用步骤之前不知道,因此在应用步骤之前也无法知道字符串。

      要使这项工作发挥作用,您需要找到某种方法,将是否声明对象的指示与其将使用的确切策略字符串分开。

      实现这一点的一种方法是将特定的字符串值包装在一个可以完全为空的对象中,以表示根本没有声明策略。例如:

      variable "bucket_policy" {
        type = object({
          json = string
        })
        default = null
      }
      
      resource "aws_s3_bucket_policy" "mod" {
        count = var.bucket_policy != null ? 1 : 0
      
        bucket = aws_s3_bucket.main.id
        policy = var.bucket_policy.json
      }
      

      调用模块时:

        bucket_policy = {
          json = jsonencode({
            # (the policy document content, as before)
          })
        }
      

      使用这种结构,即使var.bucket_policy.json 不知道,var.bucket_policy 也可以知道 ,因此我们将是否声明策略的决定与具体策略分开文件价值。

      如果您将bucket_policy 设置为null(无论是显式设置还是仅通过在module 块中省略其定义),则策略资源将具有count = 0。如果您将其设置为如上所示的非空对象,则策略资源将具有count = 1,并且策略文档将作为参数传入。

      【讨论】:

        猜你喜欢
        • 2020-12-28
        • 2021-01-30
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 2020-03-31
        • 2016-07-07
        • 2019-03-08
        • 2022-01-12
        相关资源
        最近更新 更多