terraform-google-cloud-run icon indicating copy to clipboard operation
terraform-google-cloud-run copied to clipboard

Cloud run V2 - multi containers exposed port

Open sylvain-actual opened this issue 9 months ago • 6 comments

Hello,

I am trying to setup a multiple container cloud run, but I am getting this error :

Error creating Service: googleapi: Error 400: template.containers: Revision template should contain exactly one container with an exposed port.

My setup :

module "multi" {
  source  = "GoogleCloudPlatform/cloud-run/google//modules/v2"
  version = "0.16.3"

  project_id      = "XXXX"
  service_name    = "hello-world"
  location        = "europe-west9"

  containers      = [
    {
      container_image = "nginx:latest"
      container_name  = "nginx"
      ports = {
        name           = "http1"
        container_port = "80"
      }
    },
    {
      container_image = "us-docker.pkg.dev/cloudrun/container/hello"
      container_name  = "hello"
    },
  ]
}

So maybe I am missing someting, of this local is not working as expected :

  ingress_container = try(
    [for container in var.containers : container if length(try(container.ports, {})) > 0][0],
    null
  )

This one should work :

containers_with_ports = [for c in var.containers : c if lookup(c, "port", null) != null]

Thx

sylvain-actual avatar Feb 07 '25 15:02 sylvain-actual

Update :

add local :

containers_with_ports = [for c in var.containers : c if lookup(c, "port", null) != null]

Add in dynamic "ports" loop :

for_each = lookup(containers.value, "port", null) != null && length(local.containers_with_ports) == 1 ? [1] : []

And deploy works with 2 containers.

sylvain-actual avatar Feb 10 '25 15:02 sylvain-actual

Getting this same issue on v0.17.0.

Seems it should fall back on no ports if none are specified but it doesn't, and instead insists on apply a default port.

Gonna have to abandon this module until it's fixed 😞

max-l-weaver avatar Mar 12 '25 17:03 max-l-weaver

I'm using 0.17.0.

I think this part for_each = lookup(containers.value, "ports", {}) != {} always evaluates to true, because the lookup finds default values even when ports is not specified.

If I copy the module to my project, change the variables.tf to say

ports = optional(object({
      name           = optional(string)
      container_port = optional(number)
    }), {})

the plan of my sidecar becomes + ports {} .

But now I must also specify

ports = {
        name = "http1"
        container_port = 8080
      }

on my main container.

krissrex avatar Mar 26 '25 15:03 krissrex

How about settings ports to {} for any container that is not the first one?

olivier-lacroix avatar May 10 '25 10:05 olivier-lacroix

Is there any solution to this on the latest version of the module ?

jeunii avatar Jun 19 '25 15:06 jeunii

@krissrex

So I cloned 0.17.0 and made the change in variables.tf as you indicated

    ports = optional(object({
      name           = optional(string)
      container_port = optional(number)
    }), {})

My main.tf now looks like this

module "cloud_run_core" {
  #source = "/Users/jeunii/Work/calix/terraform-google-modules-v2/cloud-run-v2"
  source  = "GoogleCloudPlatform/cloud-run/google//modules/v2"
  version = "0.17.0"

  project_id      = "XXXXXXXXXX"
  service_name    = "hello-world1"
  location        = "us-central1"
  containers      = [
    {
      container_image = "us-docker.pkg.dev/cloudrun/container/hello"
      container_name = "hello-world"
      #depends_on_container = ["hello-world-2"]
      ports = {
        name = "http1"
        container_port = 80
      }
    },
    {
      container_image = "us-docker.pkg.dev/cloudrun/container/hello"
      container_name = "hello-world-2"
    }
  ]
}

The plan looks like this

...
          + containers {
              + build_info = (known after apply)
              + image      = "us-docker.pkg.dev/cloudrun/container/hello"
              + name       = "hello-world"

              + ports {
                  + container_port = 80
                  + name           = "http1"
                }

              + resources {
                  + cpu_idle          = true
                  + limits            = (known after apply)
                  + startup_cpu_boost = false
                }

              + startup_probe (known after apply)
            }
          + containers {
              + build_info = (known after apply)
              + image      = "us-docker.pkg.dev/cloudrun/container/hello"
              + name       = "hello-world-2"

              + ports {
                  + name = (known after apply)
                }

              + resources {
                  + cpu_idle          = true
                  + limits            = (known after apply)
                  + startup_cpu_boost = false
                }

              + startup_probe (known after apply)
            }

          + scaling (known after apply)
        }

      + traffic (known after apply)
    }
...

Not sure why Im still getting

              + ports {
                  + name = (known after apply)
                }

This results in

│ Error: Error creating Service: googleapi: Error 400: Violation in CreateServiceRequest.service.template.containers[1].ports[0].container_port: must be 0 < port_number < 65536.
│ Details:

jeunii avatar Jun 19 '25 16:06 jeunii