Terraform Pull Request Automation using Gitlab pipelines

GitLab is a popular platform for DevOps teams to manage their code repositories, CI/CD pipelines, and more. GitLab pipelines allow you to automate many tasks in your development workflow, including building, testing, and deploying your code. In this blog post, we will discuss how to automate Terraform pull requests using GitLab pipelines.

Introduction

GitLab is a popular platform for DevOps teams to manage their code repositories, CI/CD pipelines, and more. GitLab pipelines allow you to automate many tasks in your development workflow, including building, testing, and deploying your code. In this blog post, we will discuss how to automate Terraform pull requests using GitLab pipelines.

What is a Pull Request?

A pull request (PR) is a feature of Git-based code repositories like GitLab. It allows contributors to propose changes to a codebase, and then submit those changes for review by other members of the team. Once the PR is approved, the changes can be merged into the main codebase.

GitLab Pipelines

GitLab pipelines are a powerful feature that allows you to automate many tasks in your development workflow. Pipelines can be triggered by various events, including pull requests, pushes to a branch, or scheduled events.

Pipelines are defined using YAML files called .gitlab-ci.yml, which can be stored in your GitLab repository. A pipeline is made up of stages, which are groups of jobs that run in parallel or sequentially.

Automating Terraform Pull Requests with GitLab Pipelines

To automate Terraform pull requests with GitLab pipelines, we need to create a pipeline that performs the following tasks:

  1. Check out the pull request branch
  2. Initialize Terraform
  3. Plan the Terraform changes
  4. Comment on the pull request with the Terraform plan
  5. Validate the Terraform configuration syntax
  6. Apply the Terraform changes

Let's take a look at how we can accomplish each of these tasks using GitLab pipelines.

Step 1: Check out the Pull Request Branch

The first step is to check out the pull request branch. This can be accomplished using the git clone command in the pipeline.

stages:
 - terraform

terraform:
 stage: terraform
 script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform

This pipeline defines a stage named "terraform" that runs when a pull request is opened or updated. The stage has two jobs, the first job clones the pull request branch and the second job changes the working directory to the cloned repository.

Step 2: Initialize Terraform

The next step is to initialize Terraform. This can be accomplished using the terraform init command in the pipeline.

 script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform
   - terraform init

This step runs the terraform init command to initialize the Terraform backend and download any necessary providers.

Step 3: Plan the Terraform Changes

The next step is to plan the Terraform changes. This can be accomplished using the terraform plan command in the pipeline.

 script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform
   - terraform init
   - terraform plan -out=tfplan

This step runs the terraform plan command and saves the output to a file named tfplan.

Step 4: Comment on the Pull Request with the Terraform Plan

The next step is to comment on the pull request with the Terraform plan. This can be accomplished

script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform
   - terraform init
   - terraform plan -out=tfplan
   - export TFPLAN_COMMENT="$(terraform show -no-color tfplan)"
   - export DISCUSSION_ID="$(curl --header \"PRIVATE-TOKEN: $CI_JOB_TOKEN\" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/discussions\" | jq -r '.[0].id')"
   - curl --request POST --header \"PRIVATE-TOKEN: $CI_JOB_TOKEN\" --header \"Content-Type: application/json\" --data \"{ \\\"body\\\": \\\"$TFPLAN_COMMENT\\\" }\" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/discussions/$DISCUSSION_ID/notes\"

This step uses the terraform show command to read the contents of the tfplan file and save it to a variable named TFPLAN_COMMENT. It then uses the GitLab API to create a new comment on the pull request with the Terraform plan.

Step 5: Validate the Terraform Configuration Syntax

The next step is to validate the syntax of the Terraform configuration. This can be accomplished using the terraform validate command in the pipeline.

 script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform
   - terraform init
   - terraform validate
   - terraform plan -out=tfplan
   - export TFPLAN_COMMENT="$(terraform show -no-color tfplan)"
   - export DISCUSSION_ID="$(curl --header \"PRIVATE-TOKEN: $CI_JOB_TOKEN\" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/discussions\" | jq -r '.[0].id')"
   - curl --request POST --header \"PRIVATE-TOKEN: $CI_JOB_TOKEN\" --header \"Content-Type: application/json\" --data \"{ \\\"body\\\": \\\"$TFPLAN_COMMENT\\\" }\" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/discussions/$DISCUSSION_ID/notes\"

This step runs the terraform validate command to check the syntax of the Terraform configuration. If there are any errors, the pipeline will fail and the pull request will not be merged.

Step 6: Apply the Terraform Changes

The final step is to apply the Terraform changes. This can be accomplished using the terraform apply command in the pipeline.

bashCopy code

 script:
   - git clone $CI_MERGE_REQUEST_PROJECT_URL.git -b $CI_MERGE_REQUEST_TARGET_BRANCH_NAME /terraform
   - cd /terraform
   - terraform init
   - terraform validate
   - terraform plan -out=tfplan
   - terraform apply tfplan

This step runs the terraform apply command to apply the changes defined in the Terraform plan.

Explore more:

Import Existing Infrastructure to Terraform

How to Test Terraform Infrastructure Code

Terraform IDE plugins

Pull Request Automation using Terraform Cloud

Terraform Pull Request Automation using Atlantis

Terraform tagging strategies and Cost Estimation Tools

Terraform Pull Request Automation using Jenkins

Terraform Pull Request Automation using Bitbucket

Terraform Pull Request Automation using Spacelift

Terraform Pull Request Automation using Gitlab pipelines

Terraform Pull Request Automation using Scalr

Terraform Pull Request Automation using Env0