Terraform and GitLab Integration for Infrastructure as Code Workflows

Infrastructure as Code has become the standard way to provision and manage cloud resources with repeatable, auditable change. GitLab provides a complete platform around Terraform from version control to state management, pipeline automation and resource management. This guide covers how Terraform and GitLab work together, the native integrations available, and the operational practices that keep those workflows secure and maintainable.

GitLab as a Version Control System for Terraform

GitLab as a VCS for Terraform starts with keeping *.tf and *.tfvars files in a GitLab project. The repository provides an audit trail of who changed what, when and why. Multiple contributors can work on the same configuration at once using feature branches. Full history enables review of past changes and rollback to a known-good version of Terraform files when something breaks.

Workflow practices that pair with the repository include branching and merging with strategies such as Gitflow or GitLab Flow to manage new features, bug fixes, or environment-specific configurations. Merge requests provide a formal process for proposing and reviewing changes. Code review of Terraform code before changes are applied catches errors early and is good practice for any IaC setup.

A common structure inside a GitLab project is:

  • main.tf: Defines primary Terraform resources
  • variables.tf: Declares input variables
  • outputs.tf: Defines outputs from the configuration
  • versions.tf: Specifies Terraform version and provider plugin versions

Terraform’s state file terraform.tfstate maps configuration to real resources. Keeping it on a local disk is risky and does not work once more than one person is involved. Remote backends solve this, and GitLab offers a managed backend for Terraform state.

GitLab-Managed Terraform State with HTTP Backend

GitLab can act as a remote backend for Terraform state files using its built-in Terraform HTTP backend. GitLab can store Terraform state remotely via its built-in HTTP backend, with encryption, versioning, and automatic state locking to prevent concurrent modifications.

State is scoped per project and protected by GitLab’s access controls. Configuration points the Terraform backend block to the GitLab instance URL with a personal or CI/CD job token for authentication. State files can be stored directly in a GitLab project without an external service like S3.

How GitLab manages Terraform state in practice:

  • Store state files directly in a GitLab project
  • State is scoped per project and protected by GitLab access controls
  • Authentication uses a personal or CI/CD job token
  • Built-in encryption and versioning are provided
  • Automatic state locking prevents concurrent modifications

This removes the need to provision and secure a separate S3 or remote storage account for small to medium teams that already trust GitLab for access control.

CI/CD Pipelines for Terraform Automation

GitLab CI/CD pipelines can validate, plan, and apply Terraform, and OIDC lets CI jobs obtain short-lived cloud credentials instead of hardcoding static access keys.

The pipeline workflow typically includes validation of syntax and provider constraints, a plan job that generates a plan artifact for review, and an apply job that runs only after approval. Merge request diff views for plan output allow reviewers to see proposed changes inline with code changes.

GitLab offers native Terraform integration through its CI/CD pipelines, letting teams plan, validate, and apply infrastructure changes alongside application code in a single platform. It includes a built-in Terraform state backend, merge request diff views for plan output, and access controls that enforce approval workflows before any apply runs.

Key CI/CD capabilities:

  • Validate Terraform configurations
  • Generate and display plan output in merge requests
  • Apply changes with approval gates
  • Use OIDC for cloud authentication

OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. GitLab’s officially recommended path going forward is migration to GitLab’s OpenTofu CI/CD component.

The official GitLab Terraform CI/CD template Terraform/Base.gitlab-ci.yml was deprecated following HashiCorp’s license change and was fully removed in GitLab 18.0. If a pipeline still references it, two options exist:

  • Pin to a specific older GitLab release, e.g., ref: ‘v17.0.0-ee’ to keep using the Terraform-based template
  • Migrate to GitLab’s OpenTofu CI/CD component, which is the officially recommended path going forward

GitLab maintains a separate Terraform images repository gitlab-org/terraform-images that you can fork and self-host if you want to continue using Terraform without switching to OpenTofu.

Private Terraform Module Registry in GitLab

GitLab provides a private Terraform module registry for publishing and consuming versioned modules. Teams can publish internal modules to GitLab and consume them with version constraints, keeping reusable infrastructure components inside the same access control boundary as code.

Using GitLab as a private registry reduces external dependencies and simplifies access management for module consumers.

Managing GitLab with the Terraform Provider for GitLab

The GitLab Terraform provider can manage GitLab itself. The Terraform Provider for GitLab project has been migrated to GitLab and can be found here gitlab-org/terraform-provider-gitlab. The project welcomes contributions on GitLab.

The provider enables provisioning of GitLab resources such as projects, groups, members, CI/CD variables, and runners from Terraform configuration. This closes the loop where GitLab hosts Terraform code and Terraform configures GitLab.

Documentation for the GitLab Terraform provider is available on the Terraform docs site. Typical use cases include:

  • Create a new cluster on Amazon Elastic Kubernetes Service (EKS)
  • Troubleshoot issues with GitLab and Terraform
  • View the images that contain the gitlab-terraform shell script

Security Best Practices for Terraform and GitLab Workflows

The post lists 7 security best practices, including securing state, using OIDC, securing plan artifacts, least privilege, and IaC code scanning with tools like tfsec or checkov.

Security habits that go with GitLab and Terraform workflows:

  • Secure Terraform state storage and access
  • Use OIDC for cloud authentication instead of long-lived static keys
  • Secure plan artifacts and prevent exposure of secrets in logs
  • Apply least privilege for CI/CD job tokens and cloud IAM roles
  • Scan IaC code with tools like tfsec or checkov
  • Enforce approval workflows before apply runs
  • Maintain audit trails through GitLab merge requests and state versioning

These practices support a Terraform workflow that runs entirely on GitLab, from version control through to applying changes.

GitLab CI/CD vs GitHub Actions for Terraform

How does GitLab CI/CD for Terraform compare to GitHub Actions?

  • GitLab CI/CD is a fully integrated pipeline system built into GitLab, with native support for Terraform via a managed terraform CI component and built-in state management through the GitLab Terraform HTTP backend
  • GitHub Actions is a workflow automation platform for GitHub repos, requiring third-party actions and external state storage

Integration depth differs because GitLab provides first-class state backend, module registry, and provider for itself, while GitHub Actions relies on external services for state and module hosting.

Reference Configuration Examples

Example backend configuration for GitLab HTTP backend:

hcl terraform { backend "http" { address = "https://gitlab.example.com" lock_address = "https://gitlab.example.com" unlock_address = "https://gitlab.example.com" read_address = "https://gitlab.example.com" # authentication via token } }

Example CI job using OIDC for cloud credentials:

yaml .terraform_plan: image: registry.gitlab.com/gitlab-org/terraform-images/toolkit:latest id_tokens: GITLAB_OIDC_TOKEN: aud: https://gitlab.example.com script: - terraform init - terraform plan -out plan.out

Example usage of the GitLab provider:

```hcl
provider "gitlab" {
token = var.gitlab_token
}

resource "gitlab_project" "example" {
name = "example"
visibility = "private"
}
```

Operational Comparison Table

| Capability | GitLab Native | Typical External Setup |
| Git repository for Terraform | Built-in GitLab repo | External Git provider |
| Remote state storage | Built-in HTTP backend with encryption, versioning, locking | S3 + DynamoDB or similar |
| CI/CD for plan/apply | Native pipelines with merge request diff | Third-party actions |
| Cloud authentication | OIDC token federation | Static access keys |
| Private module registry | Built-in private registry | External registry |
| Manage GitLab resources | Terraform provider for GitLab | Manual UI/API |

Conclusion

GitLab provides an end-to-end platform for Terraform workflows. Version control in GitLab gives auditability and collaborative review. The built-in HTTP Terraform state backend provides encrypted, versioned, locked state storage without external services. CI/CD pipelines automate validate-plan-apply with OIDC for secure short-lived credentials and merge request diff views for plan output. A private module registry keeps reusable modules in-house, and the Terraform provider for GitLab allows infrastructure teams to manage GitLab itself as code.

The deprecation of the Terraform/Base.gitlab-ci.yml template and the move toward OpenTofu CI/CD components reflects the changing ecosystem after HashiCorp’s license change. Teams can pin to older GitLab releases to keep existing Terraform templates or migrate to the recommended OpenTofu path, with the option to self-host Terraform images via gitlab-org/terraform-images if needed.

Security remains central. Securing state, using OIDC, protecting plan artifacts, applying least privilege, and scanning IaC with tfsec or checkov are essential habits. With these practices in place, Terraform workflows can run entirely on GitLab from code commit to production apply while maintaining control, visibility and compliance.

Sources

  1. Scalr Learning Center
  2. Spacelift Blog
  3. GitLab Docs
  4. GitHub Terraform Provider

Related Posts