Terraform with Google Cloud

Terraform with Google Cloud

Terraform with Google Cloud

Google Cloud Overview: 2 Hrs

Introduction to Infrastructure as a code 1hr

  • Overview of infrastructure as code (Iac)
  • Infrastructure provisioning tools - Terraform and its benefits

Getting started & Setting Up Labs 1hr

  • Terraform installation
  • Gitbash installation (ide)
  • Vscode installation and setup
  • Install Terraform plugins in Vscode
  • Setting up google cloud account

READ, GENERATE & MODIFY CONFIGURATION 2 hrs

  • Hashicorp configuration language (Hcl)
  • Terraform configure files
  • Terraform state file
  • Start to build code

Know Terraform Providers 2 hrs

  • Local
  • Google Cloud
  • Random
  • AWS
  • Azurerm

Terraform Providers and Datasources 2hrs

  • Arguments and Attributes

Google Cloud Overview

  • Create Google Cloud Free Account
  • Create Project
  • Assign access to the newly created project.
  • Download and Install Vscode Click Here
  • Download and Install terraform Click Here
  • Download and Install Gitbash
  • Create Account on Gitlab
  • Walk through Google Cloud IAM
  • Create VM on GCP
  • Create a Firewall rule
  • Create a service Account and assign permission.
  • Configure Google Cloud cli

Steps to Create a virtual Machine

  • provider Code
terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "4.20.0"
    }
  }
}

provider "google" {
  # Configuration options
  project = "quiet-fusion-348804"
  region      = "us-central1"
  zone        = "us-central1-c"
  credentials = file("admin.json")
}
  • Vm code
resource "google_compute_instance" "default" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  tags = ["foo", "bar"]

  boot_disk {
    initialize_params {
      image = "debian-11-bullseye-v20220406"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral public IP
    }
  }

  metadata = {
    foo = "bar"
  }

 

 
}
```t
-  Code for Metadata (ssh keys)

```t
resource "google_compute_project_metadata" "my_ssh_key" {
  metadata = {
    ssh-keys = <<EOF
sssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqU07gbxzO3oeNIX2gq6hmOXPk79HV+YCshoHHlloOGwy1EgRlVtPHVLQDaPpvx1xNn4UFeaKvqpcOZctWQsugq1Zo51V4yhMCEbVGfcyKhgsIuRMBkzimAeeZV77mzaLzNQxeNHOzFBprSuaw63ODtqW+FYOq+RzqfPvohr2UdTT07Ki7IQYhbLJ9zuVTfQIn/ELE59z41vrCBeyZH9Om2Orgz4CKilamY5WDBuYFJqw8QhMKVwRiF+vsJS7iLeo1pPufbRBZqvtA5eU0rG2hjTcJBYsXuKswtelwzgTXmUI/c0cRcjp+4/UYVCh4StUrlRHphDct+qyloSzT+E1zXTIKWfml+0nAnOQIP+V98fzdHHzuYPebVS9mcDbuNz/TZaxtV0RWFt1cTEWBwNZGTpB2tUqUAqJgW5yc9kHKFMm5BDpAiMPQDJUIjLUc1DbHLPOy+Gd7annuFdcGnAVJvSud8yJYNg/ABc3PmB+WyWjnGLk6eUjk6PS708sjYtM= nippy

      
    EOF
  }
}
  • How to create ssh keys
ssh-keygen -f <keyname>
  • Update network tag for a vm

  • update a vm size for a vm

  • Update deletion protection

  • Update label

  • Update metadata script

  • update service account

  • Create Disk

  • Attach Disk

  • Increase the size of Disk

  • VM code with metadata script

  • Know about multiple provider

  • Visit to terrform registry to check all providers

  • Terraform Lock file

  • check the terraform next version available

  • know the ways to delete resources

  • Create a branch on project and push the code for session wise

# Create a single Compute Engine instance
resource "google_compute_instance" "default" {
  name         = "flask-vm"
  machine_type = "f1-micro"
  zone         = "us-west1-a"
  tags         = ["ssh"]

  metadata = {
    enable-oslogin = "TRUE"
  }
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  # Install Flask
  metadata_startup_script = "sudo apt-get update; sudo apt-get install -yq build-essential python-pip rsync; pip install flask"

  network_interface {
    network = "default"

    access_config {
      # Include this section to give the VM an external IP address
    }
  }
}
  • Create a Firewall rule
resource "google_compute_firewall" "ssh" {
  name = "allow-ssh"
  allow {
    ports    = ["22"]
    protocol = "tcp"
  }
  direction     = "INGRESS"
  network       = "default"
  priority      = 1000
  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["ssh"]
}

Documents from Gooogle Cloud

Export your Google Cloud resources into Terraform format

  • List Project id
gcloud config list project

registry.terraform.io/hashicorp/google.

  • Create a network
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}
  • Use the newly create network with vm
resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}
  • Create a static ip
resource "google_compute_address" "vm_static_ip" {
  name = "terraform-static-ip"
}
  • Update vm with static ip
  network_interface {
    network = google_compute_network.vpc_network.self_link
    access_config {
      nat_ip = google_compute_address.vm_static_ip.address
    }
  }
  • Dependency with bucket
# New resource for the storage bucket our application will use.
resource "google_storage_bucket" "example_bucket" {
  name     = "<UNIQUE-BUCKET-NAME>"
  location = "US"
  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }
}
# Create a new instance that uses the bucket
resource "google_compute_instance" "another_instance" {
  # Tells Terraform that this VM instance must be created only after the
  # storage bucket has been created.
  depends_on = [google_storage_bucket.example_bucket]
  name         = "terraform-instance-2"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.self_link
    access_config {
    }
  }
}
Datasources
data "google_project" "project" {
}

output "project" {
    value = data.google_project.project.name
}

output "hhh" {
    value = "hello world"
  
}


data "google_compute_network" "my-network" {
  name = "default-us-east1"
}

output "network" {
    value = data.google_compute_network.my-network.name
  
}

data "google_compute_regions" "available" {
}

output "region" {
  value = data.google_compute_regions.available.names
}
  • Google Cloud Compute Zone
data "google_compute_zones" "available" {
}

resource "google_compute_instance_group_manager" "foo" {
  count = length(data.google_compute_zones.available.names)

  name               = "terraform-test-${count.index}"
  instance_template  = google_compute_instance_template.foobar.self_link
  base_instance_name = "foobar-${count.index}"
  zone               = data.google_compute_zones.available.names[count.index]
  target_size        = 1
}
  • Create vm as per the availablity zone
resource "google_compute_instance" "default" {
  name         = "foobar${count.index}"
  machine_type = "e2-medium"
  zone         = data.google_compute_zones.available.names[count.index]
  tags  =        ["jenkins"]
  count = length(data.google_compute_zones.available.names)

  

  boot_disk {
    initialize_params {
      image = "debian-11-bullseye-v20220406"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral public IP
    }
  }

  metadata = {
    foo = "bar"
  }

 

 
}
  • For each
resource "google_compute_instance" "default" {
  for_each = toset(var.each)
  name         = "foobar${each.key}"
  machine_type = "e2-medium"
  zone         = "${each.value}"
  tags  =        ["jenkins"]
  

  

  boot_disk {
    initialize_params {
      image = "debian-11-bullseye-v20220406"
    }
  }

  network_interface {
   subnetwork = google_compute_subnetwork.default.self_link

    access_config {
      // Ephemeral public IP
    }
  }

  metadata = {
    foo = "bar"
  }

 

 
}



### Learn for for each
variable "each" {
  default = ["us-central1-a","us-central1-b","us-central1-c"]
}


  
  • List the active account name
gcloud auth list
  • List the project ID
gcloud config list project
  • Create a new instance using Gcloud shell
gcloud compute instances create [INSTANCE_NAME] --machine-type n1-standard-2 --zone [ZONE_NAME]
  • SSH in to the machine
gcloud compute ssh [INSTANCE_NAME] --zone [YOUR_ZONE]
  • RDP a windows server
gcloud compute instances get-serial-port-output [INSTANCE_NAME] --zone [ZONE_NAME]
  • Command to check whether the server is ready for an RDP connection
gcloud compute instances get-serial-port-output
  • Create a Storage bucket
gsutil mb gs://[BUCKET_NAME]
  • Copy a file in to the bucket
gsutil cp [FILE_NAME] gs://[BUCKET_NAME]
  • Setting up default compute zone
gcloud config set compute/zone [ZONE_NAME]
  • Set the default region:
gcloud config set compute/region [REGION_NAME]
  • List the compute engine instances created:
gcloud compute instances list
  • Create Kubernetes Cluster
gcloud container clusters create [CLUSTER-NAME]
  • Get authentication credentials for the cluster
gcloud container clusters get-credentials [CLUSTER-NAME]
  • Stop a vm
gcloud compute instances stop [INSTANCE-NAME]

Terraform Version Constraints

Day2:

  • Variables
  • Meta Arguments
  • Google Cloud Networking
  • Conditions
  • Local Values
  • Terraform taint and untaint
  • Terraform refresh commands

Terraform Variables 2 hrs

  • Variable Block
  • Approaches for Variable Assignment
  • Datatypes for variables
  • Fetching data from Map and List
  • Count and Count Index
  • Conditional Expressions
  • Local Values
  • Terraform Functions

TERRAFORM PROVISIONER 2 hrs

  • Understanding Provisioners in Terraform

  • Types of Provisioners

  • Implementing remote-exec provisioners

  • Implementing local-exec provisioners

  • Creation-Time & Destroy-Time Provisioners

  • Failure Behavior for Provisioners

Terraform Modules & Workspaces 2 hrs

  • Understand DRY principle
  • Creating modules for Google Cloud vm
  • Creating modules for Google Cloud VPC
  • Creating modules for google storage
  • Terraform Registry
  • Terraform Workspace
  • Implementing Terraform workspace

REMOTE STATE MANAGEMENT 2 hrs

  • Integrating with GIT for team management
  • Security Challenges in Commiting TFState to GIT
  • Module Sources in Terraform
  • Terraform .gitignore and .terraform
  • Remote State Management with Terraform
  • Implementing google storage Backend
  • Challenges with State File locking
  • Terraform State Management
  • Importing Existing Resources with Terraform Import
  • Document - Remote State Management
  • Terraform state pull
  • Terraform refresh on state

https://blog.boltops.com/2020/10/03/terraform-hcl-conditional-logic/

  • Understand conditions
output "a1" {
  value = true ? "is true" : "is false"
}
output "a2" {
  value = false ? "is true" : "is false"
}
output "a3" {
  value = 1 == 2 ? "is true" : "is false"
}
  • More Examples
output "b1" {
  value = contains(["a","b","c"], "d") ? "is true" : "is false"
}
output "b2" {
  value = keys({a: 1, b: 2, c: 3}) == ["a","b","c"] ? "is true" : "is false"
}
output "b3" {
  value = contains(keys({a: 1, b: 2, c: 3}), "b") ? "is true" : "is false"
}
  • Dynamic Blocks examples
resource "aws_security_group" "simple" {
  name        = "demo-simple"
  description = "demo-simple"

  ingress {
    description = "description 0"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description = "description 1"
    from_port   = 81
    to_port     = 81
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
locals {
  ports = [80, 81]
}
resource "aws_security_group" "dynamic" {
  name        = "demo-dynamic"
  description = "demo-dynamic"

  dynamic "ingress" {
    for_each = local.ports
    content {
      description = "description ${ingress.key}"
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}
  • Terraform: Variable validation with samples
variable "my_var" {
  type = number
  default = 0

  validation {
    condition = var.my_var >= 0
    error_message = "Please set my_var to a positive number or 0."
  }
}
  • Validating the length of a string
# file: variables.tf
variable "hetzner_api_token" {
  type        = string
  description = "Hetzner API token"

  validation {
    condition     = length(var.hetzner_api_token) == 64
    error_message = "Must be a 64 character long Hetzner API token."
  }
}
  • more example
variable "resource_name" {
  type        = string
  description = "Input name of the resource."
 
  validation {
    condition     = length(var.resource_name) > 5
    error_message = "The resource_name must be greater than 5 characters in length."
  }
}
variable "string_may_not_contain" {
  type = string
  default = "test"

  validation {
    error_message = "Value cannot contain a \"/\"."
    condition = !can(regex("/", var.string_may_not_contain))
  }
}
variable "string_only_valid_options" {
  type = string
  default = "approved"

  # using regex
  validation {
    condition     = can(regex("^(approved|disapproved)$", var.string_only_valid_options))
    error_message = "Invalid input, options: \"approved\", \"disapproved\"."
  }

  # using contains()
  validation {
    condition     = contains(["approved", "disapproved"], var.string_only_valid_options)
    error_message = "Invalid input, options: \"approved\", \"disapproved\"."
  }
}
variable "string_like_aws_region" {
  type = string
  default = "us-east-1"

  validation {
    condition     = can(regex("[a-z][a-z]-[a-z]+-[1-9]", var.string_like_aws_region))
    error_message = "Must be valid AWS Region names."
  }
variable "num_in_range" {
  type        = number
  default     = 1

  validation {
    condition     = var.num_in_range >= 1 && var.num_in_range <= 16 && floor(var.num_in_range) == var.num_in_range
    error_message = "Accepted values: 1-16."
  }
}
  • Code for VPC peering
resource "google_compute_network_peering" "peering1" {
  name         = "peering1"
  network      = google_compute_network.default.self_link
  peer_network = google_compute_network.other.self_link
}

resource "google_compute_network_peering" "peering2" {
  name         = "peering2"
  network      = google_compute_network.other.self_link
  peer_network = google_compute_network.default.self_link
}

resource "google_compute_network" "default" {
  name                    = "foobar"
  auto_create_subnetworks = "false"
}

resource "google_compute_network" "other" {
  name                    = "other"
  auto_create_subnetworks = "false"
}
  • Used code for session
### Create a vpc
resource "google_compute_network" "vpc_network" {
 
  name                    = "vnet01"
  auto_create_subnetworks = false
  mtu                     = 1460
}


#### Create a subnet
``t
resource "google_compute_subnetwork" "default" {
  name          = "test-subnetwork"
  ip_cidr_range = "192.168.1.0/24"
  region        = "us-central1"
  network       = google_compute_network.vpc_network.self_link
  
}

Create a firewall rule for ssh allow

resource "google_compute_firewall" "ssh" {
  name = "allow-ssh-vnet01"
  allow {
    ports    = ["22","80"]
    protocol = "tcp"
  }
  direction     = "INGRESS"
  network       = "vnet01"
  priority      = 1001
  source_ranges = ["0.0.0.0/0"]
 
}

resource "google_compute_network" "vpc_network1" {
 
  name                    = "vnet02"
  auto_create_subnetworks = false
  mtu                     = 1460
}

Create a subnet

resource "google_compute_subnetwork" "default1" {
  name          = "test-subnetwork"
  ip_cidr_range = "192.168.2.0/24"
  region        = "us-west1"
  network       = google_compute_network.vpc_network1.self_link
  
}

resource "google_compute_firewall" "ssh-vnet02" {
  name = "allow-ssh-vnet02"
  allow {
    ports    = ["22","80"]
    protocol = "tcp"
  }
  direction     = "INGRESS"
  network       = "vnet02"
  priority      = 1002
  source_ranges = ["0.0.0.0/0"]
 
}
VPC Peering for vnet01 and vnet02
resource "google_compute_network_peering" "peering1" {
  name         = "peering1"
  network      = google_compute_network.vpc_network.self_link
  peer_network = google_compute_network.vpc_network1.self_link
}

resource "google_compute_network_peering" "peering2" {
  name         = "peering2"
  network      = google_compute_network.vpc_network1.self_link
  peer_network = google_compute_network.vpc_network.self_link
}

Day3:

  • Terraform State Management
  • Terraform Workspace
  • Terraform Provisioner
  • Terraform Troubleshooting
  • Terraform Logging
  • Terrform Meta Argument for_each
  • Terrform conditinal expressions
  • Terraform functions
  • Terraform Module

TERRAFORM CLOUD & ENTERPRISE CAPABILITIES 2hrs

  • Terraform cloud enterprise
  • Terraform cloud
  • Terraform cloud workflow
  • Terraform enterprise
  • Terraform registry
  • Terraform best practices

Infrastructure as Code with Terraform and GitLab 2 hrs

  • GitLab CI - Introduction
  • GitLab - CI/CD
  • GitLab - CI/CD Variables
  • GitLab CI - Permissions
  • Configuring GitLab Runners
  • Terraform and Gitlab Integration

Infrastructure as Code with Terraform and Jenkins 2 hrs

  • Introduction to Jenkins

  • Jenkins - CI/CD Variables

  • Jenkins Plugins

  • Jenkins Pipelines

  • Jenkins Triggers

  • Jenkins Upstream and Downstream jobs

  • Configuring Jenkins Agents

  • Execute Terraform with Jenkins Pipeline

Install Terraform plugin

Go to Manage Jenkins > Manage Plugins >Available > search Terraform. image

Configure Terraform

Go to Manage Jenkins > Global Tool Configuration > It will display Terraform on the list. image

  • For_Each Example
resource "google_compute_instance" "default" {
  for_each = toset(var.each)
  name         = "foobar${each.key}"
  machine_type = "e2-medium"
  zone         = "${each.value}"
  tags  =        ["jenkins"]
  

  

  boot_disk {
    initialize_params {
      image = "debian-11-bullseye-v20220406"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral public IP
    }
  }

  metadata = {
    foo = "bar"
  }

 
}


### Learn for for each
variable "each" {
  default = ["us-central1-a","us-central1-b","us-central1-c"]
}

resource "google_compute_instance" "default" {
  for_each = toset(var.each)
  name         = "foobar${each.key}"
  machine_type = "e2-medium"
  zone         = "${each.value}"
  tags  =        ["jenkins"]
  
  boot_disk {
    initialize_params {
      image = "debian-11-bullseye-v20220406"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral public IP
    }
  }

  metadata = {
    foo = "bar"
  }
 
}



### Learn for for each
variable "each" {
  default = ["us-central1-a","us-central1-b","us-central1-c"]
}
  • Add ssh key to login
resource "google_compute_project_metadata" "my_ssh_key" {
  metadata = {
    ssh-keys = <<EOF
nippy:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqU07gbxzO3oeNIX2gq6hmOXPk79HV+YCshoHHlloOGwy1EgRlVtPHVLQDaPpvx1xNn4UFeaKvqpcOZctWQsugq1Zo51V4yhMCEbVGfcyKhgsIuRMBkzimAeeZV77mzaLzNQxeNHOzFBprSuaw63ODtqW+FYOq+RzqfPvohr2UdTT07Ki7IQYhbLJ9zuVTfQIn/ELE59z41vrCBeyZH9Om2Orgz4CKilamY5WDBuYFJqw8QhMKVwRiF+vsJS7iLeo1pPufbRBZqvtA5eU0rG2hjTcJBYsXuKswtelwzgTXmUI/c0cRcjp+4/UYVCh4StUrlRHphDct+qyloSzT+E1zXTIKWfml+0nAnOQIP+V98fzdHHzuYPebVS9mcDbuNz/TZaxtV0RWFt1cTEWBwNZGTpB2tUqUAqJgW5yc9kHKFMm5BDpAiMPQDJUIjLUc1DbHLPOy+Gd7annuFdcGnAVJvSud8yJYNg/ABc3PmB+WyWjnGLk6eUjk6PS708sjYtM= nippy@ITEM-S84221

      
    EOF
  }
}
  • Terraform Backend
https://www.terraform.io/language/settings/backends

[Terraform Backend](https://www.terraform.io/language/settings/backends)
  • Example for for_each
resource "google_compute_instance" "default" {
  for_each = var.images
  name         = "${each.key}"
  machine_type = var.machine_type
  zone         = "${each.value}"
   
  
  
  allow_stopping_for_update = true
 
  
  
 
  tags = ["foo", "bar"]

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

 
  network_interface {
   network = "default"
    

    access_config {
     
    }
  }

  metadata = {
    foo = "${each.key}"
    value = "${each.value}"
  }

  metadata_startup_script = "echo hi > /test.txt"

}
  • variables used for above code.
variable "name" {
    default = "tree1"
    description = "This variable will be used for vm name"
}

variable "machine_type" {
  default = "e2-medium"
  description = "This is for machine type"
}


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

variable "myvms" {
    default = ["prd","qa","dev"]
  
}


variable "images" {
  type = map

  default = {
    dev  = "us-central1-a"
    prd = "us-central1-b"
    qa =  "us-central1-c"
  }
}
  • Terraform condition
resource "google_compute_instance" "default" {
 
  name         = var.name
  machine_type = var.machine_type
  zone         = var.name!="prd" ? "us-central1-a" : "us-central1-b"
   

  
  allow_stopping_for_update = true
 
  
  
 
  tags = ["foo", "bar"]

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

 
  network_interface {
   network = "default"
    

    access_config {
     
    }
  }

  metadata = {
    foo = "news"
    value = "paper"
  }

  metadata_startup_script = "echo hi > /test.txt"

}
  • Provisioner Example with connection
resource "google_compute_instance" "default" {
 
  name         = var.name
  machine_type = var.machine_type
  zone         = "us-central1-a"
   

  
  allow_stopping_for_update = true
 
  
  
 
  tags = ["foo", "bar"]

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

 
  network_interface {
   network = "default"
    

    access_config {
     
    }
  }

  metadata = {
    foo = "news"
    value = "paper"
  }

  metadata_startup_script = "echo hi > /test.txt"
 provisioner "local-exec" {
    command = "echo ${self.network_interface.0.network_ip} >> private_ips.txt"
 }
 provisioner "file" {
    source      = "provider.tf"
    destination = "/tmp/admin.tf"
  }
   connection {
    type     = "ssh"
    user     = "admin"
    private_key =  file("admin")
    host     = "${self.network_interface.0.access_config.0.nat_ip}"
  }
}

Day 4:

  • Terraform Cloud
  • Terraform Sentinel Policies
  • Terraform with Jenkins
  • Terraform with Gitlab

Terraform Authentication with Google Cloud 2 hrs

  • Google Cloud Free Trial Account
  • Google Cloud Project - Service Account
  • Google Provider & version
  • Connect Terraform with GCP - I (username/password)
  • Connect Terraform with GCP - II (Cloud Shell VM)
  • Connect Terraform with GCP - III (Service Account)
  • Approach to Resource Provision

Terraform for Google Storage 2 hrs

  • [Hands-on] Getting started with Cloud Storage
  • [Hands-on] Google Cloud Storage with Terraform - I
  • [Hands-on] Google Cloud Storage with Terraform - II
  • [Hands-on] Google Cloud Storage with Terraform - III

Terraform for Google Network 2hrs

  • [Hands-on] Create VPC from Console
  • [Hands-on] Create VPC with Terraform Script
  • [Hands-on] Create VPC peering
  • [Hands-on] Configure DNS with Terraform
  • [Hands-on] Create Subnet - Terraform
  • [Hands-on] Create Firewall Rule – Terraform

Terraform for Compute Engine 2 hrs

  • [Hands-on] Create Compute Engine - Console
  • [Hands-on] Compute Engine - Terraform - I
  • [Hands-on] Compute Engine - Terraform - II
  • Update Compute Engine parameter - Tearraform
  • [Hands-on] Service Account - Terraform
  • [Hands-on] Attach Disk - Terraform
  • Destroy GCE resources

Terraform for Google Container and Kubernetes 2hrs

  • Setting up Kubernetes standard cluster

  • Setting up Kubernetes cluster(Autopilot)

  • Jenkins pipeline example

pipeline {
     agent { label 'agnt' }

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

.Gitlab-ci.yaml file

stages:
  - test
  - dev
  - prd
  - destroy
Terraform-version:
    stage: test
    script:
    - terraform version
Terraform-Initialize:
   stage: test
   script:
    - terraform init
Define-variables:
  stage: prd
  script:
   export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
   export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY

Testing-varibale:
  stage: test
  script:
    - echo $AWS_ACCESS_KEY_ID
Create-a-vm:
  stage: dev
  before_script:
    - terraform init --reconfigure
  script:
    - terraform apply --auto-approve
destroy:
  stage: destroy
  script:
    - terraform destroy --auto-approve
  when: manual
  only:
    - main

Terraform Sentinel

GitHub Link for Terraform Sentinel Policy

Terraform Sentinel Docs

  • Enable Terraform Trial
  • Create GitHub repo all policies
  • Enable Sentinel policy on Terraform cloud
  • Login to Terraform using Terraform login command
  • Run terraform command from your local system.

More References

Team and Governance for Terraform

https://github.com/hashicorp/terraform-guides/tree/master/governance

https://www.terraform.io/cloud-docs/sentinel https://www.terraform.io/cloud-docs/sentinel/import

  • sentinel.hcl

advisory soft-mandatory hard-mandatory

Sentinel Policies and sentinel.hcl

allowed-providers.sentinel enforce-mandatory-tags.sentinel limit-proposed-monthly-cost.sentinel restrict-vm-publisher.sentinel restrict-vm-size.sentinel sentinel.hcl

Terraform refresh

Terrafrom Trace Log Settings

export TF_LOG=TRACE export TF_LOG_PATH=“terraform-trace.log” echo $TF_LOG echo $TF_LOG_PATH

Linux Bash

cd $HOME vi .bashrc

Terraform log settings

export TF_LOG=TRACE export TF_LOG_PATH=“terraform-trace.log”

Verify after saving the file in new terminal

$ echo $TF_LOG TRACE $ echo $TF_LOG_PATH terraform-trace.log

  • Jenkinsfile example
pipeline {
     agent { label 'agent' }

    stages {
        stage('checkout the code') {
            steps {
                sh 'git clone https://github.com/monbostest/terraform-google-myvm.git'
            }
        }
        stage('change the workspace') {
            steps {
                sh 'cd $WORKSPACE'
            }
        }
        stage('Init') {
            steps {
                sh 'terraform init'
            }
        }
         stage('Apply') {
            steps {
                sh 'terraform apply --auto-approve'
            }
        }
    }
}