Skip to content

About

Terraform modules from DasMeta to manage GitLab resources

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

terraform-gitlab-project

Supported Configuration Paths

  • Choose exactly one namespace-selection path per project:
    • set namespace_id directly, or
    • set group_key to a declared gitlab_groups entry, or
    • omit both only when exactly one gitlab_groups entry exists and you want the implicit single-group fallback
  • Do not set namespace_id and group_key together on the same project.
  • Declare each gitlab_groups entry in one of two modes:
    • managed group: create = true with name and path
    • existing group reference: create = false with existing_group_id
  • Project env_variables override global_env_variables by key, and the project-level entry replaces the full shared definition for that key.
  • Project merge_requests_template can set a default merge request description template per GitLab project; omit it to leave that setting unmanaged.
  • projects_enabled = false skips projects and project-scoped child resources, but still allows managed groups to be created.
  • Field-level defaults, allowed values, and behavior notes now live inline next to the owning attributes in variables.tf instead of a separate shared project-field description block.
  • Existing consumers can keep using the documented single-group fallback; this clarification pass does not expand the module into runners, Kubernetes, or other unrelated GitLab platform areas.

Requirements

Name Version
terraform >= 1.3
gitlab ~> 19.0
helm >= 2.17.0
null ~> 3.2

Providers

No providers.

Modules

Name Source Version
ci_env_variables ./modules/ci_env_variables n/a
dynamic_environment ./modules/dynamic_environment n/a
gitlab_agent_config ./modules/gitlab_agent_config n/a
gitlab_ci_pipelines ./modules/gitlab_ci_pipelines n/a
gitlab_group ./modules/gitlab_group n/a
project ./modules/project n/a

Resources

No resources.

Inputs

Name Description Type Default Required
dynamic_environments_project Optional central GitLab project for dynamic environments orchestration.
When enabled, the module creates a project, generates orchestration files on
source_branch, and opens a merge request to default_branch. The applications
object renders to config/applications.yaml.
object({
enabled = optional(bool, false) # Create and configure the central dynamic environments project
name = optional(string) # Central project name; required when enabled
description = optional(string, "Dynamic environments orchestration") # Central project description
visibility_level = optional(string, "private") # private
internal public
default_branch = optional(string, "main") # Target and default branch for generated configuration
initialize_with_readme = optional(bool, true) # Initialize the central project with a README
namespace_id = optional(number) # Explicit GitLab namespace id for the central project
group_key = optional(string) # Resolve namespace through gitlab_groups[].key
source_branch = optional(string, "feature/dynamic-environments") # Source branch used for generated orchestration files
mr_title = optional(string, "Add dynamic environments orchestration") # Merge request title for orchestration changes
gitlab_api_url = optional(string, "https://gitlab.com/api/v4") # GitLab API base URL used by generated jobs
gitlab_agent_path = optional(string) # GitLab Agent context path used by generated CI
cluster_name = optional(string, "eks-dev") # Kubernetes cluster name used by deployment jobs
deploy_mode = optional(string, "aws_eks") # Deployment integration mode: aws_eks
gitlab_groups GitLab groups for this module (each entry needs a unique "key"). Each entry must be one of two supported modes:
- managed group: set create = true and provide name + path
- existing group reference: set create = false and provide existing_group_id

Projects may resolve their namespace through group_key, or by the implicit single-group fallback when exactly one
gitlab_groups entry exists. If this list is empty, every gitlab_projects item must set namespace_id directly.
list(object({
key = string # Stable id for wiring group_key on projects
create = optional(bool, false) # Create group via API for this entry
name = optional(string) # Display name (required if create is true)
path = optional(string) # URL path (required if create is true)
description = optional(string, "") # Group description
visibility_level = optional(string, "private") # private
internal public
parent_id = optional(number) # Parent namespace id for subgroups
existing_group_id = optional(number) # Existing GitLab group id (namespace id) when create is false; ignored when create is true
}))
gitlab_projects List of GitLab project configurations.

Supported namespace selection paths:
- set namespace_id directly
- set group_key to select an entry from var.gitlab_groups
- omit both namespace_id and group_key only when exactly one gitlab_groups entry exists; that single group is used implicitly

Do not set namespace_id and group_key together on the same project.
When gitlab_groups is empty, set namespace_id on every project.

Merge behavior (per project; GitLab UI under Settings → Merge requests):

squash_option — Squash commits when merging:
- never → Do not allow (squash disabled; checkbox hidden)
- default_off → Allow (checkbox visible, off by default)
- default_on → Encourage (checkbox visible, on by default)
- always → Require (always squash; user cannot disable)

merge_method — Merge method:
- merge → Create a merge commit
- rebase_merge → Merge commit with semi-linear history
- ff → Fast-forward merge

branch_protections — Optional list per project: Settings → Repository → Protected branches.
When omitted or set to [], this module creates one default protection for branch "main".
Access is set with merge_access_level / push_access_level / unprotect_access_level (maintainer, developer, admin, no one).
push_user_ids adds specific users who may push regardless of push_access_level, e.g. a release bot that commits
the changelog while push_access_level = "no one".

ci_delete_pipelines_in_seconds — CI/CD → General pipelines: pipelines older than this are deleted together with
their job logs and artifacts. Omit it to leave the project setting unmanaged by this module.

mr_approvals — Merge requests → Approval settings (gitlab_project_level_mr_approvals). Omit it to leave
the settings unmanaged; unset fields inside it keep their current GitLab value.

approval_rule — Optional per project. Accepts a list of approval rule objects.
When omitted or set to [], no project approval rule resources are created.
Defaults are name = "Approval rule", approvals_required = 1,
applies_to_all_protected_branches = false (user_ids / group_ids optional;
omit approver lists to use GitLab default approvers for the rule).

prevent_destroy — Contract hint for operators and downstream tooling only; this module does not set Terraform lifecycle { prevent_destroy } from this field (dynamic lifecycle is not supported for count/for_each resources in the same way as static blocks).

ci_pipeline_variables_minimum_override_role — CI/CD → Variables: minimum role that may run a new pipeline with pipeline variables (GitLab 17.1+).
Valid values: no_one_allowed, developer, maintainer, owner. Default in type: maintainer.

merge_requests_template — Merge requests: default description template for new merge requests in the project.
Omit this field to leave the project setting unmanaged by this module.

approval_rule — Optional per project. Accepts a list of approval rule objects.
If present and non-empty, the module creates one GitLab approval rule resource
per list entry. Defaults are name = "Approval rule", approvals_required = 1,
applies_to_all_protected_branches = false (user_ids / group_ids optional;
omit approver lists to use GitLab default approvers for the rule).

env_variables — Per-project CI/CD variables (gitlab_project_variable via module ci_env_variables), merged with
var.global_env_variables; the same key on the project replaces the full global variable definition for that project.

dynamic_environment — Per-project dynamic environment CI trigger generation. When enabled,
dynamic_environments_project.enabled must also be true.

gitlab_ci_pipelines — Optional per-project generated repository files under ci-pipelines/.
For type = "build", set pipeline target to "ecr" or "onprem". The module writes
ci-pipelines/build-gitlab.ci.yaml and all jobs in that pipeline use the selected template.
ECR jobs require aws_region and image_repository. On-premises jobs require registry_host and
image_repository; REGISTRY_USERNAME and REGISTRY_PASSWORD must be supplied through env_variables.
Legacy type = "build_ecr" remains supported without target.

For type = "deploy_agent", the module writes ci-pipelines/deploy.gitlab-ci.yml with one include of
the reusable GitLab Agent deploy template. Set jobs to generate multiple jobs in that file; each job
extends .deploy-agent and owns its variables. When jobs is omitted or empty, legacy job_name + variables
generates one deploy job. Set stop_environment.enabled = true on the pipeline or a job to generate paired
stop jobs, render environment.on_stop, and allow GitLab to stop ephemeral environments from Operate -> Environments.
jobs[].rules and stop_environment.rules support if, when, allow_failure, changes, exists, and start_in.
list(object({
name = string # Project name / slug key used by child resources
description = optional(string) # Project description
visibility_level = optional(string, "private") # private
internal public
default_branch = optional(string, "develop") # Initial default branch name
initialize_with_readme = optional(bool, true) # Create repository with README
request_access_enabled = optional(bool, true) # Allow users to request access
prevent_destroy = optional(bool, true) # Contract hint only; not mapped to Terraform lifecycle
namespace_id = optional(number) # Explicit GitLab namespace id for the project
group_key = optional(string) # Resolve namespace through gitlab_groups[].key
lfs_enabled = optional(bool, true) # Enable Git LFS for the project
packages_enabled = optional(bool, true) # Enable GitLab package registry
squash_option = optional(string, "default_on") # never
global_env_variables Environment variables applied to every GitLab project. Use for shared NPM_TOKEN, GITLAB_TOKEN, etc.
list(object({
key = string # CI/CD variable name
value = string # Variable value (use masked for secrets)
masked = optional(bool, false) # Hide value in job logs / UI where supported
protected = optional(bool, false) # Available only on protected branches/tags
}))
[] no
projects_enabled When false, skips creating GitLab projects and project-scoped child resources (for example CI variables). GitLab groups are still created when gitlab_groups[].create is true. bool true no

Outputs

Name Description
gitlab_group_full_paths Map of group key to full_path for groups created by this module (Terraform-managed only; existing groups referenced via existing_group_id are not listed here).
gitlab_group_ids Map of group key (from gitlab_groups) to namespace id for every resolvable configured group — managed groups contribute their created id and existing-group references require existing_group_id.
gitlab_project_ids Map of GitLab project name to project ID

Requirements

Name Version
terraform >= 1.3
gitlab ~> 19.0
helm >= 2.17.0
null ~> 3.2

Providers

No providers.

Modules

Name Source Version
ci_env_variables ./modules/ci_env_variables n/a
dynamic_environment ./modules/dynamic_environment n/a
gitlab_agent_config ./modules/gitlab_agent_config n/a
gitlab_ci_pipelines ./modules/gitlab_ci_pipelines n/a
gitlab_group ./modules/gitlab_group n/a
project ./modules/project n/a

Resources

No resources.

Inputs

Name Description Type Default Required
dynamic_environments_project Optional central GitLab project for dynamic environments orchestration.
When enabled, the module creates a project, generates orchestration files on
source_branch, and opens a merge request to default_branch. The applications
object renders to config/applications.yaml.
object({
enabled = optional(bool, false) # Create and configure the central dynamic environments project
name = optional(string) # Central project name; required when enabled
description = optional(string, "Dynamic environments orchestration") # Central project description
visibility_level = optional(string, "private") # private
internal public
default_branch = optional(string, "main") # Target and default branch for generated configuration
initialize_with_readme = optional(bool, true) # Initialize the central project with a README
namespace_id = optional(number) # Explicit GitLab namespace id for the central project
group_key = optional(string) # Resolve namespace through gitlab_groups[].key
source_branch = optional(string, "feature/dynamic-environments") # Source branch used for generated orchestration files
mr_title = optional(string, "Add dynamic environments orchestration") # Merge request title for orchestration changes
gitlab_api_url = optional(string, "https://gitlab.com/api/v4") # GitLab API base URL used by generated jobs
gitlab_agent_path = optional(string) # GitLab Agent context path used by generated CI
cluster_name = optional(string, "eks-dev") # Kubernetes cluster name used by deployment jobs
deploy_mode = optional(string, "aws_eks") # Deployment integration mode: aws_eks
gitlab_groups GitLab groups for this module (each entry needs a unique "key"). Each entry must be one of two supported modes:
- managed group: set create = true and provide name + path
- existing group reference: set create = false and provide existing_group_id

Projects may resolve their namespace through group_key, or by the implicit single-group fallback when exactly one
gitlab_groups entry exists. If this list is empty, every gitlab_projects item must set namespace_id directly.
list(object({
key = string # Stable id for wiring group_key on projects
create = optional(bool, false) # Create group via API for this entry
name = optional(string) # Display name (required if create is true)
path = optional(string) # URL path (required if create is true)
description = optional(string, "") # Group description
visibility_level = optional(string, "private") # private
internal public
parent_id = optional(number) # Parent namespace id for subgroups
existing_group_id = optional(number) # Existing GitLab group id (namespace id) when create is false; ignored when create is true
}))
gitlab_projects List of GitLab project configurations.

Supported namespace selection paths:
- set namespace_id directly
- set group_key to select an entry from var.gitlab_groups
- omit both namespace_id and group_key only when exactly one gitlab_groups entry exists; that single group is used implicitly

Do not set namespace_id and group_key together on the same project.
When gitlab_groups is empty, set namespace_id on every project.

Merge behavior (per project; GitLab UI under Settings → Merge requests):

squash_option — Squash commits when merging:
- never → Do not allow (squash disabled; checkbox hidden)
- default_off → Allow (checkbox visible, off by default)
- default_on → Encourage (checkbox visible, on by default)
- always → Require (always squash; user cannot disable)

merge_method — Merge method:
- merge → Create a merge commit
- rebase_merge → Merge commit with semi-linear history
- ff → Fast-forward merge

branch_protections — Optional list per project: Settings → Repository → Protected branches.
When omitted or set to [], this module creates one default protection for branch "main".
Access is set with merge_access_level / push_access_level / unprotect_access_level (maintainer, developer, admin, no one).
push_user_ids adds specific users who may push regardless of push_access_level, e.g. a release bot that commits
the changelog while push_access_level = "no one".

ci_delete_pipelines_in_seconds — CI/CD → General pipelines: pipelines older than this are deleted together with
their job logs and artifacts. Omit it to leave the project setting unmanaged by this module.

mr_approvals — Merge requests → Approval settings (gitlab_project_level_mr_approvals). Omit it to leave
the settings unmanaged; unset fields inside it keep their current GitLab value.

approval_rule — Optional per project. Accepts a list of approval rule objects.
When omitted or set to [], no project approval rule resources are created.
Defaults are name = "Approval rule", approvals_required = 1,
applies_to_all_protected_branches = false (user_ids / group_ids optional;
omit approver lists to use GitLab default approvers for the rule).

prevent_destroy — Contract hint for operators and downstream tooling only; this module does not set Terraform lifecycle { prevent_destroy } from this field (dynamic lifecycle is not supported for count/for_each resources in the same way as static blocks).

ci_pipeline_variables_minimum_override_role — CI/CD → Variables: minimum role that may run a new pipeline with pipeline variables (GitLab 17.1+).
Valid values: no_one_allowed, developer, maintainer, owner. Default in type: maintainer.

merge_requests_template — Merge requests: default description template for new merge requests in the project.
Omit this field to leave the project setting unmanaged by this module.

approval_rule — Optional per project. Accepts a list of approval rule objects.
If present and non-empty, the module creates one GitLab approval rule resource
per list entry. Defaults are name = "Approval rule", approvals_required = 1,
applies_to_all_protected_branches = false (user_ids / group_ids optional;
omit approver lists to use GitLab default approvers for the rule).

env_variables — Per-project CI/CD variables (gitlab_project_variable via module ci_env_variables), merged with
var.global_env_variables; the same key on the project replaces the full global variable definition for that project.

dynamic_environment — Per-project dynamic environment CI trigger generation. When enabled,
dynamic_environments_project.enabled must also be true.

gitlab_ci_pipelines — Optional per-project generated repository files under ci-pipelines/.
For type = "build", set pipeline target to "ecr" or "onprem". The module writes
ci-pipelines/build-gitlab.ci.yaml and all jobs in that pipeline use the selected template.
ECR jobs require aws_region and image_repository. On-premises jobs require registry_host and
image_repository; REGISTRY_USERNAME and REGISTRY_PASSWORD must be supplied through env_variables.
Legacy type = "build_ecr" remains supported without target.

For type = "deploy_agent", the module writes ci-pipelines/deploy.gitlab-ci.yml with one include of
the reusable GitLab Agent deploy template. Set jobs to generate multiple jobs in that file; each job
extends .deploy-agent and owns its variables. When jobs is omitted or empty, legacy job_name + variables
generates one deploy job. Set stop_environment.enabled = true on the pipeline or a job to generate paired
stop jobs, render environment.on_stop, and allow GitLab to stop ephemeral environments from Operate -> Environments.
jobs[].rules and stop_environment.rules support if, when, allow_failure, changes, exists, and start_in.
list(object({
name = string # Project name / slug key used by child resources
description = optional(string) # Project description
visibility_level = optional(string, "private") # private
internal public
default_branch = optional(string, "develop") # Initial default branch name
initialize_with_readme = optional(bool, true) # Create repository with README
request_access_enabled = optional(bool, true) # Allow users to request access
prevent_destroy = optional(bool, true) # Contract hint only; not mapped to Terraform lifecycle
namespace_id = optional(number) # Explicit GitLab namespace id for the project
group_key = optional(string) # Resolve namespace through gitlab_groups[].key
lfs_enabled = optional(bool, true) # Enable Git LFS for the project
packages_enabled = optional(bool, true) # Enable GitLab package registry
squash_option = optional(string, "default_on") # never
global_env_variables Environment variables applied to every GitLab project. Use for shared NPM_TOKEN, GITLAB_TOKEN, etc.
list(object({
key = string # CI/CD variable name
value = string # Variable value (use masked for secrets)
masked = optional(bool, false) # Hide value in job logs / UI where supported
protected = optional(bool, false) # Available only on protected branches/tags
}))
[] no
projects_enabled When false, skips creating GitLab projects and project-scoped child resources (for example CI variables). GitLab groups are still created when gitlab_groups[].create is true. bool true no

Outputs

Name Description
gitlab_group_full_paths Map of group key to full_path for groups created by this module (Terraform-managed only; existing groups referenced via existing_group_id are not listed here).
gitlab_group_ids Map of group key (from gitlab_groups) to namespace id for every resolvable configured group — managed groups contribute their created id and existing-group references require existing_group_id.
gitlab_project_ids Map of GitLab project name to project ID

About

Terraform modules from DasMeta to manage GitLab resources

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages