Terraform Advanced — GitLab CI Pipeline

less than 1 minute read

Terraform CI/CD with GitLab CI.


Pipeline File

# .gitlab-ci.yml
image:
  name: hashicorp/terraform:1.7
  entrypoint: [""]

variables:
  TF_ROOT: infra

cache:
  key: terraform
  paths:
    - ${TF_ROOT}/.terraform

stages:
  - validate
  - plan
  - apply

validate:
  stage: validate
  script:
    - cd ${TF_ROOT}
    - terraform init -backend=false
    - terraform validate
    - terraform fmt -check
  rules:
    - if: $CI_MERGE_REQUEST_IID

plan:
  stage: plan
  script:
    - cd ${TF_ROOT}
    - terraform init
    - terraform plan -out=plan.tfplan
  artifacts:
    paths:
      - ${TF_ROOT}/plan.tfplan
    expire_in: 1 week
  rules:
    - if: $CI_MERGE_REQUEST_IID

apply:
  stage: apply
  script:
    - cd ${TF_ROOT}
    - terraform init
    - terraform apply plan.tfplan
  dependencies:
    - plan
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  when: manual  # Require manual click to apply

GitLab OIDC with AWS

# Use GitLab's OIDC token
assume_role:
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - >
      STS_RESPONSE=$(aws sts assume-role-with-web-identity
        --role-arn $AWS_ROLE_ARN
        --role-session-name gitlab-ci
        --web-identity-token $GITLAB_OIDC_TOKEN)
    - export AWS_ACCESS_KEY_ID=$(echo $STS_RESPONSE | jq -r '.Credentials.AccessKeyId')
    - export AWS_SECRET_ACCESS_KEY=$(echo $STS_RESPONSE | jq -r '.Credentials.SecretAccessKey')
    - export AWS_SESSION_TOKEN=$(echo $STS_RESPONSE | jq -r '.Credentials.SessionToken')

What’s Next?

Automate Terraform via pull requests with Atlantis.

← OIDC Authentication Atlantis Setup →

Updated: