mirror of
https://gitlab.sarex.io/infra/terraform-contour-mirror.git
synced 2026-10-07 13:51:36 +03:00
136 lines
6.5 KiB
HCL
136 lines
6.5 KiB
HCL
# Единственное место загрузки контракта сервисов (environments/<env>/*.yaml).
|
||
#
|
||
# Файл называется config.hcl, а НЕ terragrunt.hcl, намеренно: и
|
||
# scripts/run_all_stacks.sh, и scripts/generate-pipeline.sh ищут юниты строго по
|
||
# имени terragrunt.hcl, поэтому этот файл юнитом не считается и сам по себе не
|
||
# прогоняется.
|
||
#
|
||
# Стеки подключают его через read_terragrunt_config() и берут local.<...>.
|
||
# Именно read_terragrunt_config, а не dependency: dependency не виден из блока
|
||
# locals, и попытка протащить компилятор через него уже роняла пайплайн.
|
||
#
|
||
# Окружение считается переехавшим на новый формат, только если у него есть
|
||
# environments/<env>/environment.yaml. Для остальных контуров всё ниже
|
||
# вырождается в пустые списки, и concat на стороне стеков становится
|
||
# тождественной операцией.
|
||
|
||
locals {
|
||
repo_root = try(get_repo_root(), "${get_terragrunt_dir()}/../..")
|
||
|
||
infra_config = yamldecode(file("${local.repo_root}/infrastructure.yaml"))
|
||
env_override = trimspace(get_env("INFRA_ENV", ""))
|
||
env_from_file = try(trimspace(local.infra_config.current_environment), "")
|
||
env_name = local.env_override != "" ? local.env_override : (
|
||
local.env_from_file != "" ? local.env_from_file : try(sort(keys(try(local.infra_config.environments, {})))[0], "")
|
||
)
|
||
|
||
env_dir = "${local.repo_root}/environments/${local.env_name}"
|
||
|
||
# try(), а не тернарник по fileexists: в HCL обе ветки тернарника обязаны
|
||
# иметь совместимые типы, а пустой объект против объекта с backends их не
|
||
# имеет - "Inconsistent conditional result types".
|
||
environment = try(yamldecode(file("${local.env_dir}/environment.yaml")), {})
|
||
namespaces = try(yamldecode(file("${local.env_dir}/namespaces.yaml")).namespaces, {})
|
||
|
||
service_files = try(fileset(local.env_dir, "services/*.yaml"), [])
|
||
services = {
|
||
for f in local.service_files :
|
||
trimsuffix(basename(f), ".yaml") => yamldecode(file("${local.env_dir}/${f}"))
|
||
}
|
||
|
||
registry = try(local.environment.registry, null)
|
||
credentials_ref = try(local.registry.credentials_ref, "")
|
||
|
||
# ── вывод сущностей из имени сервиса ───────────────────────────────────────
|
||
# vhosts пуст -> [<service>]; первый vhost основной, его секрет зовётся просто
|
||
# rabbitmq, остальные получают суффикс - хвост после "<service>-".
|
||
service_vhosts = {
|
||
for name, svc in local.services :
|
||
name => length(try(svc.needs.rabbitmq.vhosts, [])) > 0 ? svc.needs.rabbitmq.vhosts : [name]
|
||
if try(svc.needs.rabbitmq, null) != null
|
||
}
|
||
|
||
# сервис размещён во всех namespace, где он перечислен в services[]
|
||
service_namespaces = {
|
||
for name, _ in local.services :
|
||
name => sort([for ns_key, ns in local.namespaces : ns_key if contains(try(ns.services, []), name)])
|
||
}
|
||
|
||
# ── inputs для modules/k8s-namespace ───────────────────────────────────────
|
||
namespaces_input = [
|
||
for ns_key, ns in local.namespaces : {
|
||
name = ns_key
|
||
labels = try(ns.labels, {})
|
||
annotations = try(ns.annotations, {})
|
||
manage = try(ns.manage, true)
|
||
image_pull_secret = try(ns.image_pull_secret, true)
|
||
}
|
||
]
|
||
|
||
# ── inputs для modules/rabbitmq ────────────────────────────────────────────
|
||
rabbitmq_vhosts = [
|
||
for v in sort(distinct(flatten([for _, vhosts in local.service_vhosts : vhosts]))) : { name = v }
|
||
]
|
||
|
||
rabbitmq_users = [
|
||
for name, _ in local.service_vhosts : { name = name, password_length = 32, password_special = false }
|
||
]
|
||
|
||
# владелец получает полные права в каждом своём vhost
|
||
rabbitmq_permissions = flatten([
|
||
for name, vhosts in local.service_vhosts : [
|
||
for v in vhosts : { user = name, vhost = v, configure = ".*", write = ".*", read = ".*" }
|
||
]
|
||
])
|
||
|
||
# ── секреты в форме v2-контракта ───────────────────────────────────────────
|
||
# Отдаём именно записи с targets, а не плоский список: live/secrets вливает их
|
||
# ДО собственного разбора v2, поэтому вся его машинерия (валидация ключей,
|
||
# вывод type из source.kind, разворачивание targets) работает без изменений.
|
||
secret_prefix = {
|
||
for name, _ in local.services : name => join("", [
|
||
for ns_key in local.service_namespaces[name] :
|
||
try(local.namespaces[ns_key].secret_prefix, "") == "service" ? "${name}-" : ""
|
||
])
|
||
}
|
||
|
||
rabbitmq_secrets = flatten([
|
||
for name, vhosts in local.service_vhosts : [
|
||
for ns_key in local.service_namespaces[name] : [
|
||
for idx, v in vhosts : {
|
||
id = "${name}-rabbitmq-${ns_key}-${v}"
|
||
schema = "rabbitmq.v1"
|
||
namespace = ns_key
|
||
ownership = "managed"
|
||
source = {
|
||
kind = "rabbitmq_user"
|
||
ref = { vhost = v, user = name }
|
||
}
|
||
targets = [{
|
||
kind = "kubernetes"
|
||
namespace = ns_key
|
||
name = "${try(local.namespaces[ns_key].secret_prefix, "") == "service" ? "${name}-" : ""}rabbitmq${idx == 0 ? "" : "-${trimprefix(v, "${name}-")}"}"
|
||
}]
|
||
}
|
||
]
|
||
]
|
||
])
|
||
|
||
regcred_secrets = local.credentials_ref == "" ? [] : [
|
||
for ns_key, ns in local.namespaces : {
|
||
id = "${ns_key}-regcred"
|
||
schema = "dockerconfigjson.v1"
|
||
namespace = ns_key
|
||
ownership = "referenced"
|
||
source = {
|
||
kind = "secret_ref"
|
||
ref = local.credentials_ref
|
||
}
|
||
targets = [{ kind = "kubernetes", namespace = ns_key, name = "regcred" }]
|
||
}
|
||
if try(ns.image_pull_secret, true)
|
||
]
|
||
|
||
secrets_v2 = concat(local.regcred_secrets, local.rabbitmq_secrets)
|
||
}
|