A collection of reusable Terraform/OpenTofu modules for managing GitLab resources. These modules provide a consistent, declarative way to manage GitLab projects, groups, and their associated resources.
- Terraform >= 1.6.0 or OpenTofu >= 1.6.0
- GitLab Provider >= 18.0.0, < 19.0.0
- GitLab API token with appropriate scopes
AI has been used to create all the things I don't like creating so:
- Documentation - all the READMEs, including this one, but not this section
- Entirety of examples - a way to test the code before pushing
- The issues, labels and milestones that are assigned to this project (using my own modules to manage them from different repository)
- In the future - probably CONTRIBUTING.md when needed
All other code has NOT been touched by AI. I enjoy writing code and I'm taking this as an opportunity to get to know the Gitlab ecosystem too.
| Module | Description |
|---|---|
| project | Create and manage GitLab projects with full configuration |
| group | Create and manage GitLab groups with nested resources |
| branch-protection | Manage branch protection rules |
| tag-protection | Manage tag protection rules |
| membership | Manage project and group memberships |
| labels | Manage project and group labels |
| badges | Manage project and group badges |
| milestones | Manage project milestones |
| issues | Manage project issues |
| issue-board | Manage project and group issue boards |
| variables | Manage CI/CD variables |
| access-token | Manage project, group, and personal access tokens |
| project-mirror | Manage project push and pull mirrors |
| pipeline-schedule | Manage pipeline schedules |
| application | Manage OAuth applications |
terraform {
required_version = ">= 1.6.0"
required_providers {
gitlab = {
source = "gitlabhq/gitlab"
version = ">= 18.0.0, < 19.0.0"
}
}
}
provider "gitlab" {
base_url = "https://gitlab.com" # Or your self-hosted GitLab URL
token = var.gitlab_token
}
variable "gitlab_token" {
description = "GitLab API token"
type = string
sensitive = true
}module "my_project" {
source = "gitlab.com/gitlab-utl/project/gitlab"
version = "~> 1.1"
projects = {
"awesome-project" = {
description = "My awesome project"
namespace_id = 12345
visibility_level = "private"
default_branch = "main"
}
}
}export TF_VAR_gitlab_token="your-token-here"
tofu init
tofu plan
tofu applyAll modules share these common features:
Define resources in YAML files for easier management:
module "labels" {
source = "gitlab.com/gitlab-utl/labels/gitlab"
version = "~> 1.1"
target = {
type = "project"
id = "12345"
}
labels_file = "./labels.yml"
}Prevent Terraform from managing resources after initial creation:
module "project" {
source = "gitlab.com/gitlab-utl/project/gitlab"
version = "~> 1.1"
create_only = true
projects = {
"imported-project" = {
description = "Don't manage after creation"
}
}
}User lookups by email, username, or user ID:
module "membership" {
source = "gitlab.com/gitlab-utl/membership/gitlab"
version = "~> 1.1"
target = {
type = "project"
id = "12345"
}
membership = {
developer = {
users = ["user@example.com"]
find_users = "email" # or "username" or "userid"
}
}
}Working examples are available in the examples directory:
| Example | Description |
|---|---|
| project | Project creation with various settings |
| branch-protection | Branch protection rules |
| tag-protection | Tag protection rules |
| membership | Project and group memberships |
| labels | Label management |
| badges | Badge management |
| milestones | Milestone management |
| issues | Issue management |
| issue-board | Issue board management |
| variables | CI/CD variable management |
| pipeline-schedule | Pipeline schedule management |
| application | OAuth application management |
For a real-world usage example, see the IaC repository that manages this project's GitLab resources (groups, projects, labels, milestones, issues, badges, and GitHub mirror) using these modules.
Most features work with GitLab Free tier. Premium/Ultimate features are documented in each module's README.
| Feature | Free | Premium | Ultimate |
|---|---|---|---|
| Basic branch protection | ✓ | ✓ | ✓ |
| User/group-level branch permissions | ✓ | ✓ | |
| Basic tag protection | ✓ | ✓ | ✓ |
| User/group-level tag permissions | ✓ | ✓ | |
| Code owner approval | ✓ | ✓ | |
| Custom member roles | ✓ | ||
| Issue board assignee/iteration lists | ✓ | ✓ |
Set your GitLab token via environment variable:
export TF_VAR_gitlab_token="glpat-xxxxxxxxxxxx"Or use a .tfvars file (not recommended for sensitive data):
# terraform.tfvars
gitlab_token = "glpat-xxxxxxxxxxxx"| Scope | Required For |
|---|---|
api |
All operations |
read_api |
Read-only operations |
Note: The GitHub repository is a read-only mirror. All development, issues, and merge requests should be submitted on GitLab.
-
Install pre-commit:
pip install pre-commit
-
Install tflint:
curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash -
Install the pre-commit hooks:
pre-commit install
- Create a feature branch
- Make your changes
- Test with
tofu planandtofu applyin the relevant example directory - Pre-commit hooks will run automatically on
git commit - Submit a merge request
See LICENSE for details.