"title"=>"Build Infrastructure on Google Cloud with Terraform — Google Challenge Lab Walkthrough",
"summary"=>nil,
"content"=>"
Build Infrastructure on Google Cloud with Terraform — Google Challenge Lab Walkthrough
This is a walkthrough of the challenge lab from the course Build Infrastructure with Terraform on Google Cloud.
This lab tests your ability to:
- Import existing infrastructure into your Terraform configuration.
- Build and reference your own Terraform modules.
- Add a remote backend to your configuration.
- Use and implement a module from the Terraform Registry.
- Re-provision, destroy, and update infrastructure.
- Test connectivity between the resources you’ve created.
Intro to Challenge Labs
Google provides an online learning platform called Google Cloud Skills Boost, formerly known as QwikLabs. On this platform, you can follow training courses aligned to learning paths, to particular products, or for particular solutions.
One type of learning experience on this platform is called a quest. This is where you complete a number of guided hands-on labs, and then finally complete a Challenge Lab. The challenge lab differs from the other labs in that goals are specified, but very little guidance on how to achieve the goals is given.
I occasionally create walkthroughs of these challenge labs. The goal is not to help you cheat your way through the challenge labs! But rather:
- To show you what I believe to be an ideal route through the lab.
- To help you with particular gotchas or blockers that are preventing you from completing the lab on your own.
If you’re looking for help with challenge lab, then you’ve come to the right place. But I strongly urge you to work your way through the quest first, and to try the lab on your own, before reading further!
With all these labs, there are always many ways to go about solving the problem. I generally like to solve them using the Cloud Shell, since I can then document a more repeatable and programmatic approach. But of course, you can use the Cloud Console too.
Overview of this Lab
In this lab we’re expected to use Terraform to create, deploy and manage infrastructure on Google Cloud. We also need to import some mismanaged instances into our configuration and fix them.
My Solution
Let’s start by defining some variables we can use throughout this challenge. The actual variables will be provided to you when you start the lab.
gcloud auth list
region=<ENTER REGION>
zone=<ENTER ZONE>
prj=<ENTER PRJ ID>
Task 1 — Create the Configuration Files
We’re told to create this folder structure:
main.tf
variables.tf
modules/
└── instances
| ├── instances.tf
| ├── outputs.tf
| └── variables.tf
└── storage
├── storage.tf
├── outputs.tf
└── variables.tf
We can do it like this:
# Create main.tf and variables.tf in the root directory
touch main.tf variables.tf
# Create main directory and its files
mkdir -p modules/instances
mkdir modules/storage
# Create the required files in the 'instances' module directory
touch modules/instances/instances.tf
touch modules/instances/outputs.tf
touch modules/instances/variables.tf
# Create the required files in the 'storage' module directory
touch modules/storage/storage.tf
touch modules/storage/outputs.tf
touch modules/storage/variables.tf
Now we update the variables.tf files to contain these variables:
variable "region" {
description = "The Google Cloud region"
type = string
default = "Lab-supplied region"
}
variable "zone" {
description = "The Google Cloud zone"
type = string
default = "Lab-supplied zone"
}
variable "project_id" {
description = "The ID of the project in which to provision resources."
type = string
default = "Your project ID"
}
Update the root module main.tf to include the Google Cloud Provider, which you can always look up in the Terraform Registry. We’re asked to include all three of our variables in our provider block.
terraform {
required_providers {
google = {
source = "hashicorp/google"
}
}
}
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
Now we need to initialise Terraform. So run this command:
terraform init
Task 2 — Import Infrastructure
Here, the goal is to bring infrastructure under Terraform control, that has thus far been provisioned outside of Terraform.
We’re going to use the Terraform import workflow:
These are the import steps:
- Identify the existing infrastructure to be imported.
- Import the infrastructure into your Terraform state.
- Write a Terraform configuration that matches that infrastructure.
- Review the Terraform plan to ensure that the configuration matches the expected state and infrastructure.
- Apply the configuration to update your Terraform state.
Identify the existing infrastructure to be imported
Two GCE instances have already been created. Examine one of the existing instances, tf-instance-1 in the Cloud Console. We want to retrieve:
- Network
- Machine type
- Disk
Next we need to include two calls to our instances module in our main.tf. They will contain empty definitions, so that we can import.
module "tf_instance_1" {
source = "./modules/instances"
instance_name = "tf-instance-1"
zone = var.zone
region = var.region
}
module "tf_instance_2" {
source = "./modules/instances"
instance_name = "tf-instance-2"
zone = var.zone
region = var.region
}
Remember that each module definition must have a unique label.
Now initialise:
terraform init
Now we write the module configurations in instances.tf. We’re told the arguments that need to be included in our minimal configuration:
resource "google_compute_instance" "instance" {
name = var.instance_name
machine_type = "hard code from existing instance"
zone = var.zone
boot_disk {
initialize_params {
# image = "debian-cloud/debian-11"
image = "hard code from existing instance"
}
}
network_interface {
# network = "default"
network = "hard code from existing instance"
access_config {
// Ephemeral public IP
}
}
metadata_startup_script = <<-EOT
#!/bin/bash
EOT
allow_stopping_for_update = true
}
Update variables.tf in the instance module, so we can pass in the instance_name:
variable "instance_name" {
description = "The name of the instance."
type = string
}
Import the Existing Infrastructure into Terraform State
terraform import module.tf_instance_1.google_compute_instance.instance \\
projects/$prj/zones/$zone/instances/tf-instance-1
terraform import module.tf_instance_2.google_compute_instance.instance \\
projects/$prj/zones/$zone/instances/tf-instance-2
# verify the import
terraform show
The import should look like this:
Plan and Apply
Now we update the instances in-place by running the apply:
terraform plan
terraform apply
Task 3 — Configure a Remote Backend
This is pretty easy. These are standard steps that you would run whenever we want to store Terraform state in a remote GCS backend:
- Provision a GCS bucket with Terraform.
- Add a backend block that points to the new GCS bucket.
- Reinitialise Terraform and migrate the state from the local state file to the remote backend.
Provision the GCS Bucket
Add this resource definition to main.tf:
resource "google_storage_bucket" "test-bucket-for-state" {
name = "Bucket Name You Are Given"
location = "US"
uniform_bucket_level_access = true
force_destroy = true
}
And apply:
terraform apply
Add the GCS Backend
Modify main.tf and include the backend in the terraform block:
terraform {
backend "gcs" {
bucket = var.project_id
prefix = "terraform/state"
}
}
Migrate the State
This is where we migrate the Terraform state from the local state file into the GCS backend:
terraform init -migrate-state
It will ask you to confirm you want to migrate the state:
Task 4 — Modify and Update the Infrastructure
We need to update variables.tf to include a machine_type:
variable "machine_type" {
description = "The machine type of an instance"
type = string
default = "e2-standard-2"
}
Then we need to modify instance.tf so that it can accept a machine_type parameter:
resource "google_compute_instance" "instance" {
name = var.instance_name
machine_type = var.machine_type
zone = var.zone
...
Lastly, we need to modify main.tf such that we add the specified third instance to our main.tf, by calling the module for a third time. We don’t need to pass in the machine_type, as we’ve already set it to have a default.
Now initialise (because we’ve added another module instance) and apply.
terraform init
terraform apply
Task 5 — Destroy Resources
Now we remove the instance we previously added. Remove the call to this module from main.tf, then reapply:
terraform init
terraform apply
Task 6 — Use a Module from the Registry
We’re going to use the Google Network Module.
module "network" {
source = "terraform-google-modules/network/google"
version = "6.0.0"
project_id = var.project_id
network_name = "Use Supplied VPC Name"
routing_mode = "GLOBAL"
subnets = [
{
subnet_name = "subnet-01"
subnet_ip = "10.10.10.0/24"
subnet_region = var.region
},
{
subnet_name = "subnet-02"
subnet_ip = "10.10.20.0/24"
subnet_region = var.region
}
]
}
Initialise and apply:
terraform init
terraform apply
Update instances module to take a network parameter and a subnet parameter.
In variables.tf:
variable "network" {
description = "The network"
type = string
}
variable "subnet" {
description = "The subnet"
type = string
}
In instance.tf:
network_interface {
network = var.network
subnetwork = var.subnet
access_config {
// Ephemeral public IP
}
}
Then update main.tf to create the instances like this:
module "tf_instance_1" {
source = "./modules/instances"
instance_name = "tf-instance-1"
zone = var.zone
region = var.region
network = module.network.network_name
subnet = "subnet-01"
}
module "tf_instance_2" {
source = "./modules/instances"
instance_name = "tf-instance-2"
zone = var.zone
region = var.region
network = module.network.network_name
subnet = "subnet-02"
}
terraform init
terraform apply
Task 7 — Add a Firewall
Update main.tf:
resource "google_compute_firewall" "default" {
name = "tf-firewall"
network = module.network.network_name
direction = "INGRESS"
source_ranges = ["0.0.0.0/0"]
allow {
protocol = "tcp"
ports = ["80"]
}
}
And one last apply…
terraform apply
And we’re done!
Build Infrastructure on Google Cloud with Terraform — Google Challenge Lab Walkthrough was originally published in Google Cloud - Community on Medium, where people are continuing the conversation by highlighting and responding to this story.
","author"=>"Dazbo (Darren Lester)",
"link"=>"https://medium.com/google-cloud/build-infrastructure-on-google-cloud-with-terraform-google-challenge-lab-walkthrough-30a592373d3e?source=rss----e52cf94d98af---4",
"published_date"=>Fri, 05 Apr 2024 04:49:54.000000000 UTC +00:00,
"image_url"=>nil,
"feed_url"=>"https://medium.com/google-cloud/build-infrastructure-on-google-cloud-with-terraform-google-challenge-lab-walkthrough-30a592373d3e?source=rss----e52cf94d98af---4",
"language"=>nil,
"active"=>true,
"ricc_source"=>"feedjira::v1",
"created_at"=>Fri, 05 Apr 2024 07:23:01.520827000 UTC +00:00,
"updated_at"=>Mon, 21 Oct 2024 18:52:36.679100000 UTC +00:00,
"newspaper"=>"Google Cloud - Medium",
"macro_region"=>"Blogs"}