Imported from burdandrei/vault-agent-pki-cert-example (
AGENTS.md). Install upstream withnpx skills add burdandrei/vault-agent-pki-cert-example. Copyright stays with the author.
AGENTS.md
This file provides guidance to agents when working with code in this repository.
Stack
- Infrastructure: Terraform (HashiCorp Vault provider ≥ 4.0, Terraform ≥ 1.3) — lives in
terraform/ - Vault Agent configs: HCL (
.hcl) files at the repo root - Templates: Go-template dialect used by Vault Agent (
.vtmplfiles intemplates/) - DataPower container: Podman (
icr.io/cpopen/datapower/datapower-limited:11.0.0.1), run viadatapower/start-datapower.sh - Shell scripts: Bash (
cleanup.sh,datapower/upload-certs-to-datapower.sh,nginx/reload-nginx.sh)
Critical Commands
# Bootstrap infrastructure (must run from terraform/ directory)
cd terraform && terraform init && terraform apply
# Basic flow — one-shot cert issuance
vault agent -config=./echo.hcl
# DataPower — step 1: render initial certs before starting container
vault agent -config=./datapower-init.hcl -exit-after-auth
# DataPower — step 2: start container (must run from datapower/ directory)
cd datapower && bash ./start-datapower.sh
# DataPower — step 3: continuous renewal + upload
vault agent -config=./datapower.hcl
# nginx flow
nginx -c "$(pwd)/nginx/nginx.conf"
vault agent -log-level debug -config=./nginx.hcl
# Teardown
bash ./cleanup.sh # destroys Terraform state AND deletes all .pem/.out files
Non-Obvious Patterns
Vault Agent config (*.hcl)
- All agents authenticate via
token_filepointing to.vault-tokenat the repo root (dev mode convenience). Kubernetes and AWS auth examples are commented indatapower.hcl. - The
exec.commandblock insidetemplate {}runs after every cert render, not just on first render. This is howupload-certs-to-datapower.shandnginx/reload-nginx.share triggered. datapower-init.hclis a one-shot config — always add-exit-after-authflag; thedatapower.hclis the continuous config.
Vault Agent templates (.vtmpl)
- Templates use the
pkiCertfunction:{{ with pkiCert "<mount>/issue/<role>" "common_name=..." "ttl=..." }} - Side-effect file writes use
writeToFile "<path>" "<owner>" "<group>" "<mode>"piped from.Key,.Cert, or.CA. - The
.outdestination file (the template'sdestination =) is a "combined" bundle that also echoes key+cert+CA inline — the real per-type files are written viawriteToFileside effects. - To build a cert chain (cert + CA):
{{ .Cert | writeToFile "..." "0644" "append" }}—appendmust be the 5th argument.
PKI roles and domains (defined in terraform/main.tf)
| Role | Allowed domain | Config / Template files |
|---|---|---|
demoissuer |
*.demo.vault.hashicorp.ibm |
echo.hcl, templates/source.vtmpl |
datapower |
*.datapower.hashicorp.ibm |
datapower-init.hcl, datapower.hcl, templates/dp-*.vtmpl |
nginx |
*.nginx.hashicorp.ibm |
nginx.hcl, templates/nginx-cert.vtmpl |
DataPower cert upload
upload-certs-to-datapower.shmust be run from the repo root (paths are relative:datapower/certs/demo-sscert.pem).- After uploading files, the script calls
reload_certandreload_key(PUT to/mgmt/config/default/CryptoCertificate/<name>andCryptoKey/<name>) — without this step, DataPower TLS contexts keep the old cert material in memory even after the file is replaced. - The DataPower crypto objects are named
demo(cert),demo(key), grouped in idcredssl-keystore(defined indatapower/config/auto-startup.cfg). start-datapower.shmountsdatapower/certs/→/opt/ibm/datapower/root/secure/usrcertsinside the container, which DataPower maps ascert:///.
nginx cert path coupling
nginx/nginx.confresolves certs with relative paths../certs/nginx-cert.pemand../certs/nginx-privkey.pem, which means nginx must be started from the repo root using the absolute path form:nginx -c "$(pwd)/nginx/nginx.conf".- The private key is written via
writeToFileintemplates/nginx-cert.vtmpl; the templatedestinationfile (certs/nginx-cert.pem) contains cert + CA chain only.
Cleanup
cleanup.shdeletes all*.pemand*.outfiles across the repo (excluding.gitand.terraformdirs) — do not store generated certs anywhere else in the tree if you want them preserved after cleanup.