Skip to content

Instantly share code, notes, and snippets.

@sanikamal
Last active September 28, 2022 06:32
Show Gist options
  • Save sanikamal/f5af5fc7ff369c2516b4dec200e8297b to your computer and use it in GitHub Desktop.
Save sanikamal/f5af5fc7ff369c2516b4dec200e8297b to your computer and use it in GitHub Desktop.
Automating Infrastructure on Google Cloud with Terraform: Challenge Lab

Overview

  • Task - 1 : Create the configuration files
  • Task - 2 : Import infrastructure
  • Task - 3 : Configure a remote backend
  • Task - 4 : Modify and update infrastructure
  • Task - 5 : Taint and destroy resources
  • Task - 6 : Use a module from the Registry
  • Task - 7 : Configure a firewall

Task - 1 : Create the configuration files

Make the empty files and directories in Cloud Shell or the Cloud Shell Editor.

touch main.tf
touch variables.tf
mkdir modules
cd modules
mkdir instances
cd instances
touch instances.tf
touch outputs.tf
touch variables.tf
cd ..
mkdir storage
cd storage
touch storage.tf
touch outputs.tf
touch variables.tf
cd

Add the following to the each variables.tf file, and fill in the GCP Project ID:

variable "region" {
 default = "us-central1"
}

variable "zone" {
 default = "us-central1-a"
}

variable "project_id" {
 default = "<FILL IN PROJECT ID>"
}

Add the following to the main.tf file :

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "3.55.0"
    }
  }
}

provider "google" {
  project     = var.project_id
  region      = var.region

  zone        = var.zone
}

module "instances" {

  source     = "./modules/instances"

}

Run terraform init in Cloud Shell in the root directory to initialize terraform.

Task - 2 : Import infrastructure

Next, navigate to modules/instances/instances.tf. Copy the following configuration into the file:

resource "google_compute_instance" "tf-instance-1" {
  name         = "tf-instance-1"
  machine_type = "n1-standard-1"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
  metadata_startup_script = <<-EOT
        #!/bin/bash
    EOT
allow_stopping_for_update = true
}

resource "google_compute_instance" "tf-instance-2" {
  name         = "tf-instance-2"
  machine_type = "n1-standard-1"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
  metadata_startup_script = <<-EOT
        #!/bin/bash
    EOT
allow_stopping_for_update = true
}

terraform import module.instances.google_compute_instance.tf-instance-1 <Instance ID - 1>

terraform import module.instances.google_compute_instance.tf-instance-2 <Instance ID - 2>

terraform plan
terraform apply

Task - 3 : Configure a remote backend

Add the following code to the modules/storage/storage.tf file:

resource "google_storage_bucket" "storage-bucket" {
  name          = var.project_id
  location      = "US"
  force_destroy = true
  uniform_bucket_level_access = true
}

Next, add the following to the main.tf file:

module "storage" {
  source     = "./modules/storage"
}

terraform init
terraform apply

Next, update the main.tf file so that the terraform block looks like the following. Fill in your GCP Project ID for the bucket argument definition.

terraform {
  backend "gcs" {
    bucket  = "<FILL IN PROJECT ID>"
 prefix  = "terraform/state"
  }
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "3.55.0"
    }
  }
}

terraform init

Task - 4 : Modify and update infrastructure

Navigate to modules/instances/instance.tf. Replace the entire contents of the file with the following:

resource "google_compute_instance" "tf-instance-1" {
  name         = "tf-instance-1"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
}

resource "google_compute_instance" "tf-instance-2" {
  name         = "tf-instance-2"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
}

resource "google_compute_instance" "tf-instance-3" {
  name         = "tf-instance-3"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
}

terraform init
terraform apply

Task - 5 : Taint and destroy resources

terraform taint module.instances.google_compute_instance.tf-instance-3

terraform init
terraform apply

Remove the tf-instance-3 resource from the instances.tf file. Delete the following code chunk from the file.

resource "google_compute_instance" "tf-instance-3" {
  name         = "tf-instance-3"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "default"
  }
}

terraform apply

Task - 6 : Use a module from the Registry

Copy and paste the following into the main.tf file:

module "vpc" {
    source  = "terraform-google-modules/network/google"
    version = "~> 3.2.2"

    project_id   = var.project_id
    network_name = "terraform-vpc"
    routing_mode = "GLOBAL"

    subnets = [
        {
            subnet_name           = "subnet-01"
            subnet_ip             = "10.10.10.0/24"
            subnet_region         = "us-central1"
        },
        {
            subnet_name           = "subnet-02"
            subnet_ip             = "10.10.20.0/24"
            subnet_region         = "us-central1"
            subnet_private_access = "true"
            subnet_flow_logs      = "true"
            description           = "This subnet has a description"
        }
    ]
}

terraform init
terraform apply

Navigate to modules/instances/instances.tf. Replace the entire contents of the file with the following:

resource "google_compute_instance" "tf-instance-1" {
  name         = "tf-instance-1"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "terraform-vpc"
    subnetwork = "subnet-01"
  }
}

resource "google_compute_instance" "tf-instance-2" {
  name         = "tf-instance-2"
  machine_type = "n1-standard-2"
  zone         = var.zone
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }

  network_interface {
 network = "terraform-vpc"
    subnetwork = "subnet-02"
  }
}

terraform init
terraform apply

Task - 7 : Configure a firewall

Add the following resource to the main.tf file and fill in the GCP Project ID:

resource "google_compute_firewall" "tf-firewall" {
  name    = "tf-firewall"
 network = "projects/<PROJECT_ID>/global/networks/<terraform-vpc>"

  allow {
    protocol = "tcp"
    ports    = ["80"]
  }

  source_tags = ["web"]
  source_ranges = ["0.0.0.0/0"]
}

terraform init
terraform apply

Congratulations, you're all done with the lab 😄

@devashishsingh
Copy link

I got this on Task 2
module.instances is not defined in the configuration

@sanikamal
Copy link
Author

Recheck may be lab instructions are updated by gcp

@sanikamal
Copy link
Author

@rishabhlakh
Copy link

Task 2 has issues.
getting │ Error: Cannot import non-existent remote object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment