我有一个包含以下代码的模块。
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。
我不确定问题出在哪里。有人能给点建议吗?
发布于 2021-09-13 22:12:34
如错误消息所示,您不能这样做。您的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
]发布于 2021-09-14 00:05:01
这里的关键问题是,您试图使用字符串的长度作为count条件的一部分,但是string模板包含的值在apply步骤之前是未知的,因此字符串的长度在apply步骤之前也是未知的。
要实现这一点,您需要找到某种方法,将是否声明对象的指示与它将使用的确切策略字符串分开。
要实现这一点,一种方法是将特定的字符串值包装在一个对象中,该对象可以完全为空,以表示根本不声明策略。例如:
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,并且策略文档将作为参数传入。
https://stackoverflow.com/questions/69169472
复制相似问题