From c6df3a7619c7c9803498015c50cdcb8b2f380984 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Wed, 29 Jul 2026 21:36:47 +1000 Subject: [PATCH] feat: make puppet-initial CA endpoint configurable, default to k8s puppetca (#171) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why The `puppet-initial` firstrun bootstrap RPM hardcoded the legacy Consul-discovered CA endpoint `puppetca.query.consul:8140`. That VM-era CA is being replaced by the in-cluster puppetserver CA service `puppetca.k8s.syd1.au.unkin.net`. Rather than swap one hardcoded host for another, the endpoint is now configurable so kickstart can override it per host. Verified the new service serves the same Puppet CA API on the same port: `https://puppetca.k8s.syd1.au.unkin.net:8140/puppet-ca/v1/certificate/ca` returns HTTP 200 with a valid Puppet CA cert. ## Changes - Default the CA host to `puppetca.k8s.syd1.au.unkin.net` (still port `8140`, same `/puppet-ca/v1/certificate/ca` path). - Bootstrap script reads `PUPPETCA_HOST` / `PUPPETCA_PORT` from the environment, falling back to the defaults, and uses them for both the CA cert fetch and the `--server` of the initial noop registration run. - Add `EnvironmentFile=-/etc/sysconfig/puppet-initial` to the systemd unit so kickstart `%post` can drop overrides in there. - Ship a commented example config at `/etc/sysconfig/puppet-initial` as `%config(noreplace)`. - Add a package README documenting the override, with a kickstart `%post` example. - Bump el8/el9 build version `1.0.3` -> `1.0.4` so a new RPM is published (dedup skips identical filenames). Note: the run loop still targets `puppet.query.consul` (the compile master, a separate host from the CA) — intentionally left unchanged; scope here is the CA endpoint only. ## Validation - `make test` — 72 passed - pre-commit (metadata jsonschema, yamllint, shebang/executable checks) — all pass - Local `nfpm pkg` build: RPM assembles; `/etc/sysconfig/puppet-initial` correctly listed by `rpm -qcp` as a config file; packaged script carries the new default + env wiring. https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv --------- Co-authored-by: Ben Vincent Reviewed-on: https://git.unkin.net/unkin/rpmbuilder/pulls/171 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- rpms/puppet-initial/README.md | 38 +++++++++++++++++++ rpms/puppet-initial/metadata.yaml | 4 +- rpms/puppet-initial/resources/nfpm.yaml | 7 ++++ rpms/puppet-initial/resources/puppet-initial | 11 +++++- .../resources/puppet-initial.service | 1 + .../resources/puppet-initial.sysconfig | 13 +++++++ 6 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 rpms/puppet-initial/README.md create mode 100644 rpms/puppet-initial/resources/puppet-initial.sysconfig diff --git a/rpms/puppet-initial/README.md b/rpms/puppet-initial/README.md new file mode 100644 index 0000000..bce9974 --- /dev/null +++ b/rpms/puppet-initial/README.md @@ -0,0 +1,38 @@ +# puppet-initial + +A firstrun bootstrap script and oneshot systemd service that initialises a +freshly-provisioned host into Puppet: + +1. Sets the FQDN under `.main.unkin.net`. +2. Fetches the Puppet CA certificate from the CA service. +3. Registers the node with a noop agent run against the CA. +4. Runs the agent a few times against the compile master, then enables the + `puppet` service and disables itself. + +## Puppet CA endpoint + +The CA endpoint defaults to the in-cluster puppetserver CA service +`puppetca.k8s.syd1.au.unkin.net:8140` (serving the standard +`/puppet-ca/v1/certificate/ca` API). + +It is overridable via the environment. The `puppet-initial.service` unit reads +`/etc/sysconfig/puppet-initial` (`EnvironmentFile=-`, so the file is optional), +which the RPM ships as a commented `%config(noreplace)` example: + +| Variable | Default | Purpose | +|-----------------|----------------------------------|-------------------------------------------------------------| +| `PUPPETCA_HOST` | `puppetca.k8s.syd1.au.unkin.net` | CA hostname (CA cert fetch + `--server` for registration). | +| `PUPPETCA_PORT` | `8140` | CA API port. | + +### Overriding from kickstart + +A kickstart `%post` can point a host at a different CA without rebuilding the +RPM by writing the sysconfig file before the service starts: + +```bash +%post +cat > /etc/sysconfig/puppet-initial <<'EOF' +PUPPETCA_HOST=puppetca.k8s.syd1.au.unkin.net +PUPPETCA_PORT=8140 +EOF +``` diff --git a/rpms/puppet-initial/metadata.yaml b/rpms/puppet-initial/metadata.yaml index 9a50889..f4fda5a 100644 --- a/rpms/puppet-initial/metadata.yaml +++ b/rpms/puppet-initial/metadata.yaml @@ -11,9 +11,9 @@ builds: release: '1' repository: - almalinux/el8 - version: 1.0.3 + version: 1.0.4 - image: git.unkin.net/unkin/almalinux9-rpmbuilder:latest release: '1' repository: - almalinux/el9 - version: 1.0.3 + version: 1.0.4 diff --git a/rpms/puppet-initial/resources/nfpm.yaml b/rpms/puppet-initial/resources/nfpm.yaml index bb8e86a..a730ff9 100644 --- a/rpms/puppet-initial/resources/nfpm.yaml +++ b/rpms/puppet-initial/resources/nfpm.yaml @@ -31,6 +31,13 @@ contents: mode: 0644 owner: root group: root + - src: /app/resources/puppet-initial.sysconfig + dst: /etc/sysconfig/puppet-initial + type: config|noreplace + file_info: + mode: 0644 + owner: root + group: root # Scripts to run during installation/removal (optional) scripts: diff --git a/rpms/puppet-initial/resources/puppet-initial b/rpms/puppet-initial/resources/puppet-initial index fb958fa..e63c822 100755 --- a/rpms/puppet-initial/resources/puppet-initial +++ b/rpms/puppet-initial/resources/puppet-initial @@ -1,14 +1,21 @@ #!/bin/bash +# Puppet CA endpoint. Overridable via the environment (systemd reads +# /etc/sysconfig/puppet-initial via EnvironmentFile), so kickstart %post can +# point a host at a different CA without rebuilding the RPM. Defaults to the +# in-cluster puppetserver CA service. +PUPPETCA_HOST="${PUPPETCA_HOST:-puppetca.k8s.syd1.au.unkin.net}" +PUPPETCA_PORT="${PUPPETCA_PORT:-8140}" + # Ensure the hostname is set hostnamectl set-hostname $(hostname -s).main.unkin.net grep '^HOSTNAME=' /etc/sysconfig/network | cut -d= -f2 | grep -q '\.' || sed -i 's/^\(HOSTNAME=[^\.]*\)$/\1.main.unkin.net/' /etc/sysconfig/network # Install CA for Puppet -test -f /etc/puppetlabs/puppet/ssl/certs/ca.pem || mkdir -p /etc/puppetlabs/puppet/ssl/certs && wget --no-check-certificate https://puppetca.query.consul:8140/puppet-ca/v1/certificate/ca -O /etc/puppetlabs/puppet/ssl/certs/ca.pem +test -f /etc/puppetlabs/puppet/ssl/certs/ca.pem || mkdir -p /etc/puppetlabs/puppet/ssl/certs && wget --no-check-certificate "https://${PUPPETCA_HOST}:${PUPPETCA_PORT}/puppet-ca/v1/certificate/ca" -O /etc/puppetlabs/puppet/ssl/certs/ca.pem # Registering to Puppet server -/opt/puppetlabs/bin/puppet agent --test --server puppetca.query.consul --noop --onetime --no-daemonize --verbose +/opt/puppetlabs/bin/puppet agent --test --server "${PUPPETCA_HOST}" --noop --onetime --no-daemonize --verbose # Running Puppet agent five times with a 30-second gap between each run, stop puppet service at the end of each run for i in {1..5}; do diff --git a/rpms/puppet-initial/resources/puppet-initial.service b/rpms/puppet-initial/resources/puppet-initial.service index f38debf..2391454 100644 --- a/rpms/puppet-initial/resources/puppet-initial.service +++ b/rpms/puppet-initial/resources/puppet-initial.service @@ -5,6 +5,7 @@ Wants=network-online.target [Service] Type=simple +EnvironmentFile=-/etc/sysconfig/puppet-initial ExecStart=/usr/local/bin/puppet-initial RemainAfterExit=true ExecStop=/bin/true diff --git a/rpms/puppet-initial/resources/puppet-initial.sysconfig b/rpms/puppet-initial/resources/puppet-initial.sysconfig new file mode 100644 index 0000000..84b2d53 --- /dev/null +++ b/rpms/puppet-initial/resources/puppet-initial.sysconfig @@ -0,0 +1,13 @@ +# Environment overrides for the puppet-initial firstrun bootstrap. +# Read by the puppet-initial.service unit (EnvironmentFile=-/etc/sysconfig/puppet-initial). +# A kickstart %post can write this file to point a host at a different Puppet CA +# without rebuilding the RPM. All values are optional; the defaults below match +# the shipped in-cluster puppetserver CA service. + +# Hostname of the Puppet CA service. Used both to fetch the CA certificate +# (https://:/puppet-ca/v1/certificate/ca) and as --server for the +# initial noop agent registration run. +#PUPPETCA_HOST=puppetca.k8s.syd1.au.unkin.net + +# Port the Puppet CA API listens on. +#PUPPETCA_PORT=8140