Gitlab-CI is awesomelishiously simple. Let’s assume you have a Terraform Gitlab project with a folder structure like mine:

README.md
.gitignore
terraform
 │  main.tf
 │  outputs.tf
 └──variables.tf

You can find a .gitignore example here.

Since we can provide our credentials via environment variables, the provider can look like:

provider "aws" {
  version = ">= 2.28.1"
}

In the Gitlab project page, go to “Settings” > “CI/CD” > “Variables”, and set the following variables:

  • AWS_ACCESS_KEY_ID: e.g. AKIA26UDUJHTR4HNB6PD
  • AWS_SECRET_ACCESS_KEY: e.g. wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • AWS_DEFAULT_REGION: e.g. eu-central-1

Gitlab variables settings

Remote state

In order to remember the state between pipelines, we need to add a backend. For example an s3 bucket; at the following backend.tf:

terraform {
  backend "s3" {
    bucket = "dobdata-terraform-backend"
    key    = "network/terraform.tfstate"
    region = "eu-central-1"
  }
}

the gitlab-ci file

Using the light Terraform image from Hashicorp, this is the .gitlab-ci.yml file:

image:
  name: hashicorp/terraform:light
  entrypoint:
    - "/usr/bin/env"
    - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

before_script:
  - rm -rf .terraform
  - terraform --version
  - terraform init ./terraform

stages:
  - validate
  - plan
  - apply

validate:
  stage: validate
  script:
    - terraform validate ./terraform

plan:
  stage: plan
  script:
    - terraform plan -out "dobcluster.tfplan" ./terraform
  dependencies:
    - validate
  artifacts:
    paths:
      - dobcluster.tfplan

apply:
  stage: apply
  script:
    - terraform apply -input=false "dobcluster.tfplan"
  dependencies:
    - plan
  when: manual

If you’re familiar with Terraform, this file speaks for itself. After the plan stage is succeeded, you can check the plan and if you like the results, click play on the Apply job and the infra is deployed.

Resources