What is the Correct Terraform Provider Configuration for Google Cloud Platform Resources with Beta Arguments?

Viewed 1878

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?

1 Answers

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.

Related