Terraform - Deploy to Google Cloud

The Google Cloud provider allows you to create Terraform configurations to deploy configurations to the large set of Google Cloud services. Among the resources we can manage are:

  • Infrastructure (Instances, Images, Networks, …​)
  • AppEngine
  • Databases (Cloud SQL, Big Query, Firebase, …)
  • Kubernetes
  • cloud-storage
  • …​

Create a key for the Service Account

  • Select the Google Cloud project.
  • In the navigation menu select IAM and administration | service accounts.
  • Select Create service account.
  • Give it a name (pe terraform)
  • Select Create.
  • In the Grant this service account access to the project wizard step, select the role Project → Editor.
  • Edit the Service Account. In the Keysselect section Add Key | Create password.
  • Leave JSON in the key type..
  • Select Create. The private key will then be downloaded.

Provider configuration
To use it you have to configure its access parameters . We will do it in a file providers.tf

The file providers.tf

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

provider "google" {
  version = "3.5.0"

  credentials = file("../gcp-identity.json")

  project = var.gcp-project
  region  = "us-central1"
  zone    = "us-central1-c"
}
Variables defined in the file are usedvariables.tf

variable "gcp-username" {
  description = "GCP user name"
  default     = "mtorres"
}

variable "gcp-project" {
  description = "GCP project"
  default     = "cc2021-clouddi"
}
Initialize the provider
To initialize run terraform init.
Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/google versions matching "3.5.0"...
- Installing hashicorp/google v3.5.0...
- Installed hashicorp/google v3.5.0 (signed by HashiCorp)

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
This will create a folder .terraform with the Google Cloud plugin installed and available for use in the project.
Deploy an instance
Creating an instance is done with google_compute_instance .
Next, we'll create an instance named tf-vm. The name used in resource, not the name assigned in name, is the one that refers to the created resource object. This allows to treat the created resource (eg to assign it a fixed IP address, to connect a volume to it, …​).
The following example illustrates the creation of a virtual machine with an ephemeral IP address.
By default, if no fixed IP address is provided, Google Cloud will create an ephemeral one for the virtual machine.
resource "google_compute_instance" "tf-vm" { #1
  name         = "tf-vm"
  zone         = "us-central1-a"
  machine_type = "n1-standard-1"
  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-1804-lts"
    }
  }

  # Add SSH access to the Compute Engine instance
  metadata = {
    ssh-keys = "${var.gcp-username}:${file("~/.ssh/id_rsa.pub")}"
  }

  # Startup script
  # metadata_startup_script = "${file("update-docker.sh")}"

  network_interface { #2
    network    = "default"
    subnetwork = "default"

    access_config {} #3
  }
}

output "tf-vm-internal-ip" { #4
  value      = google_compute_instance.tf-vm.network_interface.0.network_ip
  depends_on = [google_compute_instance.tf-vm]
}

output "tf-vm-ephemeral-ip" { #5
  value      = google_compute_instance.tf-vm.network_interface.0.access_config.0.nat_ip
  depends_on = [google_compute_instance.tf-vm]
}

  1. Creation of an instance resource (virtual machine) in Google Cloud. The created resource object is assigned to the variable tf-vm.
  2. Network to which the created instance will connect.
  3. Leaving access_configunconfigured will cause an ephemeral IP address to be generated.
  4. Internal IP address of the instance
  5. Ephemeral IP address of the instance

Modify the deployment
As an illustration, this example shows how to apply changes to a previously deployed configuration. In this case it is:

  • Change the machine type of the deployed instance to n1-standard-2.
  • Create a 1GB volume ( google_compute_disk).
  • Attach the volume to the virtual machine ( google_compute_attached_disk).
resource "google_compute_instance" "tf-vm" {
  name         = "tf-vm"
  zone         = "us-central1-a"
  machine_type = "n1-standard-2" #1
  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-1804-lts"
    }
  }
...
resource "google_compute_disk" "tf-disk" { #2
  name = "tf-disk"
  type = "pd-ssd" #3
  zone = "us-central1-a" #4
  size = 1 #5
}

resource "google_compute_attached_disk" "attached-tf-disk" { #6
  disk     = google_compute_disk.tf-disk.id #7
  instance = google_compute_instance.tf-vm.id #8
}

  • Image resizing
  • Creating a volume resource
  • SSD Type
  • Area in which the storage is located
  • Volume Size Specification
  • Connecting the volume to the instance
  • Access to the id of the created volume
  • Access to instance id

When executing with terraform apply, Terraform will inform us of the detected changes and the new configuration. The new settings will be applied if we confirm the operation.
Run an initialization script
A very interesting feature in the deployment of an instance is the possibility of running an initialization script during its creation. This allows the creation of instances with packages installed and configured.
Terraform allows this operation on GCP by passing a script in the parameter metadata_startup_scriptwhen creating the instance.
Modifying the value of metadata_startup_script will create a new server if is used terraform apply.
In this section we will see how to create a provisioned instance with Docker and Docker Compose. Additionally, the instance will be initialized with a file docker-compose.ymlthat deploys two containers: a MySQL container with an initialized database and another container with a PHP application that displays a catalog of products stored in the MySQL container.
The application must be accessible on the Internet. Therefore, a rule must be defined in the firewall that allows HTTP communication. We will take advantage of the configuration to also define a rule for SSH communication. Each rule will have an associated tag. Instances that want to apply the rule will include the corresponding tag in their definition.

The file network-firewall.tf

# allow http traffic
resource "google_compute_firewall" "allow-http" {
  name    = "tf-fw-allow-http" #1
  network = "default" #2
  allow {
    protocol = "tcp"
    ports    = ["80"] #3
  }
  target_tags = ["http"] #4
}

# allow ssh traffic
resource "google_compute_firewall" "allow-ssh" {
  name    = "tf-fw-allow-ssh" #5
  network = "default" #6
  allow {
    protocol = "tcp"
    ports    = ["22"] #7
  }
  target_tags = ["ssh"] #8
}

  • Firewall rule name
  • Network to which the defined rule applies
  • open port
  • Label to be able to use the ruler
  • Firewall rule name
  • Network to which the defined rule applies
  • open port
  • Label to be able to use the ruler

resource "google_compute_instance" "tf-vm" {
  name         = "tf-vm"
  zone         = "us-central1-a"
  machine_type = "n1-standard-1"
  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-1804-lts"
    }
  }

  # Add SSH access to the Compute Engine instance
  metadata = {
    ssh-keys = "${var.gcp-username}:${file("~/.ssh/id_rsa.pub")}"
  }

  tags = ["ssh", "http"] #1

  # Startup script
  metadata_startup_script = file("setup-docker.sh") #2

  network_interface {
    network    = "default"
    subnetwork = "default"

    access_config {}
  }
}

  • Firewall rules to apply to the instance
  • Instance initialization script

setup-docker.shThe instance initialization script

#!/bin/bash

echo "Instalando Docker"

apt-get update
apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
apt-key fingerprint 0EBFCD88
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io #1
systemctl enable docker

echo "Instalando Docker Compose" #2
curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

git clone https://github.com/ualmtorres/docker_customer_catalog.git #3
cd docker_customer_catalog
docker-compose up -d #4

exit 0

  • Docker installation
  • Install Docker Compose
  • Repository clone with deployment file, application, and database initialization script
  • Environment deployment (Database + Application)

To create the instance with Terraform, simply create the resource by passing metadata_startup_scriptthe name and path of the initialization script to the property. In this case, the initialization script is assumed to be in the same directory as the Terraform script.
The following figure illustrates the result after a few minutes that are required for the creation and initialization of the instance and deployment of the database and catalog application.

Get Started Tutorial - Google Cloud with Terraform

Tutorial Serverless Deployment on Cloud Run using Terraform and Configuring Cloud Run with Terraform

No comments

Powered by Blogger.