From 72ca360719ea6a72516cd35935b18ef598608c76 Mon Sep 17 00:00:00 2001 From: wiseelf Date: Tue, 7 Jul 2026 17:35:42 +1000 Subject: [PATCH 1/2] fix: Derive managed_group_paths from var.gitlab_groups, not resource keys managed_group_paths referenced keys(gitlab_group.parent_groups) and keys(gitlab_group.subgroups), which feeds into referenced_group_paths and therefore data.gitlab_group.referenced's for_each. Referencing a resource address there makes the for_each depend on that resource being planned first, which breaks operations that don't plan the whole graph up front -- notably terraform import, which fails with 'Invalid for_each argument: known only after apply' even though the underlying value never actually depends on anything computed. Compute the same key set (group.name, or parent/name for subgroups) directly from var.gitlab_groups instead, mirroring the gitlab_group.parent_groups/ subgroups for_each expressions without referencing those resources. Makes managed_group_paths a pure function of input variables, safe for import, plan, and apply alike. Verified via terraform console that referenced_group_ paths now resolves to a fully known set instead of known-after-apply. --- main.tf | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index e967baa..33172c3 100644 --- a/main.tf +++ b/main.tf @@ -523,7 +523,15 @@ locals { # Group full_paths managed by this module invocation, excluded from the external # group lookup below since they don't exist yet at plan time for a brand-new group. - managed_group_paths = toset(concat(keys(gitlab_group.parent_groups), keys(gitlab_group.subgroups))) + # Derived straight from var.gitlab_groups (mirroring the gitlab_group.parent_groups/ + # subgroups for_each keys below) rather than keys(gitlab_group.*): referencing the + # resource itself makes data.gitlab_group.referenced's for_each depend on resource + # attributes, which breaks operations that don't plan the whole graph first, such + # as `terraform import`. + managed_group_paths = toset([ + for group in var.gitlab_groups : + contains(keys(group), "parent") ? "${group.parent}/${group.name}" : group.name + ]) # Same rationale as referenced_user_emails: look up exactly the group full_paths # this config references, instead of paging through every group on the instance. From 5d6c3df06ffd75cd753623026895303c7961f6c3 Mon Sep 17 00:00:00 2001 From: wiseelf Date: Tue, 7 Jul 2026 17:46:25 +1000 Subject: [PATCH 2/2] fix: Ignore ref changes on gitlab_branch to prevent destroy/recreate ref is only populated in state at creation time; the provider has no way to read it back for an existing branch. After import (or for a branch that has since diverged from its original ref), state has ref unset while config still declares it, and since ref is ForceNew, Terraform plans to destroy and recreate the branch -- discarding its actual commit history. This is exactly what the provider's own docs recommend guarding against. Add lifecycle { ignore_changes = [ref] } to gitlab_branch.this. --- main.tf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main.tf b/main.tf index 33172c3..8a09482 100644 --- a/main.tf +++ b/main.tf @@ -1363,6 +1363,15 @@ resource "gitlab_branch" "this" { name = each.value.branch.name project = gitlab_project.this["${each.value.project_namespace}/${each.value.project_name}"].id ref = each.value.branch.ref + + # ref is only populated in state on creation; the provider can't read it back + # (GitLab has no "ref" concept for an existing branch). Without this, importing + # an existing branch or a branch that has since diverged leaves ref unset in + # state, and since ref is ForceNew, the next plan destroys and recreates the + # branch, discarding its real commit history. + lifecycle { + ignore_changes = [ref] + } } # Create GitLab Branch Protection for Protected Branches