我有两个条件需要满足:
- 根据
env
授予用户对特定project-id
的权限。例如:my-project-{env}
(env: stg/prd) - 我想循环遍历变量,而不是为每个用户写下重复的
resource
。
例子:
variable some_ext_users {
type = map(any)
default = {
user_1 = { email_id = "user_1@gmail.com" }
user_2 = { email_id = "user_2@gmail.com" }
}
}
为了避免对每个用户(想象100++用户)进行重复资源,我决定将它们列在上面所写的variable
中。
然后,我想给这些用户分配GCS权限,例如:
resource "google_storage_bucket_iam_member" "user_email_access" {
for_each = var.some_ext_users
count = var.env == "stg" ? 1 : 0
provider = google-beta
bucket = "my-bucketttt"
role = "roles/storage.objectViewer"
member = "user:${each.value.email_id}"
}
我得到的错误是明确的:
错误:无效的"count"组合和";for_each"在. ./. ./. ./模块/助教。在资源的第54行"google_storage_bucket_iam_member"user_email_access">: 54:
for_each = var.some_ext_users"count"one_answers";for_each"元参数是互斥的,只能使用一个显式指定要创建的资源数量
我的问题是,什么是解决方案,以满足上述要求,如果count
和for_each
不能一起使用?
您可以根据环境控制用户列表,而不是试图控制资源。像这样:
resource "google_storage_bucket_iam_member" "user_email_access" {
for_each = var.env == "stg" ? var.some_ext_users : {}
provider = google-beta
bucket = "my-bucketttt"
role = "roles/storage.objectViewer"
member = "user:${each.value.email_id}"
}
for_each
的规则是为它分配一个映射,每个实例有一个元素,因此考虑您的需求的最佳方法是,当您的条件不成立时,您需要编写一个表达式,生成一个零元素的映射。
for
表达式,实际上我们可以使用for
表达式和if
子句来有条件地过滤掉不需要的元素,在这种特殊情况下将是所有元素:
resource "google_storage_bucket_iam_member" "user_email_access" {
for_each = {
for name, user in var.some_ext_users : name => user
if var.env == "stg"
}
# ...
}
另一种可能的构建方法是将环境关键字作为数据结构的一部分,这将使所有信息保存在一个位置,并可能允许您拥有一次应用于多个环境的项:
variable "some_ext_users" {
type = map(object({
email_id = string
environments = set(string)
}))
default = {
user_1 = {
email_id = "user_1@gmail.com"
environments = ["stg"]
}
user_2 = {
email_id = "user_2@gmail.com"
environments = ["stg", "prd"]
}
}
}
resource "google_storage_bucket_iam_member" "user_email_access" {
for_each = {
for name, user in var.some_ext_users : name => user
if contains(user.environments, var.env)
}
# ...
}
这是"过滤元素"中示例的变体。它使用is_admin
标志,以便为管理员用户和非管理员用户声明不同的资源。在本例中,请注意if
子句引用了在for
表达式中声明的符号,这意味着我们现在可以为映射的每个元素获得不同的结果,而第一个示例要么保留所有元素,要么不保留元素。