Getting Started with the Google Provider
Before you begin
- Create a project in the Google Cloud Console and set up billing on that project. Any examples in this guide will be part of the GCP "always free" tier.
- Install Terraform and read the Terraform getting started guide that follows. This guide will assume basic proficiency with Terraform - it is an introduction to the Google provider.
Configuring the Provider
First, authenticate with GCP. The easiest way to do this is to run gcloudAuthApplicationDefaultLogin
, if you already have gcloud installed. If you don't already have it, you can install it from here.
Next, create a Terraform config file named "mainTf"
. Inside, you'll want to include the following configuration:
/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as google from "./.gen/providers/google";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: google.
For a more precise conversion please use the --provider flag in convert.*/
new google.provider.GoogleProvider(this, "google", {
project: "{{YOUR GCP PROJECT}}",
region: "us-central1",
zone: "us-central1-c",
});
- The
project
field should be your personal project id. Theproject
indicates the default GCP project all of your resources will be created in. Most Terraform resources will have aproject
field. - The
region
andzone
are locations for your resources to be created in. - The
region
will be used to choose the default location for regional resources. Regional resources are spread across several zones. - The
zone
will be used to choose the default location for zonal resources. Zonal resources exist in a single zone. All zones are a part of a region.
Not all resources require a location. Some GCP resources are global and are automatically spread across all of GCP.
-> Want to try out another location? Check out the list of available regions and zones. Instances created in zones outside the US are not necessarily part of the always free tier and could incur charges.
Creating a VM instance
A Google Compute Engine VM instance is named googleComputeInstance
in Terraform. The google
part of the name identifies the provider for Terraform, compute
indicates the GCP product family, and instance
is the resource name.
Google provider resources will generally, although not always, be named after the name used in gcloud
/the REST API. For example, a VM instance is called instance
in the API. Most resource field names will also correspond 1:1 with their gcloud
/REST API names.
If you look at the googleComputeInstanceDocumentation
, you'll see that project
and zone
(VM instances are a zonal resource) are listed as optional. When present in a resource's config block, these values will be used. If omitted, the provider defaults will be used instead.
Add the following to your config file:
/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as google from "./.gen/providers/google";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: google.
For a more precise conversion please use the --provider flag in convert.*/
new google.computeInstance.ComputeInstance(this, "vm_instance", {
boot_disk: [
{
initialize_params: [
{
image: "debian-cloud/debian-11",
},
],
},
],
machine_type: "e2-micro",
name: "terraform-instance",
network_interface: [
{
access_config: [{}],
network: "default",
},
],
});
\~> Note: Don't use terraformApply
quite yet! You still need to add GCP credentials. If you want to try out provisioning your VM instance before continuing, follow the instructions in the "Adding credentials" section below.
Linking GCP resources
Like this VM instance, nearly every GCP resource will have a name
field. They are used as a short way to identify resources, and a resource's display name in the Cloud Console will be the one defined in the name
field.
When linking resources in a Terraform config though, you'll primarily want to use a different field, the selfLink
of a resource. Like name
, nearly every resource has a selfLink
. They look like:
{{API base url}}/projects/{{your project}}/{{location type}}/{{location}}/{{resource type}}/{{name}}
For example, the instance defined earlier in a project named foo
will have the selfLink
:
A resource's selfLink
is a unique reference to that resource. When linking two resources in Terraform, you can use Terraform interpolation to avoid typing out the self link! Let's use a googleComputeNetwork
to demonstrate.
Add this block to your config:
/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as google from "./.gen/providers/google";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: google.
For a more precise conversion please use the --provider flag in convert.*/
new google.computeNetwork.ComputeNetwork(this, "vpc_network", {
auto_create_subnetworks: "true",
name: "terraform-network",
});
This will create VPC network resource with a subnetwork in each region. Next, change the network of the googleComputeInstance
from the "default"
network to the new network.
network_interface {
- # A default network is created for all GCP projects
- network = "default"
+ network = google_compute_network.vpc_network.self_link
access_config {
This means that when we create the VM instance, it will use "terraformNetwork"
instead of the default VPC network for the project. If you run terraformPlan
, you will see that "terraformInstance"
depends on "terraformNetwork"
.
Your configuration is complete. Before you can run terraformApply
though, Terraform needs GCP credentials.
Adding credentials
In order to make requests against the GCP API, you need to authenticate to prove that it's you making the request. The preferred method of provisioning resources with Terraform on your workstation is to use the Google Cloud SDK as we mentioned earlier.
You can also use a Google Cloud Service Account with terraform.
From the service account key page in the Cloud Console choose an existing account, or create a new one. Next, download the JSON key file. Name it something you can remember, and store it somewhere secure on your machine.
Note: Currently the only supported service account credentials are credentials downloaded from Cloud Console or generated by
gcloud
.
You supply the key to Terraform using the environment variable googleApplicationCredentials
, setting the value to the location of the file.
If you choose to use gcloud
-generated credentials, and you encounter quota or billing issues which don't seem to apply to you, you may want to set userProjectOverride
to true
in the provider block - see the provider reference for more information.
-> Remember to add this line to a startup file such as bashProfile
or bashrc
to store your credentials across sessions!
Using Terraform Cloud as the Backend
You need to use a different environment variable name to store your credentials in Terraform Cloud.
- Create an environment variable called
googleCredentials
in your Terraform Cloud workspace. - Remove the newline characters from your JSON key file and then paste the credentials into the environment variable value field.
- Mark the variable as Sensitive and click Save variable.
All runs within the workspace will use the googleCredentials
variable to authenticate with Google Cloud Platform.
\~> Note: When running inside a CLI-driven TFC workspace, local environment variables will only be accessible when executed locally. All credentials environment variables (including default application credentials) need to be set in the Variables tab in order to be accessible by workspaces executed remotely.
Provisioning your resources
By now, your config will look something like:
/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as google from "./.gen/providers/google";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: google.
For a more precise conversion please use the --provider flag in convert.*/
new google.provider.GoogleProvider(this, "google", {
project: "{{YOUR GCP PROJECT}}",
region: "us-central1",
zone: "us-central1-c",
});
const googleComputeNetworkVpcNetwork = new google.computeNetwork.ComputeNetwork(
this,
"vpc_network",
{
auto_create_subnetworks: "true",
name: "terraform-network",
}
);
new google.computeInstance.ComputeInstance(this, "vm_instance", {
boot_disk: [
{
initialize_params: [
{
image: "debian-cloud/debian-11",
},
],
},
],
machine_type: "e2-micro",
name: "terraform-instance",
network_interface: [
{
access_config: [{}],
network: googleComputeNetworkVpcNetwork.selfLink,
},
],
});
With a Terraform config and with your credentials configured, it's time to provision your resources:
Congratulations! You've gotten started using the Google provider and provisioned a virtual machine on Google Cloud Platform. The key concepts unique to GCP are:
- How a
project
contains resources - and how to use a default
project
in your provider - What a resource being global, regional, or zonal means on GCP
- and how to specify a default
region
andzone
- How GCP uses
name
andselfLink
to identify resources - How to add GCP service account credentials to Terraform
Run terraformDestroy
to tear down your resources.
Afterwards, check out the provider reference for more details on configuring the provider block (including how you can eliminate it entirely!).
You can also check out the GCP Community tutorials such as: