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
|
# 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