Populate terragrunt-enc: encapi ENC data as code
ci/woodpecker/pr/plan Pipeline failed
ci/woodpecker/pr/pre-commit Pipeline was successful

terragrunt-enc is the single source of truth for encapi ENC data (Puppet
statuses, roles, and node classifications), managed with Terraform/Terragrunt.
It supersedes Cobbler classification for Puppet and the terraform-incus
dual-write prototype (PR #39).

- Add modules/encapi (encapi_status / encapi_role / encapi_node, nodes
  FK-ordered after their role and status).
- Add config/encapi leaf: 3 statuses, 51 roles, and 143 node assignments
  (130 container VMs env production + 13 prodnxsr physicals env develop),
  all YAML-driven.
- Add config/root.hcl (consul backend infra/terraform/enc/<leaf>/state) and
  the encapi provider from the artifactapi registry (v0.1.0).
- Add Makefile, Woodpecker pre-commit/plan/apply pipelines, pre-commit
  config, ci/extract_incus_nodes.py, and expand the README.
This commit is contained in:
Ben Vincent
2026-07-24 23:12:03 +10:00
parent 1e01bc9673
commit 054110d748
17 changed files with 908 additions and 1 deletions
+444
View File
@@ -0,0 +1,444 @@
# encapi node classifications.
#
# 130 container VMs (environment=production): extracted from
# terraform-incus config/instances/<host>/config.yaml. certname is
# <host>.main.unkin.net (dir basename + cobbler_domain), role is
# cobbler_mgmt_classes[0] (defaulting to roles::base if absent). See
# ci/extract_incus_nodes.py, which regenerates this section.
#
# 13 prodnxsr* physical hypervisor/k8s nodes (environment=develop): NOT
# managed by the incus instance module; roles come from the PuppetDB
# enc_role fact. Maintained by hand below.
# --- container VMs (production) ---
ausyd1nxvm2000.main.unkin.net:
role: roles::infra::storage::vault
environment: production
ausyd1nxvm2001.main.unkin.net:
role: roles::infra::storage::vault
environment: production
ausyd1nxvm2002.main.unkin.net:
role: roles::infra::storage::vault
environment: production
ausyd1nxvm2003.main.unkin.net:
role: roles::infra::storage::vault
environment: production
ausyd1nxvm2004.main.unkin.net:
role: roles::infra::storage::vault
environment: production
ausyd1nxvm2005.main.unkin.net:
role: roles::infra::storage::consul
environment: production
ausyd1nxvm2006.main.unkin.net:
role: roles::infra::storage::consul
environment: production
ausyd1nxvm2007.main.unkin.net:
role: roles::infra::storage::consul
environment: production
ausyd1nxvm2008.main.unkin.net:
role: roles::infra::storage::consul
environment: production
ausyd1nxvm2009.main.unkin.net:
role: roles::infra::storage::consul
environment: production
ausyd1nxvm2010.main.unkin.net:
role: roles::infra::puppetdb::api
environment: production
ausyd1nxvm2011.main.unkin.net:
role: roles::infra::puppetdb::api
environment: production
ausyd1nxvm2012.main.unkin.net:
role: roles::infra::puppetdb::api
environment: production
ausyd1nxvm2013.main.unkin.net:
role: roles::infra::puppetboard::server
environment: production
ausyd1nxvm2014.main.unkin.net:
role: roles::infra::puppetboard::server
environment: production
ausyd1nxvm2015.main.unkin.net:
role: roles::infra::metrics::grafana
environment: production
ausyd1nxvm2016.main.unkin.net:
role: roles::infra::metrics::grafana
environment: production
ausyd1nxvm2017.main.unkin.net:
role: roles::infra::auth::glauth
environment: production
ausyd1nxvm2018.main.unkin.net:
role: roles::infra::auth::glauth
environment: production
ausyd1nxvm2019.main.unkin.net:
role: roles::infra::auth::glauth
environment: production
ausyd1nxvm2020.main.unkin.net:
role: roles::infra::proxy::jumphost
environment: production
ausyd1nxvm2021.main.unkin.net:
role: roles::infra::proxy::jumphost
environment: production
ausyd1nxvm2022.main.unkin.net:
role: roles::infra::proxy::jumphost
environment: production
ausyd1nxvm2023.main.unkin.net:
role: roles::infra::git::runner
environment: production
ausyd1nxvm2024.main.unkin.net:
role: roles::infra::git::runner
environment: production
ausyd1nxvm2025.main.unkin.net:
role: roles::infra::git::runner
environment: production
ausyd1nxvm2026.main.unkin.net:
role: roles::infra::nomad::server
environment: production
ausyd1nxvm2027.main.unkin.net:
role: roles::infra::nomad::server
environment: production
ausyd1nxvm2028.main.unkin.net:
role: roles::infra::nomad::server
environment: production
ausyd1nxvm2029.main.unkin.net:
role: roles::infra::dns::master
environment: production
ausyd1nxvm2030.main.unkin.net:
role: roles::infra::dns::master
environment: production
ausyd1nxvm2031.main.unkin.net:
role: roles::infra::dns::master
environment: production
ausyd1nxvm2032.main.unkin.net:
role: roles::infra::dns::resolver
environment: production
ausyd1nxvm2033.main.unkin.net:
role: roles::infra::dns::resolver
environment: production
ausyd1nxvm2034.main.unkin.net:
role: roles::infra::dns::resolver
environment: production
ausyd1nxvm2035.main.unkin.net:
role: roles::apps::music::gonic
environment: production
ausyd1nxvm2036.main.unkin.net:
role: roles::apps::music::gonic
environment: production
ausyd1nxvm2037.main.unkin.net:
role: roles::apps::music::gonic
environment: production
ausyd1nxvm2038.main.unkin.net:
role: roles::infra::metrics::prometheus
environment: production
ausyd1nxvm2039.main.unkin.net:
role: roles::infra::metrics::prometheus
environment: production
ausyd1nxvm2040.main.unkin.net:
role: roles::infra::nomad::agentv2
environment: production
ausyd1nxvm2041.main.unkin.net:
role: roles::infra::nomad::agentv2
environment: production
ausyd1nxvm2042.main.unkin.net:
role: roles::infra::nomad::agentv2
environment: production
ausyd1nxvm2043.main.unkin.net:
role: roles::infra::nomad::agentv2
environment: production
ausyd1nxvm2044.main.unkin.net:
role: roles::infra::nomad::agentv2
environment: production
ausyd1nxvm2045.main.unkin.net:
role: roles::apps::media::nzbget
environment: production
ausyd1nxvm2046.main.unkin.net:
role: roles::apps::media::sonarr
environment: production
ausyd1nxvm2047.main.unkin.net:
role: roles::apps::media::radarr
environment: production
ausyd1nxvm2048.main.unkin.net:
role: roles::apps::media::lidarr
environment: production
ausyd1nxvm2049.main.unkin.net:
role: roles::apps::media::readarr
environment: production
ausyd1nxvm2050.main.unkin.net:
role: roles::apps::media::prowlarr
environment: production
ausyd1nxvm2051.main.unkin.net:
role: roles::apps::media::jellyfin
environment: production
ausyd1nxvm2052.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2053.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2054.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2055.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2056.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2057.main.unkin.net:
role: roles::infra::pki::certbot
environment: production
ausyd1nxvm2058.main.unkin.net:
role: roles::infra::reposync::syncer
environment: production
ausyd1nxvm2059.main.unkin.net:
role: roles::infra::reposync::repo
environment: production
ausyd1nxvm2060.main.unkin.net:
role: roles::infra::reposync::repo
environment: production
ausyd1nxvm2061.main.unkin.net:
role: roles::infra::reposync::repo
environment: production
ausyd1nxvm2062.main.unkin.net:
role: roles::infra::incus::imagehost
environment: production
ausyd1nxvm2063.main.unkin.net:
role: roles::infra::storage::edgecache
environment: production
ausyd1nxvm2064.main.unkin.net:
role: roles::infra::storage::edgecache
environment: production
ausyd1nxvm2065.main.unkin.net:
role: roles::infra::puppetdb::sql
environment: production
ausyd1nxvm2066.main.unkin.net:
role: roles::infra::puppetdb::sql
environment: production
ausyd1nxvm2067.main.unkin.net:
role: roles::infra::puppetdb::sql
environment: production
ausyd1nxvm2068.main.unkin.net:
role: roles::apps::jupyter::hub
environment: production
ausyd1nxvm2069.main.unkin.net:
role: roles::infra::halb::haproxy2
environment: production
ausyd1nxvm2070.main.unkin.net:
role: roles::infra::halb::haproxy2
environment: production
ausyd1nxvm2071.main.unkin.net:
role: roles::infra::halb::haproxy2
environment: production
ausyd1nxvm2072.main.unkin.net:
role: roles::infra::halb::haproxy2
environment: production
ausyd1nxvm2073.main.unkin.net:
role: roles::infra::halb::haproxy2
environment: production
ausyd1nxvm2074.main.unkin.net:
role: roles::infra::dhcp::server
environment: production
ausyd1nxvm2075.main.unkin.net:
role: roles::infra::dhcp::server
environment: production
ausyd1nxvm2076.main.unkin.net:
role: roles::infra::dhcp::server
environment: production
ausyd1nxvm2077.main.unkin.net:
role: roles::infra::sql::shared
environment: production
ausyd1nxvm2078.main.unkin.net:
role: roles::infra::sql::shared
environment: production
ausyd1nxvm2079.main.unkin.net:
role: roles::infra::sql::shared
environment: production
ausyd1nxvm2080.main.unkin.net:
role: roles::infra::git::server
environment: production
ausyd1nxvm2081.main.unkin.net:
role: roles::infra::git::server
environment: production
ausyd1nxvm2082.main.unkin.net:
role: roles::infra::git::server
environment: production
ausyd1nxvm2083.main.unkin.net:
role: roles::infra::git::redis
environment: production
ausyd1nxvm2084.main.unkin.net:
role: roles::infra::git::redis
environment: production
ausyd1nxvm2085.main.unkin.net:
role: roles::infra::git::redis
environment: production
ausyd1nxvm2086.main.unkin.net:
role: roles::infra::metrics::vmstorage
environment: production
ausyd1nxvm2087.main.unkin.net:
role: roles::infra::metrics::vmstorage
environment: production
ausyd1nxvm2088.main.unkin.net:
role: roles::infra::metrics::vmstorage
environment: production
ausyd1nxvm2089.main.unkin.net:
role: roles::infra::metrics::vmstorage
environment: production
ausyd1nxvm2090.main.unkin.net:
role: roles::infra::metrics::vmstorage
environment: production
ausyd1nxvm2091.main.unkin.net:
role: roles::infra::metrics::vminsert
environment: production
ausyd1nxvm2092.main.unkin.net:
role: roles::infra::metrics::vminsert
environment: production
ausyd1nxvm2093.main.unkin.net:
role: roles::infra::metrics::vminsert
environment: production
ausyd1nxvm2094.main.unkin.net:
role: roles::infra::metrics::vmselect
environment: production
ausyd1nxvm2095.main.unkin.net:
role: roles::infra::metrics::vmselect
environment: production
ausyd1nxvm2096.main.unkin.net:
role: roles::infra::metrics::vmselect
environment: production
ausyd1nxvm2097.main.unkin.net:
role: roles::infra::puppet::master
environment: production
ausyd1nxvm2098.main.unkin.net:
role: roles::infra::cobbler::server
environment: production
ausyd1nxvm2099.main.unkin.net:
role: roles::infra::metrics::vmagent
environment: production
ausyd1nxvm2100.main.unkin.net:
role: roles::infra::metrics::vmagent
environment: production
ausyd1nxvm2101.main.unkin.net:
role: roles::infra::metrics::vmagent
environment: production
ausyd1nxvm2102.main.unkin.net:
role: roles::infra::logs::vlinsert
environment: production
ausyd1nxvm2103.main.unkin.net:
role: roles::infra::logs::vlinsert
environment: production
ausyd1nxvm2104.main.unkin.net:
role: roles::infra::logs::vlinsert
environment: production
ausyd1nxvm2105.main.unkin.net:
role: roles::infra::logs::vlselect
environment: production
ausyd1nxvm2106.main.unkin.net:
role: roles::infra::logs::vlselect
environment: production
ausyd1nxvm2107.main.unkin.net:
role: roles::infra::logs::vlselect
environment: production
ausyd1nxvm2108.main.unkin.net:
role: roles::infra::logs::vlstorage
environment: production
ausyd1nxvm2109.main.unkin.net:
role: roles::infra::logs::vlstorage
environment: production
ausyd1nxvm2110.main.unkin.net:
role: roles::infra::logs::vlstorage
environment: production
ausyd1nxvm2111.main.unkin.net:
role: roles::infra::logs::vlstorage
environment: production
ausyd1nxvm2112.main.unkin.net:
role: roles::infra::logs::vlstorage
environment: production
ausyd1nxvm2113.main.unkin.net:
role: roles::infra::logs::vlagent
environment: production
ausyd1nxvm2114.main.unkin.net:
role: roles::infra::logs::vlagent
environment: production
ausyd1nxvm2115.main.unkin.net:
role: roles::infra::ceph::rgw
environment: production
ausyd1nxvm2116.main.unkin.net:
role: roles::infra::ceph::rgw
environment: production
ausyd1nxvm2117.main.unkin.net:
role: roles::infra::ceph::rgw
environment: production
ausyd1nxvm2118.main.unkin.net:
role: roles::infra::ceph::rgw
environment: production
ausyd1nxvm2119.main.unkin.net:
role: roles::infra::ceph::rgw
environment: production
ausyd1nxvm2120.main.unkin.net:
role: roles::base
environment: production
ausyd1nxvm2121.main.unkin.net:
role: roles::infra::mail::gateway
environment: production
ausyd1nxvm2122.main.unkin.net:
role: roles::infra::mail::gateway
environment: production
ausyd1nxvm2123.main.unkin.net:
role: roles::infra::mail::gateway
environment: production
ausyd1nxvm2124.main.unkin.net:
role: roles::infra::mail::backend
environment: production
ausyd1nxvm2125.main.unkin.net:
role: roles::infra::mail::backend
environment: production
ausyd1nxvm2126.main.unkin.net:
role: roles::infra::mail::backend
environment: production
ausyd1nxvm2127.main.unkin.net:
role: roles::infra::dns::externaldns
environment: production
ausyd1nxvm2128.main.unkin.net:
role: roles::infra::dns::externaldns
environment: production
ausyd1nxvm2129.main.unkin.net:
role: roles::infra::dns::externaldns
environment: production
# --- prodnxsr physical nodes (develop) ---
prodnxsr0001.main.unkin.net:
role: roles::infra::k8s::control
environment: develop
prodnxsr0002.main.unkin.net:
role: roles::infra::k8s::control
environment: develop
prodnxsr0003.main.unkin.net:
role: roles::infra::k8s::control
environment: develop
prodnxsr0004.main.unkin.net:
role: roles::infra::k8s::compute
environment: develop
prodnxsr0005.main.unkin.net:
role: roles::infra::k8s::compute
environment: develop
prodnxsr0006.main.unkin.net:
role: roles::infra::k8s::compute
environment: develop
prodnxsr0007.main.unkin.net:
role: roles::infra::k8s::compute
environment: develop
prodnxsr0008.main.unkin.net:
role: roles::infra::k8s::compute
environment: develop
prodnxsr0009.main.unkin.net:
role: roles::infra::incus::node
environment: develop
prodnxsr0010.main.unkin.net:
role: roles::infra::incus::node
environment: develop
prodnxsr0011.main.unkin.net:
role: roles::infra::incus::node
environment: develop
prodnxsr0012.main.unkin.net:
role: roles::infra::incus::node
environment: develop
prodnxsr0013.main.unkin.net:
role: roles::infra::incus::node
environment: develop
+55
View File
@@ -0,0 +1,55 @@
# encapi roles: every distinct Puppet role class used across
# config/instances/*/config.yaml (cobbler_mgmt_classes[0]) PLUS the roles
# run by the 13 prodnxsr physical nodes (from PuppetDB enc_role fact).
# Values are empty maps; add description/default_params here when needed.
roles::apps::jupyter::hub: {}
roles::apps::media::jellyfin: {}
roles::apps::media::lidarr: {}
roles::apps::media::nzbget: {}
roles::apps::media::prowlarr: {}
roles::apps::media::radarr: {}
roles::apps::media::readarr: {}
roles::apps::media::sonarr: {}
roles::apps::music::gonic: {}
roles::base: {}
roles::infra::auth::glauth: {}
roles::infra::ceph::rgw: {}
roles::infra::cobbler::server: {}
roles::infra::dhcp::server: {}
roles::infra::dns::externaldns: {}
roles::infra::dns::master: {}
roles::infra::dns::resolver: {}
roles::infra::git::redis: {}
roles::infra::git::runner: {}
roles::infra::git::server: {}
roles::infra::halb::haproxy2: {}
roles::infra::incus::imagehost: {}
roles::infra::incus::node: {}
roles::infra::k8s::compute: {}
roles::infra::k8s::control: {}
roles::infra::logs::vlagent: {}
roles::infra::logs::vlinsert: {}
roles::infra::logs::vlselect: {}
roles::infra::logs::vlstorage: {}
roles::infra::mail::backend: {}
roles::infra::mail::gateway: {}
roles::infra::metrics::grafana: {}
roles::infra::metrics::prometheus: {}
roles::infra::metrics::vmagent: {}
roles::infra::metrics::vminsert: {}
roles::infra::metrics::vmselect: {}
roles::infra::metrics::vmstorage: {}
roles::infra::nomad::agentv2: {}
roles::infra::nomad::server: {}
roles::infra::pki::certbot: {}
roles::infra::proxy::jumphost: {}
roles::infra::puppetboard::server: {}
roles::infra::puppetdb::api: {}
roles::infra::puppetdb::sql: {}
roles::infra::puppet::master: {}
roles::infra::reposync::repo: {}
roles::infra::reposync::syncer: {}
roles::infra::sql::shared: {}
roles::infra::storage::consul: {}
roles::infra::storage::edgecache: {}
roles::infra::storage::vault: {}
+10
View File
@@ -0,0 +1,10 @@
# encapi statuses == Puppet environments (Cobbler "status").
# Seeded from what the estate actually runs (all nodes today report
# catalog_environment=develop) plus production (the environment the incus
# instance module pins via puppetca_certificate) and testing (implicit).
production:
description: Production environment
develop:
description: Development environment (current default across the estate)
testing:
description: Implicit/transient environment
+19
View File
@@ -0,0 +1,19 @@
locals {
statuses = yamldecode(file("${get_terragrunt_dir()}/statuses.yaml"))
roles = yamldecode(file("${get_terragrunt_dir()}/roles.yaml"))
nodes = yamldecode(file("${get_terragrunt_dir()}/nodes.yaml"))
}
include "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "${get_repo_root()}/modules/encapi"
}
inputs = {
statuses = local.statuses
roles = local.roles
nodes = local.nodes
}
+15
View File
@@ -0,0 +1,15 @@
generate "backend" {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
terraform {
backend "consul" {
address = "https://consul.service.consul"
path = "infra/terraform/enc/$${path_relative_to_include()}/state"
scheme = "https"
lock = true
ca_file = "/etc/pki/tls/certs/ca-bundle.crt"
}
}
EOF
}