Populate terragrunt-enc: encapi ENC data as code
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:
@@ -0,0 +1,5 @@
|
||||
.terraform
|
||||
.terraform.lock.hcl
|
||||
env
|
||||
.terragrunt-cache
|
||||
tfplan
|
||||
@@ -0,0 +1,22 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
types: [yaml]
|
||||
- id: trailing-whitespace
|
||||
types: [yaml]
|
||||
- repo: https://github.com/gruntwork-io/pre-commit
|
||||
rev: v0.1.30
|
||||
hooks:
|
||||
- id: tofu-fmt
|
||||
- id: terragrunt-hcl-fmt
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args:
|
||||
[
|
||||
"-d {extends: relaxed, rules: {line-length: disable}}",
|
||||
"-s",
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
when:
|
||||
- event: push
|
||||
branch: main
|
||||
|
||||
steps:
|
||||
- name: apply
|
||||
image: git.unkin.net/unkin/almalinux9-opentofu:20260606
|
||||
environment:
|
||||
VAULT_AUTH_METHOD: kubernetes
|
||||
commands:
|
||||
- dnf install vault -y
|
||||
- make apply
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: terraform-enc
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
cpu: 1
|
||||
limits:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
@@ -0,0 +1,21 @@
|
||||
when:
|
||||
- event: pull_request
|
||||
|
||||
steps:
|
||||
- name: plan
|
||||
image: git.unkin.net/unkin/almalinux9-opentofu:20260606
|
||||
environment:
|
||||
VAULT_AUTH_METHOD: kubernetes
|
||||
commands:
|
||||
- dnf install vault -y
|
||||
- make plan
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: terraform-enc
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
cpu: 1
|
||||
limits:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
@@ -0,0 +1,18 @@
|
||||
when:
|
||||
- event: pull_request
|
||||
|
||||
steps:
|
||||
- name: pre-commit
|
||||
image: git.unkin.net/unkin/almalinux9-opentofu:20260606
|
||||
commands:
|
||||
- uvx pre-commit run --all-files
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 512Mi
|
||||
cpu: 1
|
||||
limits:
|
||||
memory: 2Gi
|
||||
cpu: 2
|
||||
@@ -0,0 +1,51 @@
|
||||
.PHONY: init plan apply apply-if-changes format pre-commit
|
||||
|
||||
VAULT_AUTH_METHOD ?= approle
|
||||
VAULT_K8S_ROLE ?= woodpecker_terraform_enc
|
||||
VAULT_K8S_MOUNT ?= auth/k8s/au/syd1
|
||||
VAULT_K8S_JWT_PATH ?= /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
|
||||
define vault_env
|
||||
@export VAULT_ADDR="https://vault.service.consul:8200" && \
|
||||
if [ "$(VAULT_AUTH_METHOD)" = "kubernetes" ]; then \
|
||||
export VAULT_TOKEN=$$(vault write -field=token $(VAULT_K8S_MOUNT)/login role=$(VAULT_K8S_ROLE) jwt=$$(cat $(VAULT_K8S_JWT_PATH))); \
|
||||
else \
|
||||
export VAULT_TOKEN=$$(vault write -field=token auth/approle/login role_id=$$VAULT_ROLEID); \
|
||||
fi && \
|
||||
export CONSUL_HTTP_TOKEN=$$(vault read -field=token consul_root/au/syd1/creds/terraform-enc) && \
|
||||
export ENCAPI_WRITE_TOKEN=$$(vault kv get -field=ENCAPI_WRITE_TOKEN kv/kubernetes/namespace/encapi/default/environment)
|
||||
endef
|
||||
|
||||
init:
|
||||
@$(call vault_env) && \
|
||||
terragrunt run --all --non-interactive init -- -upgrade
|
||||
|
||||
plan: init
|
||||
@$(call vault_env) && \
|
||||
terragrunt run --all --parallelism 4 --non-interactive plan
|
||||
|
||||
apply-if-changes: init
|
||||
@$(call vault_env) && \
|
||||
terragrunt run --all --parallelism 4 --non-interactive plan -- -detailed-exitcode -out=tfplan; \
|
||||
EXIT_CODE=$$?; \
|
||||
if [ $$EXIT_CODE -eq 2 ]; then \
|
||||
$(call vault_env) && \
|
||||
terragrunt run --all --parallelism 2 --non-interactive apply -- tfplan; \
|
||||
elif [ $$EXIT_CODE -eq 0 ]; then \
|
||||
echo "No changes detected, skipping apply."; \
|
||||
else \
|
||||
exit $$EXIT_CODE; \
|
||||
fi
|
||||
|
||||
apply: init
|
||||
@$(call vault_env) && \
|
||||
terragrunt run --all --parallelism 2 --non-interactive apply
|
||||
|
||||
format:
|
||||
@echo "Formatting OpenTofu files..."
|
||||
@tofu fmt -recursive .
|
||||
@echo "Formatting Terragrunt files..."
|
||||
@terragrunt hcl fmt
|
||||
|
||||
pre-commit:
|
||||
@uvx pre-commit run --all-files
|
||||
@@ -1,3 +1,60 @@
|
||||
# terragrunt-enc
|
||||
|
||||
Single source of truth for encapi ENC data (statuses, roles, nodes), managed via Terraform/Terragrunt. Supersedes Cobbler node classification for Puppet.
|
||||
Single source of truth for [encapi](https://git.unkin.net/unkin/encapi) ENC
|
||||
data, managed with Terraform/Terragrunt. This repo owns every Puppet node
|
||||
classification the estate has:
|
||||
|
||||
- **statuses** — Puppet environments (`production`, `develop`, `testing`)
|
||||
- **roles** — the Puppet role classes (`roles::…`) a node can be assigned
|
||||
- **nodes** — the certname → role + environment mapping for all 143 hosts
|
||||
(130 container VMs + 13 `prodnxsr*` physicals)
|
||||
|
||||
It **supersedes Cobbler** as the classification source for Puppet: encapi is the
|
||||
live ENC, and this repo is the declarative, reviewed input to it. It also
|
||||
supersedes the dual-write approach that was prototyped in terraform-incus
|
||||
(PR #39) — terraform-incus is no longer involved in ENC data.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
config/
|
||||
root.hcl # terragrunt root: consul backend (infra/terraform/enc/<leaf>/state)
|
||||
encapi/
|
||||
terragrunt.hcl # leaf: feeds the three YAMLs into modules/encapi
|
||||
statuses.yaml # Puppet environments
|
||||
roles.yaml # Puppet role classes
|
||||
nodes.yaml # certname -> {role, environment} for all 143 hosts
|
||||
modules/
|
||||
encapi/ # encapi_status / encapi_role / encapi_node resources,
|
||||
# ordered so nodes depend on their role + status (FK)
|
||||
ci/
|
||||
extract_incus_nodes.py # regenerates the container-VM block of nodes.yaml
|
||||
# from a terraform-incus checkout
|
||||
```
|
||||
|
||||
The encapi provider comes from the internal registry
|
||||
(`artifactapi.k8s.syd1.au.unkin.net/terraform-unkin/encapi` v0.1.0). Writes to
|
||||
encapi are authenticated with `ENCAPI_WRITE_TOKEN`, read from Vault by the
|
||||
Makefile.
|
||||
|
||||
## Data provenance
|
||||
|
||||
- **130 container VMs** (`environment: production`) are extracted from
|
||||
terraform-incus `config/instances/<host>/config.yaml`: certname is
|
||||
`<host>.main.unkin.net`, role is `cobbler_mgmt_classes[0]` (default
|
||||
`roles::base`). terraform-incus itself is not modified — the data is copied in
|
||||
here as plain config. Re-run `ci/extract_incus_nodes.py --incus-repo <path>`
|
||||
to refresh after VM changes.
|
||||
- **13 `prodnxsr*` physical nodes** (`environment: develop`) are the bare-metal
|
||||
hypervisor / k8s nodes, not managed by the incus module. Their roles come from
|
||||
the PuppetDB `enc_role` fact and are maintained by hand in `nodes.yaml`.
|
||||
|
||||
## Usage
|
||||
|
||||
CI (Woodpecker) plans on every PR and applies on merge to `main`, authenticating
|
||||
to Vault via kubernetes auth (`terraform-enc` ServiceAccount). Locally:
|
||||
|
||||
```sh
|
||||
make plan # approle auth by default (needs env with VAULT_ROLEID)
|
||||
make apply
|
||||
```
|
||||
|
||||
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regenerate the container-VM portion of config/encapi/nodes.yaml from a
|
||||
checkout of terraform-incus.
|
||||
|
||||
encapi is the single source of truth for Puppet ENC data, but the 130 container
|
||||
VMs are *defined* in terraform-incus (config/instances/<host>/config.yaml). This
|
||||
script lifts that classification into plain config data here:
|
||||
|
||||
certname = <dir basename>.<cobbler_domain> (cobbler_domain = main.unkin.net)
|
||||
role = cobbler_mgmt_classes[0] (default roles::base)
|
||||
environment = production
|
||||
|
||||
It only rewrites the "container VMs" block; the prodnxsr physical nodes below
|
||||
the marker are maintained by hand and left untouched.
|
||||
|
||||
Usage:
|
||||
python3 ci/extract_incus_nodes.py --incus-repo /path/to/terraform-incus
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
sys.exit("PyYAML required: pip install pyyaml")
|
||||
|
||||
PHYS_MARKER = "# --- prodnxsr physical nodes (develop) ---"
|
||||
VM_MARKER = "# --- container VMs (production) ---"
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--incus-repo", required=True,
|
||||
help="Path to a terraform-incus checkout")
|
||||
ap.add_argument("--domain", default="main.unkin.net")
|
||||
ap.add_argument("--nodes-file",
|
||||
default=os.path.join(os.path.dirname(__file__),
|
||||
"..", "config", "encapi", "nodes.yaml"))
|
||||
args = ap.parse_args()
|
||||
|
||||
inst = os.path.join(args.incus_repo, "config", "instances")
|
||||
dirs = sorted(d for d in os.listdir(inst)
|
||||
if os.path.isdir(os.path.join(inst, d))
|
||||
and os.path.exists(os.path.join(inst, d, "config.yaml")))
|
||||
|
||||
vm_lines = []
|
||||
for d in dirs:
|
||||
with open(os.path.join(inst, d, "config.yaml")) as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
classes = cfg.get("cobbler_mgmt_classes") or []
|
||||
role = classes[0] if classes else "roles::base"
|
||||
vm_lines.append(f"{d}.{args.domain}:")
|
||||
vm_lines.append(f" role: {role}")
|
||||
vm_lines.append(" environment: production")
|
||||
|
||||
nodes_file = os.path.abspath(args.nodes_file)
|
||||
with open(nodes_file) as f:
|
||||
existing = f.read().splitlines()
|
||||
|
||||
# Preserve everything from the physical-nodes marker onward.
|
||||
try:
|
||||
idx = existing.index(PHYS_MARKER)
|
||||
except ValueError:
|
||||
sys.exit(f"marker not found in {nodes_file}: {PHYS_MARKER!r}")
|
||||
tail = existing[idx:]
|
||||
|
||||
# Preserve only the top-of-file comment block, stopping at the VM marker.
|
||||
header = []
|
||||
for ln in existing[:idx]:
|
||||
if ln == VM_MARKER:
|
||||
break
|
||||
header.append(ln)
|
||||
while header and header[-1] == "":
|
||||
header.pop()
|
||||
|
||||
out = header + ["", VM_MARKER] + vm_lines + ["", *tail]
|
||||
with open(nodes_file, "w") as f:
|
||||
f.write("\n".join(out).rstrip("\n") + "\n")
|
||||
print(f"wrote {len(dirs)} container VM records to {nodes_file}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -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
|
||||
@@ -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: {}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
resource "encapi_status" "this" {
|
||||
for_each = var.statuses
|
||||
|
||||
name = each.key
|
||||
description = each.value.description
|
||||
}
|
||||
|
||||
resource "encapi_role" "this" {
|
||||
for_each = var.roles
|
||||
|
||||
name = each.key
|
||||
description = each.value.description
|
||||
default_params = each.value.default_params == null ? null : jsonencode(each.value.default_params)
|
||||
}
|
||||
|
||||
resource "encapi_node" "this" {
|
||||
for_each = var.nodes
|
||||
|
||||
certname = each.key
|
||||
role = each.value.role
|
||||
environment = each.value.environment
|
||||
params = each.value.params == null ? null : jsonencode(each.value.params)
|
||||
|
||||
# Nodes FK-require their role and status to exist first.
|
||||
depends_on = [
|
||||
encapi_role.this,
|
||||
encapi_status.this,
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
provider "encapi" {
|
||||
endpoint = var.encapi_endpoint
|
||||
# token defaults to the ENCAPI_WRITE_TOKEN environment variable
|
||||
}
|
||||
|
||||
variable "encapi_endpoint" {
|
||||
description = "The encapi server base URL."
|
||||
type = string
|
||||
default = "https://encapi.k8s.syd1.au.unkin.net"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
variable "statuses" {
|
||||
description = <<EOT
|
||||
Map of encapi statuses (Puppet environments) to seed. Keyed by status name.
|
||||
Each value may carry an optional description.
|
||||
EOT
|
||||
type = map(object({
|
||||
description = optional(string)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "roles" {
|
||||
description = <<EOT
|
||||
Map of encapi roles to seed. Keyed by role class name (e.g. roles::base).
|
||||
Each value may carry an optional description and a default_params object that
|
||||
is jsonencode()'d into the role's inheritable defaults.
|
||||
EOT
|
||||
type = map(object({
|
||||
description = optional(string)
|
||||
default_params = optional(any)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "nodes" {
|
||||
description = <<EOT
|
||||
Map of encapi node assignments to seed. Keyed by certname. Each value pins the
|
||||
node to a role and environment (which must exist as a role/status above), with
|
||||
optional per-node params jsonencode()'d into the ENC output.
|
||||
EOT
|
||||
type = map(object({
|
||||
role = string
|
||||
environment = string
|
||||
params = optional(any)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
encapi = {
|
||||
source = "artifactapi.k8s.syd1.au.unkin.net/terraform-unkin/encapi"
|
||||
version = "0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user