Skip to content

google_cloud_run_v2_service sends full service definition on update, instead of just changed fieldsΒ #25464

@andyroyle

Description

@andyroyle

Community Note

  • Please vote on this issue by adding a πŸ‘ reaction to the original issue to help the community and maintainers prioritize this request.
  • Please do not leave +1 or me too comments, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.
  • If an issue is assigned to a user, that user is claiming responsibility for the issue.
  • Customers working with a Google Technical Account Manager or Customer Engineer can ask them to reach out internally to expedite investigation and resolution of this issue.

Terraform Version & Provider Version(s)

Terraform v1.13.x

  • provider registry.terraform.io/hashicorp/google v7.x

Affected Resource(s)

  • google_cloud_run_v2_service

Terraform Configuration

terraform {
  required_version = ">= 1.13"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 7.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

variable "project_id" {
  description = "GCP project ID"
  type        = string
}

variable "region" {
  description = "GCP region"
  type        = string
  default     = "europe-west1"
}

# Dedicated service account for Cloud Run
resource "google_service_account" "cloudrun_sa" {
  account_id   = "cloudrun-nginx-sa"
  display_name = "Cloud Run Nginx Service Account"
}

# Cloud Run v2 service
resource "google_cloud_run_v2_service" "nginx" {
  name     = "nginx-service"
  location = var.region

  template {
    service_account = google_service_account.cloudrun_sa.email

    containers {
      image = "docker.io/library/nginx:latest"

      ports {
        container_port = 80
      }

      resources {
        limits = {
          cpu    = "1"
          memory = "512Mi"
        }
      }
    }
  }

  lifecycle {
    ignore_changes = [
      template[0].containers[0].image
    ]
  }
}

output "service_url" {
  value = google_cloud_run_v2_service.nginx.uri
}

Debug Output

No response

Expected Behavior

When using lifecycle { ignore_changes = [template[0].containers[0].image] } and applying a saved plan, the provider should either:

  1. Use PATCH semantics to only update the fields that actually changed in the Terraform configuration, OR
  2. Read the current state of the resource from GCP at apply time to get the current image value, rather than using the potentially stale value from the saved plan

This would ensure that the ignore_changes directive is truly honored, even when using saved plans in a CI/CD workflow where the plan is generated at one time (e.g., PR creation) and applied later (e.g., after PR merge).

Actual Behavior

The provider sends the entire service definition to the Cloud Run API when updating, including the image field. The image value is read from the Terraform state, which is only refreshed when terraform plan is executed.

When using saved plans, this causes a race condition:

  1. At time T1: terraform plan is run, recording image = "my-image@sha256:abc123" in the plan
  2. At time T2: An external deployment (e.g., a separate CI/CD pipeline) updates the Cloud Run service to image = "my-image@sha256:def456"
  3. At time T3: The saved plan from T1 is applied with terraform apply tfplan
  4. Result: The service is reverted to image = "my-image@sha256:abc123" despite ignore_changes being set

The ignore_changes lifecycle rule only prevents Terraform from detecting changes to the image field during planning. It does not prevent Terraform from overwriting the current image value when applying other changes, because the provider sends the full resource definition rather than using PATCH semantics.

Steps to reproduce

  1. terraform apply - Create the Cloud Run service with image nginx:1.24
  2. Update the Cloud Run service image externally (via gcloud or another CI/CD pipeline) to nginx:1.25
  3. Make a change to another field in the Terraform config (e.g., change memory = "512Mi" to memory = "1Gi")
  4. terraform plan -out=tfplan - Plan shows only the memory change (image change is correctly ignored)
  5. Update the Cloud Run service image externally again to nginx:1.26
  6. terraform apply tfplan - Apply the saved plan
  7. Observe that the image has been reverted to nginx:1.24 (the value at step 1) instead of remaining at nginx:1.26

Important Factoids

No response

References

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions