Infrastructure-as-code: integration of Terraform with GitLab

Infrastructure-as-code: integration of Terraform with GitLab

Author : Stanislas Peyssard (DevOps/Cloud Architect & Manager) at Astrakhan - Published date : July 8, 2021

Terraform and GitLab

At Astrakhan, when we talk about Infrastructure as Code, we are convinced that GitOps is the essential practice to adopt, which consists in considering Git as the single source of truth of the desired state of the entire system. This means applying the same rigor to the infrastructure as we know in the world of application development to better build, collaborate, and deliver the infrastructure by tracking all changes.

Various tools allow you to describe your infrastructure as code to automate it, such as Pulumi, Troposphere, AWS CloudFormation or AWS Cloud Development Kit (CDK), or Terraform. In the rest of this post, we will focus on Terraform. We will present in this article an integration of Terraform with GitLab and the externalization of the configuration specific to Terraform to keep in your repository only what concerns your target infrastructure. 

Integration of Terraform with GitLab

We recommend reading Brad Downey’s (GitLab) excellent posts on this topic:

Why collaboration technology is critical for GitOps

•  How infrastructure teams use GitLab and Terraform for GitOps

•  How to deploy to any cloud using GitLab for GitOps

Through these articles, Brad Downey provides this Terraform template, which has inspired our work. 

The Terraform pipeline is divided into 4 stages, corresponding to the four main Terraform actions:

•  validate: control the code of the infrastructure

•  plan: build a plan of operations to align the system state with its description as code

•  apply: apply the plan built in the previous step

•  destroy: delete the system and all its resources

Factoring the code for the Terraform configuration

When we talk about the Terraform configuration, we are referring to the Terraform backend and the Cloud provider whose configuration appears in each of your Terraform projects. To avoid having to redefine these configurations for each project, we suggest setting them as GitLab CI/CD variables. In the following example of project organization,

•  the code specific to the Terraform backend is configured at the level of the GitLab “cloud” subgroup

•  the code specific to the Cloud provider is configured in the AWS, Azure, or GCP subgroups corresponding to your provider

Labs

To configure GCP access, add the following variables:

•  TF_VAR_gcp_project = ID of your GCP project

•  GOOGLE_CLOUD_KEYFILE_JSON = JSON file corresponding to a GCP account service with the necessary rights to build the infrastructure

In this example, we also use GitLab as a Terraform backend. That’s why it’s necessary to add a GitLab access token.

•  GITLAB_TOKEN = personal access token with owner rights on the project

Now to implement the shared solution, follow these instructions:

•  Add to the cloud subgroup a GitLab CI/CD variable of type “File” named “TFCD_BACKEND” with the following content:

•  For Google Cloud Platform, add to the GCP subgroup a GitLab CI/CD variable of type “File” named “TFCD_PROVIDER” with the following content:

In the CI chain, it is now necessary to dump these two variables as Terraform code files before the Terraform commands are executed. Adding the following two lines to the before_script of the Terraform jobs allows you to write the content of the two variables to the provider.tf and backend.tf files.

For this last step, you can reuse our pipeline, which was provided in this project.