2

Terraforming any Google Cloud Platform (GCP) resource defined by any beta arguments requires the google-beta provider. Should the google-beta provider be used instead of or in tandem with the google provider?

In other words, say a certain Google Kubernetes Engine (GKE) cluster $GKE_CLUSTER_NAME exists within a GCP project $GCP_PROJECT_NAME:

gcloud container clusters list \
--format="value(name)" \
--project=$GCP_PROJECT_NAME

#=>

. . .
$GKE_CLUSTER_NAME
. . .

with Config Connector enabled:

gcloud container clusters describe $GKE_CLUSTER_NAME \
--format=“value(addonsConfig.configConnectorConfig.enabled)” \
--zone=$GKE_CLUSTER_ZONE

#=>

True

Terraforming $GKE_CLUSTER_NAME requires a google_container_cluster resource definition within container_cluster.tf that includes both the config_connector_config argument (within the addons_config block; more here) and the provider argument (missing from the official reference documentation):

resource "google_container_cluster" "test" {
  addons_config {
    config_connector_config {
      enabled = true
    }
    . . .
  }
  . . .
  provider        = google-beta
  . . .
}

but does not require a google-beta provider definition in providers.tf:

provider "google" {
  project = ". . ."
}

terraform {
  required_providers {
    google = {
      version = "~> 3.83.0"
    }
  }
}

This and the lack of a provider argument from other resource definitions, such as a google_container_node_pool found in container_node_pool.tf, results in the following output from the providers command:

terraform providers

Providers required by configuration:
.
├── provider[registry.terraform.io/hashicorp/google] ~> 3.83.0
└── provider[registry.terraform.io/hashicorp/google-beta]

Providers required by state:

    provider[registry.terraform.io/hashicorp/google]

    provider[registry.terraform.io/hashicorp/google-beta]

after an apply command has refreshed the terraform.tfstate state file.

Is the more correct and less error-prone method of Terraforming GCP resources with beta arguments? Or, should I run a replace-provider subcommand instead:

terraform state replace-provider \
-auto-approve \
"hashicorp/google" \
"hashicorp/google-beta"

#=>

Terraform will perform the following actions:

  ~ Updating provider:
    - registry.terraform.io/hashicorp/google
    + registry.terraform.io/hashicorp/google-beta

Changing 2 resources:

  google_container_node_pool.$GKE_NODE_POOL_NAME

Successfully replaced provider for 1 resources.

and modify providers.tf:

provider "google-beta" {
  project = ". . ."
}

terraform {
  required_providers {
    google-beta = {
      version = "~> 3.83.0"
    }
  }
}

so that the output of the providers command is:

terraform providers

#=>

Providers required by configuration:
.
└── provider[registry.terraform.io/hashicorp/google-beta] ~> 3.83.0

Providers required by state:

    provider[registry.terraform.io/hashicorp/google-beta]

after an apply command refreshes the state in terraform.state?

Mike
  • 1,080
  • 1
  • 9
  • 25

1 Answers1

3

You should use both google and google-beta providers.

It is safe to use both the google and the google-beta providers within the same providers.tf. Terraform sends requests for any resource requiring the google-beta provider to the Beta endpoint: https://. . .googleapis.com/v1beta1/. . .; I.e., using the google-beta provider is similar to using the beta gcloud group.

You should:

  • include both the google and google-beta provider in providers.tf:

    provider "google" {
      project = ". . ."
    }
    
    provider "google-beta" {
      project = ". . ."
    }
    
    terraform {
      required_providers {
        google = {
          version = "~> 3.83.0"
        }
        google-beta = {
          version = "~> 3.83.0"
        }
      }
    }
    
  • use the provider argument for every GCP resource: google-beta for any resource that has at least one enabled Beta feature:

    resource "google_container_cluster" "beta_cluster" {
       . . .
       provider        = google-beta
       . . .
    }
    

    and google for every other resource:

    resource "google_container_node_pool" "general_availability_node_pool" {
    . . .
      provider       = google
    . . .
    }
    

After making both of the suggested changes above and then running a refresh, the output of the providers command should now resemble this:

terraform providers

#=>

Providers required by configuration:
.
├── provider[registry.terraform.io/hashicorp/google] ~> 3.83.0
└── provider[registry.terraform.io/hashicorp/google-beta] ~> 3.83.0

Providers required by state:

    provider[registry.terraform.io/hashicorp/google]

    provider[registry.terraform.io/hashicorp/google-beta]

You should read through the official doc. for provider versions here.

Mike
  • 1,080
  • 1
  • 9
  • 25