Modificare il modulo per gestire il comportamento del GitLab agent in modo diverso a seconda che si operi a livello di root group o meno, semplificando la configurazione con un toggle unico e introducendo comportamenti automatici intelligenti.
- Rimuovere le variabili separate:
gitlab_agent_grant_access_to_entire_root_namespacegitlab_agent_create_variables_in_root_namespace
- Introdurre una nuova variabile booleana unica (es.
operate_at_root_group_levelois_root_group_scope)
Quando operate_at_root_group_level == true:
- File di configurazione automaticamente gestito
- Variabili CI/CD create sul root group
- Comportamento identico all'attuale implementazione
Quando operate_at_root_group_level == false:
Se length(concat(groups_enabled, projects_enabled)) == 0:
- Recuperare automaticamente il parent DIRETTO del progetto specificato in
gitlab_project_path_with_namespace - Trattare questo parent come l'UNICO elemento di
groups_enabled - Nota: Il parent potrebbe essere un root group - verificare e gestire questo caso
Se sono specificati gruppi o progetti:
- Creare file di configurazione solo per quei gruppi/progetti specifici
- Creare variabili CI/CD in quei gruppi/progetti specifici (non nel root)
gitlab_agent_grant_access_to_entire_root_namespacegitlab_agent_create_variables_in_root_namespace
variable "operate_at_root_group_level" {
description = "Operate at root group level. If true, grants access to entire root namespace and creates variables in root group. If false, behavior depends on groups_enabled and projects_enabled."
type = bool
default = true
}
variable "groups_enabled" {
description = "List of group IDs or paths where the GitLab Agent should be enabled. Only used when operate_at_root_group_level is false. If empty and projects_enabled is also empty, the parent group of the agent project will be used automatically."
type = list(string)
default = []
}
variable "projects_enabled" {
description = "List of project IDs or paths where the GitLab Agent should be enabled. Only used when operate_at_root_group_level is false. If empty and groups_enabled is also empty, the parent group of the agent project will be used automatically."
type = list(string)
default = []
}- Verificare coerenza tra
operate_at_root_group_levele uso digitlab_agent_custom_config_file_content - Validare che gruppi/progetti specificati esistano (dove possibile)
# Determina il parent group del progetto
parent_group_path = join("/", slice(split("/", var.gitlab_project_path_with_namespace), 0, length(split("/", var.gitlab_project_path_with_namespace)) - 1))
# Determina se siamo in modalità auto-parent
auto_detect_parent = !var.operate_at_root_group_level && length(concat(var.groups_enabled, var.projects_enabled)) == 0
# Lista finale di gruppi da abilitare
groups_to_enable = var.operate_at_root_group_level ? [local.project_root_namespace] : (
local.auto_detect_parent ? [local.parent_group_path] : var.groups_enabled
)
# Lista finale di progetti da abilitare
projects_to_enable = var.operate_at_root_group_level ? [] : (
local.auto_detect_parent ? [] : var.projects_enabled
)# final_configuration_file_content
# Deve essere modificato per gestire:
# - Root group: comportamento attuale (template con root_namespace)
# - Non-root con gruppi/progetti: generare config dinamico con yamlencode() o nuovo template
# - Considerare se mantenerlo vuoto quando custom_config è specificatodata "gitlab_group" "parent_group" {
count = local.auto_detect_parent ? 1 : 0
full_path = local.parent_group_path
}data "gitlab_group" "enabled_groups" {
for_each = !var.operate_at_root_group_level ? toset(var.groups_enabled) : toset([])
full_path = each.value
}data "gitlab_project" "enabled_projects" {
for_each = !var.operate_at_root_group_level ? toset(var.projects_enabled) : toset([])
path_with_namespace = each.value
}- Mantenere la logica attuale per root group
- Per non-root-group: generare il file solo se ci sono gruppi/progetti da abilitare
- Modificare il contenuto in base ai gruppi/progetti target
Sostituire con logica condizionale:
# Variabili per root group (comportamento attuale)
resource "gitlab_group_variable" "root_namespace" {
for_each = var.operate_at_root_group_level ? local.gitlab_agent_kubernetes_context_variables : {}
# ... resto della configurazione
}
# Variabili per gruppi specifici (non-root-group)
resource "gitlab_group_variable" "enabled_groups" {
for_each = !var.operate_at_root_group_level && length(local.groups_to_enable) > 0 ? {
for pair in setproduct(keys(local.gitlab_agent_kubernetes_context_variables), local.groups_to_enable) :
"${pair[1]}_${pair[0]}" => {
group = pair[1]
key = pair[0]
value = local.gitlab_agent_kubernetes_context_variables[pair[0]]
}
} : {}
# ... resto della configurazione
}
# Variabili per progetti specifici (non-root-group)
resource "gitlab_project_variable" "enabled_projects" {
for_each = !var.operate_at_root_group_level && length(local.projects_to_enable) > 0 ? {
for pair in setproduct(keys(local.gitlab_agent_kubernetes_context_variables), local.projects_to_enable) :
"${pair[1]}_${pair[0]}" => {
project = pair[1]
key = pair[0]
value = local.gitlab_agent_kubernetes_context_variables[pair[0]]
}
} : {}
# ... resto della configurazione
}Creare files/config-custom.yaml.tftpl per gestire gruppi/progetti specifici:
ci_access:
%{~ if length(groups) > 0 }
groups:
%{~ for group in groups }
- id: ${group}
%{~ endfor }
%{~ endif }
%{~ if length(projects) > 0 }
projects:
%{~ for project in projects }
- id: ${project}
%{~ endfor }
%{~ endif }Usare yamlencode() per generare dinamicamente il contenuto:
local.final_configuration_file_content = var.operate_at_root_group_level ?
templatefile("${path.module}/files/config.yaml.tftpl", {...}) :
yamlencode({
ci_access = {
groups = [for g in local.groups_to_enable : { id = g }]
projects = [for p in local.projects_to_enable : { id = p }]
}
})output "gitlab_root_namespace_id" {
description = "The ID of the root namespace of the Gitlab Agents project. Only available when operate_at_root_group_level is true."
value = var.operate_at_root_group_level ? data.gitlab_group.root_namespace.group_id : null
}output "gitlab_enabled_groups" {
description = "List of groups where the GitLab Agent has been enabled with variables."
value = local.groups_to_enable
}
output "gitlab_enabled_projects" {
description = "List of projects where the GitLab Agent has been enabled with variables."
value = local.projects_to_enable
}
output "gitlab_parent_group_auto_detected" {
description = "Whether the parent group was automatically detected."
value = local.auto_detect_parent
}- Attenzione: Il parsing del path deve gestire correttamente:
- Progetti nel root group:
root-group/project→ parent =root-group - Progetti in sottogruppi:
root/subgroup1/subgroup2/project→ parent =root/subgroup1/subgroup2
- Progetti nel root group:
- Validazione: Verificare che il parent esista prima di procedere
- Se il parent risulta essere un root group, il comportamento dovrebbe essere coerente
- Valutare se forzare
operate_at_root_group_level = truein questo caso o gestirlo normalmente
Opzioni:
- Breaking change: Rimuovere completamente le vecchie variabili (richiede major version bump)
- Deprecazione: Mantenere le vecchie variabili con warning, mappandole alle nuove
- Migrazione automatica: Creare locals che traducono vecchia configurazione → nuova
Raccomandazione: Considerare un major version bump con breaking change per semplificare il codice.
Preferenza: Usare yamlencode() per maggiore flessibilità e manutenibilità rispetto ai template, a meno che non si voglia mantenere il supporto per gitlab_agent_append_to_config_file.
- Usare data source per validare l'esistenza di gruppi/progetti specificati
- Gestire errori in modo chiaro se path non esistono
- Attualmente
gitlab_agent_grant_user_access_to_root_namespacesi applica solo al root namespace - Valutare se estendere questa funzionalità anche a gruppi/progetti specifici
- Aggiungere nuove variabili (
operate_at_root_group_level,groups_enabled,projects_enabled) - Aggiungere locals per logica condizionale e parsing parent
- Aggiungere data sources per gruppi/progetti
- Modificare generazione config file con logica condizionale
- Sostituire risorse variabili con nuova logica multi-target
- Aggiornare outputs
- Aggiungere validazioni
- Testing completo di tutti gli scenari
- Deprecare vecchie variabili (se si sceglie quel percorso)
- Aggiornare documentazione (README.md)
operate_at_root_group_level = true
# groups_enabled e projects_enabled ignoratiAspettativa: File su root namespace, variabili su root group
operate_at_root_group_level = false
groups_enabled = []
projects_enabled = []
gitlab_project_path_with_namespace = "root-group/subgroup/project"Aspettativa: Parent = "root-group/subgroup", file e variabili su quel gruppo
operate_at_root_group_level = false
groups_enabled = ["group1", "group2/subgroup"]
projects_enabled = []Aspettativa: File con access a group1 e group2/subgroup, variabili in entrambi
operate_at_root_group_level = false
groups_enabled = []
projects_enabled = ["org/project1", "org/project2"]Aspettativa: File con access a project1 e project2, variabili in entrambi
operate_at_root_group_level = false
groups_enabled = ["group1"]
projects_enabled = ["org/project1"]Aspettativa: File con access a group1 e project1, variabili in entrambi
operate_at_root_group_level = false
groups_enabled = []
projects_enabled = []
gitlab_project_path_with_namespace = "root-group/project"Aspettativa: Parent = "root-group" (che è root), comportamento da definire
Questa specifica fornisce una roadmap completa per l'implementazione. Prima di iniziare il coding:
- Decidere la strategia di backward compatibility
- Scegliere tra template vs
yamlencode()per config generation - Definire comportamento esatto quando parent è root group
- Preparare esempi e test cases
- Pianificare versioning (major bump vs minor/patch)