hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.31k stars 1.73k forks source link

google_alloydb_cluster throws error when psc_config or network_config values are passed using dynamic block #18481

Open imrannayer opened 3 months ago

imrannayer commented 3 months ago

Community Note

Terraform Version & Provider Version(s)

Terraform v1.7.5 on darwin_amd64

Affected Resource(s)

google_alloydb_cluster

Terraform Configuration

variable "network_self_link" {
  description = "Network ID where the AlloyDb cluster will be deployed. If network_self_link is set then psc_enabled should be set to false"
  type        = string
  default     = null
}

variable "psc_enabled" {
  type        = bool
  description = "Create an instance that allows connections from Private Service Connect endpoints to the instance. If psc_enabled is set to true, then network_self_link should be set to null"
  default     = true
}

resource "google_alloydb_cluster" "default" {
  cluster_id   = "cluster-us-central1-psc"
  cluster_type = "PRIMARY"
  location     = "us-central1"
  project      = "ci-alloy-db-1-859a"

  dynamic "network_config" {
    for_each = var.network_self_link == null ? [] : ["network_config"]
    content {
      network            = var.network_self_link
      allocated_ip_range = local.allocated_ip_range
    }
  }

  dynamic "psc_config" {
    for_each = var.psc_enabled ? ["psc_enabled"] : []
    content {
      psc_enabled = var.psc_enabled
    }
  }

}

OR

variable "network_self_link" {
  description = "Network ID where the AlloyDb cluster will be deployed. If network_self_link is set then psc_enabled should be set to false"
  type        = string
  default     = "projects/ci-alloy-db-1-859a/global/networks/deleteme-network"
}

variable "psc_enabled" {
  type        = bool
  description = "Create an instance that allows connections from Private Service Connect endpoints to the instance. If psc_enabled is set to true, then network_self_link should be set to null"
  default     = false
}

resource "google_alloydb_cluster" "default" {
  cluster_id   = "cluster-us-central1-psc"
  cluster_type = "PRIMARY"
  location     = "us-central1"
  project      = "ci-alloy-db-1-859a"

  dynamic "network_config" {
    for_each = var.network_self_link == null ? [] : ["network_config"]
    content {
      network            = var.network_self_link
    }
  }

  dynamic "psc_config" {
    for_each = var.psc_enabled ? ["psc_enabled"] : []
    content {
      psc_enabled = var.psc_enabled
    }
  }
}

Debug Output

https://gist.github.com/imrannayer/c2ca657e5ba4a731febf15949f8e7acb

Expected Behavior

It should work fine as the value of psc_config.0.psc_enabled is provided

Actual Behavior

getting following error

│ Error: Invalid combination of arguments
│
│   with google_alloydb_cluster.default,
│   on main.tf line 46, in resource "google_alloydb_cluster" "default":
│   46: resource "google_alloydb_cluster" "default" {
│
│ "network": one of `network,network_config.0.network,psc_config.0.psc_enabled` must be specified

Steps to reproduce

  1. terraform apply

Important Factoids

No response

References

No response

b/349388135

ggtisc commented 3 months ago

Hi @imrannayer!

I noticed that in your code for the variable network_self_link you are assigning a default value of null and this is not supported according to terraform registry and Google Cloud API. This argument requires this specific nomenclature projects/{projectNumber}/global/networks/{network_id}.

You could follow this example to test the resource and the go to implement changes on your variables and dynamic code.

imrannayer commented 3 months ago

@ggtisc for PSC setup network_self_link has to be null otherwise you will get an error. You can only specify value psc_config or network_config. If you provide values as network_config {} then you will get an error on next execution of the code. See this issue

ggtisc commented 3 months ago

Both issues are different, the issue you are sharing looks like a permadiff, but to confirm that we need the full code. And this one is just a mistake in the configuration, besides the invalid value on the network_self_link = null I noticed other bad configurations:

The problem you are facing is related to how you are using the dynamic blocks in Terraform to configure the network (network_config) and Private Service Connect (psc_config) options within the google_alloydb_cluster resource. The specific error indicates that the network value is not being correctly specified within network_config, even though it appears to be set to a default value in the network_self_link variable.

You need to have something like this:

variable "network_self_link" {
  description = "Network ID where the AlloyDb cluster will be deployed. If network_self_link is set then psc_enabled should be set to false"
  type        = string
  default     = "projects/ci-alloy-db-1-859a/global/networks/deleteme-network"
}

variable "psc_enabled" {
  type        = bool
  description = "Create an instance that allows connections from Private Service Connect endpoints to the instance. If psc_enabled is set to true, then network_self_link should be set to null"
  default     = false
}

resource "google_alloydb_cluster" "default" {
  cluster_id   = "cluster-us-central1-psc"
  cluster_type = "PRIMARY"
  location     = "us-central1"
  project      = "ci-alloy-db-1-859a"

  dynamic "network_config" {
    for_each = var.network_self_link != null ? [1] : []
    content {
      network = var.network_self_link
    }
  }

  dynamic "psc_config" {
    for_each = var.psc_enabled ? [1] : []
    content {
      psc_enabled = var.psc_enabled
    }
  }
}

Explanation of the changes:

  1. Dynamic Blocks:
  1. psc_config:
  1. Observations:

With these changes, the bug related to invalid combination of arguments should be resolved, as at least one of the required values ​ ​(network, psc_enabled) is now guaranteed to be properly specified.

I suggest you to try first the basic example configuration without using variables and dynamic blocks and then when you are completely sure it works fine you could implement the dynamic blocks.

imrannayer commented 3 months ago

@ggtisc I dont see any difference in your code and mine. You just changed logic for executing once by putting "1" instead of a string. They both will produce same result. I executed your code and here is the error:

 Error: Invalid combination of arguments
│
│   with google_alloydb_cluster.default,
│   on updated.tf line 13, in resource "google_alloydb_cluster" "default":
│   13: resource "google_alloydb_cluster" "default" {
│
│ "network": one of `network,network_config.0.network,psc_config.0.psc_enabled` must be specified
ggtisc commented 3 months ago

If this is the same issue as the one you shared maybe it could be better to share the simplified code to confirm the permadiff on network_config {}, because the user is just sharing the output but not the terraform code to replicate the issue according to his configuration

imrannayer commented 3 months ago

@ggtisc user is executing example provided with the module. In order to resolve that issue I need to make both network_config and psc_config blocks dynamic so we dont face the issue. But making both of them dynamic is throwing error. Thats why I provided simple example in this issue to show whats happening.

ggtisc commented 3 months ago

After some tries it isn't possible to replicate this issue, the result was the same (successfully without errors) even with the shared module example. This looks more like troubleshooting than a bug. If you have the code that triggers the result of this issue please share it, with all the steps:

Terraform will perform the following actions:

  # module.alloydb_main["REDACTED"].google_alloydb_cluster.default will be updated in-place
  ~ resource "google_alloydb_cluster" "default" {
        id                     = "projects/REDACTED/locations/europe-west1/clusters/REDACTED"
        name                   = "projects/REDACTED/locations/europe-west1/clusters/REDACTED"
        # (18 unchanged attributes hidden)

      + network_config {}

        # (3 unchanged blocks hidden)
    }
imrannayer commented 3 months ago

For the issue mentioned in the module if you execute terraform apply twice you will get the error. You will get error in cross region replica cluster.

ggtisc commented 3 months ago

Confirmed issue!

To clarify the issue since several configurations and different steps to follow were shared. This is the correct order:

  1. The code from this repository must be executed whit a terraform apply
  2. After the 1st terraform apply finishes a 2nd terraform apply must be executed and this is going to trigger a possible permadiff