I am working on setting up VPC Service control in GCP using google_access_context_manager_service_perimeter provider. In this resource, within status block, I have to specify a list of google projects as resources
value in the format "projects/123456789"
. I want to put the project numbers in a variable and created something like this.
variable "project_numbers_to_protect" {
type = list(any)
default = [
"123456",
"456789",
"894321"
]
}
I am able to reference the variable as below.
resources = ["projects/${var.project_numbers_to_protect[0]}",
"projects/${var.project_numbers_to_protect[1]}",
"projects/${var.project_numbers_to_protect[2]}"]
But in my production case, I have a large number of projects in the list and I am looking for option to reference it dynamically. I tried count
option, but that didn't work.
count = var.project_numbers_to_protect
resources = ["projects/${var.project_numbers_to_protect[count.index]}"]
Error message
vpc-sc-module $ terraform validate
╷
│ Error: Reference to "count" in non-counted context
│
│ on vpc-sc-copy.tf line 16, in resource "google_access_context_manager_service_perimeter" "regular_service_perimeter":
│ 16: resources = ["projects/${var.project_numbers_to_protect[count.index]}"]
│
│ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set.
╵
Appreciate any help. Thanks.
Full Code
vpc-sc-copy.tf
resource "google_access_context_manager_service_perimeter" "regular_service_perimeter" {
parent = "accessPolicies/${var.access_context_manager_policy_number}"
name = "accessPolicies/${var.access_context_manager_policy_number}/servicePerimeters/${var.perimeter_name}"
perimeter_type = var.perimeter_type
title = var.perimeter_name
use_explicit_dry_run_spec = false
status {
restricted_services = var.restricted_services
## Below two lines works.
# resources = ["projects/${var.project_numbers_to_protect[0]}",
# "projects/${var.project_numbers_to_protect[1]}",]
## Below option doesn't work
count = var.project_numbers_to_protect
resources = ["projects/${var.project_numbers_to_protect[count.index]}"]
ingress_policies {
ingress_from {
identity_type = "ANY_IDENTITY"
sources {
access_level = "*"
}
}
ingress_to {
resources = [
"*"
]
dynamic "operations" {
for_each = var.ingress_rule1_service_name
content {
service_name = operations.value
method_selectors {
method = "*"
}
}
}
}
}
egress_policies {
egress_from {
identities = ["serviceAccount:service-${var.project_number_to_protect}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"]
}
egress_to {
resources = [
"projects/${var.egress_rule1_project_number}"
]
operations {
service_name = "storage.googleapis.com"
dynamic "method_selectors" {
for_each = var.egress_rule1_methods
content {
method = method_selectors.value
}
}
}
}
}
egress_policies {
egress_from {
identity_type = "ANY_IDENTITY"
}
egress_to {
resources = [
"projects/${var.egress_rule2_project_number}"
]
operations {
service_name = "storage.googleapis.com"
dynamic "method_selectors" {
for_each = var.egress_rule2_methods
content {
method = method_selectors.value
}
}
}
}
}
}
}
Relevant section of vars.tf
variable "project_numbers_to_protect" {
type = list(any)
default = [
"123456",
"456789",
"894321"
]
}
As the error writes, you can't use count
the way you want. Instead it should be:
resource "google_access_context_manager_service_perimeter" "regular_service_perimeter" {
parent = "accessPolicies/${var.access_context_manager_policy_number}"
name = "accessPolicies/${var.access_context_manager_policy_number}/servicePerimeters/${var.perimeter_name}"
perimeter_type = var.perimeter_type
title = var.perimeter_name
use_explicit_dry_run_spec = false
status {
restricted_services = var.restricted_services
resources = [for project_number in var.project_numbers_to_protect:
"projects/${project_number}" ]
ingress_policies {
ingress_from {
identity_type = "ANY_IDENTITY"
sources {
access_level = "*"
}
}
ingress_to {
resources = [
"*"
]
dynamic "operations" {
for_each = var.ingress_rule1_service_name
content {
service_name = operations.value
method_selectors {
method = "*"
}
}
}
}
}
egress_policies {
egress_from {
identities = ["serviceAccount:service-${var.project_number_to_protect}@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"]
}
egress_to {
resources = [
"projects/${var.egress_rule1_project_number}"
]
operations {
service_name = "storage.googleapis.com"
dynamic "method_selectors" {
for_each = var.egress_rule1_methods
content {
method = method_selectors.value
}
}
}
}
}
egress_policies {
egress_from {
identity_type = "ANY_IDENTITY"
}
egress_to {
resources = [
"projects/${var.egress_rule2_project_number}"
]
operations {
service_name = "storage.googleapis.com"
dynamic "method_selectors" {
for_each = var.egress_rule2_methods
content {
method = method_selectors.value
}
}
}
}
}
}
}