terraform-provider-google: False positive diff in `google_cloud_tasks_queue` resources on field `app_engine_routing_override`

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 the modular-magician user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned to hashibot, a community member has claimed the issue already.

Terraform Version

❯ terraform -v
Terraform v1.4.6
on darwin_arm64
+ provider registry.terraform.io/hashicorp/google v4.64.0

Affected Resource(s)

  • google_cloud_tasks_queue

Terraform Configuration Files

This is a terraform module I use for creation cloud_task.

variable "name" {
  type        = string
  description = "name of the task"
}

variable "location" {
  type        = string
  description = "location of  the task"
}

variable "project_id" {
  description = "name of the project"
}

variable "retry_config" {
  default     = {}
  description = "If a job does not complete successfully, Ifan acknowledgement is not received from the handler, then it will be retried with mentioned configuration"
}

variable "rate_limits" {
  default     = {}
  description = "Rate limits for task dispatches."
}

variable "app_engine_routing_override" {
  type       = object({
    service = optional(string)
    version = optional(string)
    instance = optional(string)
  })
  default = {}
  description = "App Engine Routing for the task. If set, app_engine_routing_override is used for all tasks in the queue, no matter what the setting is for the task."
}

resource "google_cloud_tasks_queue" "this" {
  project  = var.project_id
  name     = var.name
  location = var.location
  dynamic "retry_config" {
    for_each = var.retry_config != {} ? [var.retry_config] : toset([])
    content {
      max_attempts       = try(retry_config.value.max_attempts, null)
      max_retry_duration = try(retry_config.value.max_retry_duration, null)
      max_backoff        = try(retry_config.value.max_backoff, null)
      min_backoff        = try(retry_config.value.min_backoff, null)
      max_doublings      = try(retry_config.value.max_doublings, null)
    }
  }
  dynamic "rate_limits" {
    for_each = var.rate_limits != {} ? [var.rate_limits] : toset([])
    content {
      max_concurrent_dispatches = try(rate_limits.value.max_concurrent_dispatches, null)
      max_dispatches_per_second = try(rate_limits.value.max_dispatches_per_second, null)
      max_burst_size            = try(rate_limits.value.max_burst_size, null)
    }
  }
  dynamic "app_engine_routing_override" {
    for_each = var.app_engine_routing_override != {} ? [var.app_engine_routing_override] : []
    content {
      service = try(var.app_engine_routing_override.service, null)
      version = try(var.app_engine_routing_override.version, null)
      host    = try(var.app_engine_routing_override.host, null)
    }
  }
}

Debug Output

Panic Output

No panic output

Expected Behavior

Terraform should not try to update in place in case dynamic "app_engine_routing_override" is empty.

Actual Behavior

Creation of "google_cloud_tasks_queue" resource without any "app_engine_routing_override" was successful

Here is content invoking module:

module "abc" {
  source = "../modules/cloud_tasks"
  location = "europe-west1"
  name = "some-name"
  project_id = "artusiep-project"
}
❯ tf apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.abc.google_cloud_tasks_queue.this will be created
  + resource "google_cloud_tasks_queue" "this" {
      + id       = (known after apply)
      + location = "europe-west1"
      + name     = "some-name"
      + project  = "artusiep-project"

      + app_engine_routing_override {
          + host = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions in workspace "default"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.abc.google_cloud_tasks_queue.this: Creating...
module.abc.google_cloud_tasks_queue.this: Creation complete after 1s [id=projects/artusiep-project/locations/europe-west1/queues/some-name]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

But terraform keep trying to update the resource seeing diff in "app_engine_routing_override" configuration

❯ tf plan
module.abc.google_cloud_tasks_queue.this: Refreshing state... [id=projects/artusiep-project/locations/europe-west1/queues/some-name]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.abc.google_cloud_tasks_queue.this will be updated in-place
  ~ resource "google_cloud_tasks_queue" "this" {
        id       = "projects/artusiep-project/locations/europe-west1/queues/some-name"
        name     = "some-name"
        # (2 unchanged attributes hidden)

      + app_engine_routing_override {}

        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Steps to Reproduce

  1. Create module based on Terraform Configuration Files
  2. Add invocation of the module
module "abc" {
  source = "../modules/cloud_tasks"
  location = "europe-west1"
  name = "some-name"
  project_id = "artusiep-project"
}
  1. terraform apply
  2. terraform plan

Important Factoids

None

References

None

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 5
  • Comments: 18

Most upvoted comments

@artusiep have you tried removing the type in the variable to see if that makes difference?

variable "app_engine_routing_override" {
  /*
  type       = object({
    service = optional(string)
    version = optional(string)
    instance = optional(string)
  })*/
  default = {}
  description = "App Engine Routing for the task. If set, app_engine_routing_override is used for all tasks in the queue, no matter what the setting is for the task."
}

Keep in mind, the provider does not have much control over how the api behaves. What we could do is to use all terraform core provides to make it work for us. When you say the issue can’t be reproed with the resource (without dynamic code), that means it is unlikely a problem in the provider. If the api’s behavior does not make sense, we can file an issue against it. Does this make sense?