• Gavin In The Cloud
  • Posts
  • Automating Cloud Run Deployment for a Hello World App Using Terraform and GitLab CI/CD

Automating Cloud Run Deployment for a Hello World App Using Terraform and GitLab CI/CD

Effortless Cloud Run Deployment: Unveiling the Power of Terraform and GitLab CI/CD for Seamlessly Deploying a Hello World App

Automating Cloud Run Deployment for a Hello World App Using Terraform and GitLab CI/CD

Introduction: As cloud engineers, we are continually seeking ways to optimize and automate our cloud workflows. In this blog post, we will delve into the process of automating the deployment of a simple "Hello World" application on Google Cloud Run using Terraform and GitLab CI/CD. We'll cover the step-by-step implementation of provisioning the required resources, setting up the CI/CD pipeline, and ultimately achieving a seamless and efficient deployment process.

Prerequisites: Before we jump into the technical details, ensure that you have the following prerequisites in place:

  • A Google Cloud Platform (GCP) account with appropriate permissions to create resources like Google Cloud Run services.

  • A GitLab account with a repository set up to manage your Terraform code.

Repo Structure: To maintain a well-organized project structure, we will follow this directory structure within our GitLab repository: GitLab-Repo

You can simply clone my public repository: GitLab-Repo

Terraform Configuration: Let's explore the details of each component of our Terraform code:

main.tf: The main.tf file defines the Terraform configuration for provisioning a Google Cloud Run service. It specifies the container image to deploy and sets up access permissions using IAM policies.

resource "google_cloud_run_service" "cloud-run-tf" {
  name     = "cloud-run-tf"
  location = "us-central1"

  template {
    spec {
      containers {
        image = "us-docker.pkg.dev/cloudrun/container/hello"
      }
    }
  }
}

resource "google_cloud_run_service_iam_policy" "app-access" {
  service = google_cloud_run_service.cloud-run-tf.name
  location = google_cloud_run_service.cloud-run-tf.location
  policy_data = data.google_iam_policy.pub-1.policy_data
}

data "google_iam_policy" "app-role" {
  binding {
    role = "roles/run.invoker"
    members = ["allUsers"]
  }
}

provider.tf: The provider.tf file configures the Terraform provider for Google Cloud. It specifies the necessary details such as the required provider version, project ID, region, and zone.

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.58.0"
    }
  }
  backend "gcs" {
    bucket  = "your-backend-bucket" // Replace with your backend bucket name
    prefix  = "terraform/state"
  }
}

provider "google" {
  project = "project-id" // Replace with your project ID
  region  = "us-central1" // Replace with your desired region
  zone    = "us-central1-c" // Replace with your desired zone
}

GitLab CI/CD Configuration: The .gitlab-ci.yml file sets up the CI/CD pipeline for automating the infrastructure deployment process. It defines stages, jobs, and associated scripts to perform tasks such as validation, planning, applying, and destroying Terraform changes.

---
workflow:
  rules:
    - if: $CI_COMMIT_BRANCH != "main" && $CI_PIPELINE_SOURCE != "merge_request_event"
      when: never
    - when: always

variables:
  TF_DIR: ${CI_PROJECT_DIR}/terraform
  STATE_NAME: "gitlab-terraform-gcp-tf"

stages:
  - validate
  - plan
  - apply
  - destroy

image:
  name: hashicorp/terraform:light
  entrypoint: [""]
  
before_script:
  - terraform --version
  - cd ${TF_DIR}
  - terraform init -reconfigure

validate:
  stage: validate
  script:
    - terraform validate
  cache:
    key: ${CI_COMMIT_REF_NAME}
    paths:
    - ${TF_DIR}/.terraform
    policy: pull-push

plan:
  stage: plan
  script:
    - terraform plan 
  dependencies:
    - validate
  cache:
    key: ${CI_COMMIT_REF_NAME}
    paths:
    - ${TF_DIR}/.terraform
    policy: pull


apply:
  stage: apply
  script:
    - terraform apply  -auto-approve
  dependencies:
    - plan
  cache:
    key: ${CI_COMMIT_REF_NAME}
    paths:
    - ${TF_DIR}/.terraform
    policy: pull

destroy:
  stage: destroy
  script:
    - terraform destroy  -auto-approve
  dependencies:
    - plan
    - apply
  cache:
    key: ${CI_COMMIT_REF_NAME}
    paths:
    - ${TF_DIR}/.terraform
    policy: pull
  when: manual

Implementation Steps: With the configurations in place, let's walk through the implementation steps.

  1. Set up GitLab Repository: Create a new repository on GitLab or use an existing one to host your Terraform code. If needed, clone this repository: GitLab-Repo

  2. Configure GCP Provider: In the Terraform provider.tf file, configure the GCP provider with your backend bucket, project ID, region, and zone.

  3. Set Secrets in GitLab: In your GitLab repository, navigate to Settings > CI/CD > Variables. Add a new variable named "GOOGLE_CREDENTIALS" and paste the contents of your Google Cloud service account key file into the value field. This securely provides the necessary credentials for Terraform to authenticate with GCP.

Note: Make sure to remove any white spaces in your token content before pasting it.

  1.  Run the Pipeline: Commit and push your Terraform code to the GitLab repository. The GitLab CI/CD pipeline will automatically trigger, executing the defined stages and jobs.

  2.  Verify Resource Creation in GCP: Check the Google Cloud Run console to confirm the successful deployment of your "Hello World" application.

Conclusion: In this blog post, we successfully automated the creation of a Google Cloud Storage (GCS) bucket, uploaded an object, and deployed a Google Cloud Function using Terraform and GitLab CI/CD. By following the steps outlined above, you can now efficiently manage and automate your GCP resources. Remember to regularly update your Terraform code and pipeline to reflect any changes in your cloud infrastructure requirements. By combining Terraform and GitLab CI/CD, you can streamline cloud workflows, improve consistency, and minimize manual intervention. Happy automating!

References: GitLab-Repo