Secrets Manager: Support GitLab Terraform Provider
### Problem to solve: GitLab Secrets Manager currently has no support for the GitLab Terraform provider, meaning teams that manage infrastructure as code (IaC) cannot create, read, or manage secrets programmatically through Terraform. This forces DevOps and Infrastructure Engineers to manage secrets through the UI or API manually, breaking IaC workflows and creating inconsistency in how secrets are provisioned across environments. ##### Target Personas DevOps Engineer / Platform Engineer: provisions secrets for CI/CD pipelines via IaC; manages secrets across multiple environments (dev, staging, prod); integrates secrets management with infrastructure as code. ### Proposed Solution Add support for resources and data source to [GitLab Terraform Provider](https://registry.terraform.io/providers/gitlabhq/gitlab/18.9.0) to support GitLab Secrets Manager | Capability | Scope | Description | |------------|-------|-------------| | `gitlab_project_secret` resource | Project | Create, update, delete a secret scoped to a project | | `gitlab_group_secret` resource | Group | Create, update, delete a secret scoped to a group | | `gitlab_project_secret` data source | Project | Read a secret value scoped to a specific project | | `gitlab_group_secret` data source | Group | Read a secret value scoped to a group | * Support current values during creation process * Support "sensitive=true" with Terraform to redact values. * Instructions on using a Service Account to retrieve secrets with specific permissions <details> <summary>Terraform Example</summary> ```hcl # ============================================================ # GROUP-LEVEL SECRETS # ============================================================ # Shared secret available to all projects in the org resource "gitlab_group_secret" "stripe_api_key" { group = "my-org/platform-team" name = "STRIPE_API_KEY" value = var.stripe_api_key_prod } # Database password shared across all backend services resource "gitlab_group_secret" "shared_db_password" { group = "my-org/platform-team" name = "DB_PASSWORD" value = var.db_password } # ============================================================ # PROJECT-LEVEL SECRETS # ============================================================ # payments-service uses a different Stripe key (staging override) resource "gitlab_project_secret" "payments_stripe_key" { project = "my-org/platform-team/payments-service" name = "STRIPE_API_KEY" value = var.stripe_api_key_staging } # Project-specific secret with no group-level equivalent resource "gitlab_project_secret" "payments_webhook_secret" { project = "my-org/platform-team/payments-service" name = "STRIPE_WEBHOOK_SECRET" value = "whsec_xyz789" } # ============================================================ # DATA SOURCES # Read existing secrets for use in other resources # ============================================================ # Read a group-level secret data "gitlab_group_secret" "read_db_password" { group = "my-org/platform-team" name = "DB_PASSWORD" } # Read a project-level secret data "gitlab_project_secret" "read_webhook_secret" { project = "my-org/platform-team/payments-service" name = "STRIPE_WEBHOOK_SECRET" } # ============================================================ # REFERENCE SECRETS IN OTHER RESOURCES # ============================================================ resource "aws_postgres..." "db_url" { username = ... password = "postgresql://app:${data.gitlab_group_secret.read_db_password.value}@db.internal:5432/payments" } # ============================================================ # OUTPUTS # Never output raw secret values — reference them by ID only # ============================================================ output "stripe_secret_id" { description = "Resource ID of the group-level Stripe secret" value = gitlab_group_secret.stripe_api_key.id } output "payments_webhook_secret_id" { description = "Resource ID of the payments webhook secret" value = gitlab_project_secret.payments_webhook_secret.id } ``` </details>
epic