GitLab CI
GitLab CI/CD is a robust automation platform for deploying infrastructure with Terraform across AWS, Azure, and GCP. It offers tight integration with GitLab repositories, built-in secret management, and flexible runners. Below are real-life scenarios, best practices, and a comparison with GitHub Actions and Azure DevOps Pipelines.
Why Use GitLab CI/CD for Terraform?
Integrated experience: Native with GitLab repos, merge requests, and issues.
Secret management: Built-in CI/CD variables and Vault integration.
Flexible runners: Use shared, group, or self-hosted runners (Linux, NixOS, Docker, etc.).
Multi-cloud: Supports AWS, Azure, GCP, and hybrid deployments.
Pipeline as Code: YAML-based, versioned, and auditable.
Real-Life Scenarios
1. Deploying to AWS with GitLab CI/CD
stages:
- validate
- plan
- apply
variables:
TF_ROOT: "terraform"
validate:
stage: validate
image: hashicorp/terraform:1.7.5
script:
- cd $TF_ROOT
- terraform init -input=false
- terraform validate
plan:
stage: plan
image: hashicorp/terraform:1.7.5
script:
- cd $TF_ROOT
- terraform init -input=false
- terraform plan -out=tfplan
artifacts:
paths:
- $TF_ROOT/tfplan
apply:
stage: apply
image: hashicorp/terraform:1.7.5
script:
- cd $TF_ROOT
- terraform apply -auto-approve tfplan
when: manual
only:
- main
environment:
name: production
dependencies:
- plan
When to use:
Teams using GitLab for code, issues, and CI/CD
AWS, Azure, or GCP deployments with GitLab-managed secrets
2. Multi-Cloud Deployments with Secure Variables
Store cloud credentials as GitLab CI/CD variables:
AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
ARM_CLIENT_ID
,ARM_CLIENT_SECRET
,ARM_SUBSCRIPTION_ID
,ARM_TENANT_ID
GOOGLE_CREDENTIALS
(JSON)
Reference them in your pipeline:
before_script:
- export AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY"
- export ARM_CLIENT_ID="$ARM_CLIENT_ID"
- export ARM_CLIENT_SECRET="$ARM_CLIENT_SECRET"
- export ARM_SUBSCRIPTION_ID="$ARM_SUBSCRIPTION_ID"
- export ARM_TENANT_ID="$ARM_TENANT_ID"
- export GOOGLE_CREDENTIALS="$GOOGLE_CREDENTIALS"
When to use:
Centralized, secure multi-cloud deployments from a single pipeline
3. NixOS-based Runners for Reproducible IaC
Use a NixOS self-hosted runner to ensure consistent Terraform, provider, and tool versions:
# shell.nix for runner
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [ terraform tflint awscli azure-cli google-cloud-sdk ];
}
Register the runner with this shell for reproducible builds.
When to use:
Teams needing strict reproducibility and custom toolchains
Best Practices for Security and Deployments
Store all secrets as masked/protected CI/CD variables—never in code.
Use separate variables and pipelines for dev, staging, and prod.
Use remote state (S3, Azure Storage, GCP Storage) with state locking.
Pin Terraform and provider versions in your pipeline and code.
Use
terraform validate
,tflint
, andcheckov
in the pipeline.Require manual approval for production applies.
Use merge request pipelines for plan/apply previews.
GitLab CI/CD vs GitHub Actions vs Azure DevOps Pipelines
Best for
Self-hosted, DevSecOps
Open source, GitHub
Enterprise, Azure
Secret Management
CI/CD Variables, Vault
GitHub Secrets
Key Vault, Library
RBAC
Flexible, project/group
Basic (org/repo)
Native, granular
Multi-cloud
Yes
Yes
Yes
Pipeline as Code
YAML
YAML
YAML
Marketplace
Registry
Actions Marketplace
Extensions
Audit/Compliance
Strong
Moderate
Strong
Integration
GitLab, self-hosted
GitHub, open ecosystem
Azure, MSFT stack
Summary:
GitLab CI/CD: Best for self-hosted, advanced runners, and integrated DevSecOps.
GitHub Actions: Best for open source, GitHub-native, fast setup, good for multi-cloud.
Azure DevOps Pipelines: Best for enterprise Azure, strong RBAC, Key Vault, and compliance.
References
Tip: Use GitLab CI/CD for secure, reproducible, and auditable Terraform deployments—especially if you need custom runners, DevSecOps, or self-hosted control.
- [Terraform in GitLab CI/CD Pipelines](pages/terraform/cicd/gitlab-ci.md)
Last updated