--- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/component: puppetboard app.kubernetes.io/instance: puppetserver app.kubernetes.io/name: puppetserver app.kubernetes.io/version: 8.8.0 name: puppetboard namespace: puppet spec: selector: matchLabels: app.kubernetes.io/component: puppetboard app.kubernetes.io/name: puppetserver strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 template: metadata: annotations: reloader.stakater.com/auto: "true" labels: app.kubernetes.io/component: puppetboard app.kubernetes.io/instance: puppetserver app.kubernetes.io/name: puppetserver app.kubernetes.io/version: 8.8.0 spec: enableServiceLinks: false initContainers: - name: wait-puppetserver image: curlimages/curl:8.11.1 imagePullPolicy: IfNotPresent command: - sh - -c - | echo 'Waiting for puppetserver to become ready...' until printf "." && curl --silent --fail --insecure 'https://puppetca:8140/status/v1/simple' | grep -q '^running$'; do sleep 2; done; echo 'Puppetserver OK ✓' resources: limits: cpu: 20m memory: 32Mi requests: cpu: 20m memory: 32Mi - name: cert-generator image: git.unkin.net/unkin/almalinux9-base:20260308 imagePullPolicy: IfNotPresent command: - sh - -c - | set -e # Set the hostname for the certificate HOSTNAME="puppetboard" CERT_DIR="/opt/puppetboard/ssl" # Create certificate directory mkdir -p ${CERT_DIR} # Check if certificates already exist if [ -f "${CERT_DIR}/${HOSTNAME}.pem" ] && [ -f "${CERT_DIR}/${HOSTNAME}.key" ] && [ -f "${CERT_DIR}/ca.pem" ]; then echo "Certificates already exist for ${HOSTNAME}, skipping generation" exit 0 fi # Request certificate from Puppet CA for Puppetboard echo "Requesting certificate for ${HOSTNAME} from puppetca service" # Generate private key openssl genrsa -out ${CERT_DIR}/${HOSTNAME}.key 2048 # Create certificate signing request (CSR) openssl req -new -key ${CERT_DIR}/${HOSTNAME}.key \ -out /tmp/${HOSTNAME}.csr \ -subj "/CN=${HOSTNAME}" # Submit CSR to Puppet CA echo "Submitting certificate request to Puppet CA..." curl -X PUT \ --insecure \ --data-binary @/tmp/${HOSTNAME}.csr \ -H "Content-Type: text/plain" \ https://puppetca:8140/puppet-ca/v1/certificate_request/${HOSTNAME} # Wait for certificate to be signed (poll the CA) echo "Waiting for certificate to be signed..." for i in {1..30}; do if curl --insecure -f -s https://puppetca:8140/puppet-ca/v1/certificate/${HOSTNAME} > ${CERT_DIR}/${HOSTNAME}.pem; then echo "Certificate received for ${HOSTNAME}" break fi echo "Attempt $i: Certificate not ready yet, waiting 10 seconds..." sleep 10 done # Verify we got the certificate if [ ! -f "${CERT_DIR}/${HOSTNAME}.pem" ] || [ ! -s "${CERT_DIR}/${HOSTNAME}.pem" ]; then echo "Failed to obtain certificate for ${HOSTNAME}" exit 1 fi # Get CA certificate curl --insecure -f https://puppetca:8140/puppet-ca/v1/certificate/ca > ${CERT_DIR}/ca.pem # Set appropriate permissions chmod 644 ${CERT_DIR}/${HOSTNAME}.pem chmod 600 ${CERT_DIR}/${HOSTNAME}.key chmod 644 ${CERT_DIR}/ca.pem # Change ownership to puppetboard user (1000:1000) chown -R 1000:1000 ${CERT_DIR} echo "Certificate generation completed for ${HOSTNAME}" volumeMounts: - name: puppetboard-certs mountPath: /opt/puppetboard/ssl resources: limits: cpu: 100m memory: 128Mi requests: cpu: 50m memory: 64Mi securityContext: runAsUser: 0 runAsGroup: 0 allowPrivilegeEscalation: true containers: - name: puppetboard image: ghcr.io/voxpupuli/puppetboard:7.0.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: puppetboard envFrom: - configMapRef: name: puppetboard-config - secretRef: name: puppetboard-secrets resources: requests: memory: 350Mi cpu: 100m limits: memory: 1Gi cpu: 500m securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 allowPrivilegeEscalation: false capabilities: drop: - all volumeMounts: - name: puppetboard-certs mountPath: /opt/puppetboard/ssl readOnly: true volumes: - name: puppetboard-certs persistentVolumeClaim: claimName: puppetboard-certs