Reputation: 125
I have deployed a cloud run application for currently two domains with a load balancer, which is already running. Now this setup needs to be rolled out to other domains. Because the resource setup is always the same, I face some issues:
The first issue I solved like this, which seems to work:
Old:
resource "google_cloud_run_service" "cr_domain1" {
name = "cr-domain1"
location = "europe-west6"
project = "my_project"
template {
...
}
}
resource "google_cloud_run_service" "cr_domain2" {
name = "cr-domain2"
location = "europe-southwest1"
project = "my_project"
template {
...
}
}
New:
resource "google_cloud_run_service" "cr" {
for_each = toset( ["domain1", "domain2"] )
name = "cr-${each_key}"
location = "tdb" # This is my second issue
project = "my_project"
template {
...
}
}
Regarding second issue I still need domain-specific location setup, which I tried to solve like this, but I am getting errors:
variable "cr_location" {
type = list(object({
domain1 = string
domain2 = string
}))
default = [{
domain1 = "europe-west6"
domain2 = "europe-southwest1"
}]
}
resource "google_cloud_run_service" "cr" {
for_each = toset( ["domain1", "domain2"] )
name = "cr-${each_key}"
location = "${var.cr_location[0]}.${each.key}"
project = "my_project"
template {
...
}
}
Error is "Cannot include the given value in a string template: string required". But I have already declared it as a string in my variable "cr_location". Any idea what's the issue here? The expected output should be:
Also regarding issue 3 I do not understand how to referencing resources, which are created with for_each in another resource. So before my for_each in the cloud run resource block (see issue 1) I had this 2 resources:
Now I only have resource "google_cloud_run_service" "cr". But in my loadbalancer.tf I still have to references to the old namings (last coderow within "service"):
resource "google_compute_region_network_endpoint_group" "backendneg" {
for_each = toset( ["domain1", "domain2"] )
name = "backendneg-${each.key}"
project = "my_project"
network_endpoint_type = "SERVERLESS"
region = "${var.cr_location[0]}.${each.key}" # Here same issues as issue 2
cloud_run {
service = google_cloud_run_service.cr_domain1.name # Old reference
}
}
So if there is no "cr_domain1" anymore how do I reference to this resource? My issue is that I have to create over 20 resources like that and I couldn't figure it out how to do it. I appreciate any guideline here.
Upvotes: 1
Views: 505
Reputation: 18108
What I would suggest here is to try and refactor the variable because it is making a lot of things harder than they should be. So I would go for this kind of a variable definition:
variable "cr_location" {
type = map(string)
default = {
domain1 = "europe-west6"
domain2 = "europe-southwest1"
}
}
Then, the rest should be easy to create:
resource "google_cloud_run_service" "cr" {
for_each = var.cr_location
name = "cr-${each.key}"
location = each.value
project = "my_project"
template {
...
}
}
And for the network endpoint resource:
resource "google_compute_region_network_endpoint_group" "backendneg" {
for_each = var.cr_location
name = "backendneg-${each.key}"
project = "my_project"
network_endpoint_type = "SERVERLESS"
region = each.value
cloud_run {
service = google_cloud_run_service.cr[each.key].name
}
}
You could even try resource chaining with for_each
[1] to make sure you are doing this for all the Cloud Run resources created:
resource "google_compute_region_network_endpoint_group" "backendneg" {
for_each = google_cloud_run_service.cr
name = "backendneg-${each.key}"
project = "my_project"
network_endpoint_type = "SERVERLESS"
region = each.value.location
cloud_run {
service = each.value.name
}
}
[1] https://www.terraform.io/language/meta-arguments/for_each#chaining-for_each-between-resources
Upvotes: 2