consul-template, Rendered Offline, Stopped At Consul's Door
consul-template on EL 10 from releases.hashicorp.com; SHA256SUMS is signature-checked against HashiCorp's key before get_url trusts it, the live test re-checks both, then renders env and file templates with -once (to stdout, then to disk, read back) and runs a key template against a dead Consul with retries off, to 'connection refused'. Pinned. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-09-21 · podman 4.9.3 · ansible 2.21.4 · how we verify
Documentation
consul-template
HashiCorp consul-template on EL 10 from the vendor's release, checked against the
published SHA-256 and the vendor's signature on it, pinned to a version, installed as root's binary
in /usr/local/bin. Original role for EL 10, live-tested with podman on
Rocky Linux 10.
No package worth the name. EL 10 carries no consul-template, and a
third-party repository is one more key to trust. This role takes the
release from releases.hashicorp.com, has Ansible's get_url refuse the asset unless
its SHA-256 is the published one, and the live test checks the asset on
disk against the same published value again.
The checksum file is signed, and the signature is checked first. HashiCorp Security
signs consul-template_0.43.0_SHA256SUMS; the role ships HashiCorp Security's public key
(C874 011F 0AB4 0511 0D02 1055 3436 5D94 72D7 468F), imports it into a GnuPG home of its own under
/usr/local/src, asserts that fingerprint, and verifies the signature
before get_url is allowed to trust the file. The live test re-verifies
the signature and asserts the home holds exactly the expected key(s).
Pinned. consul_template_version is what gets installed, kept in a directory
of its own so the checksum file and the asset it names stay together. A
newer release is a variable change and a run; the same version is
changed=0.
Proven to run. The live test runs consul-template -template /tmp/consul-template-p/in.tpl:/tmp/consul-template-p/out.txt -once -dry and expects
"name=iacbazaar-env" - the binary ran all the way to the point where it
needed something this host does not have.
Rendered offline, and stopped at Consul's door. consul-template's
env and file functions need no Consul: the live test renders a
template from both with -once (dry to stdout, then to disk, read back).
A template with a key dependency is run against a dead address with
-consul-retry=false and expected to stop at "connection refused" in
seconds - with retries on, the default, it would retry for minutes,
which is the right behaviour for a daemon and the wrong one for a test.
The role installs the binary only; a unit that watches Consul or Vault
is the operator's, with the addresses and tokens it needs.
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
vault-kv-engine
KV v1 overwrites in place, so a bad write is the end of the previous secret; cas_required defaults to false, so two writers that read the same version both succeed and the second silently replaces the first; and version history is unbounded by default. v2 always, check-and-set on (off by name), versions bounded by count and age, the mount's lease ceilings set rather than inherited.
vault-pki-certificate-authority
Issuing from the root puts every leaf one signature from the root's compromise; a PKI role's defaults issue nothing until somebody reaches for allow_any_name, which issues for every hostname; and without AIA and CRL URLs a leaf is valid and unverifiable. A root that signs one intermediate, roles bound to allowed_domains, 30-day leaves under a 90-day ceiling, URLs on both mounts.
vault-approle
A secret ID with no TTL and no use limit is a password, and both default to unlimited; a role with no bound CIDRs logs in from anywhere; and a role with no max TTL mints tokens that renew forever. Secret IDs that live an hour and are used once, roles bound to the ranges they run from with unbound accepted by name, and token ceilings set.
ansible-cfssl
cfssl and cfssljson on EL 10 from the GitHub release, each refused by Ansible's get_url unless its SHA-256 is the one in the vendor's checksums file, and re-checked by the live test, which mints a root CA from a CSR, writes it as PEM through cfssljson and reads the subject back with certinfo. Pinned; a newer release is a variable change. Original role, live-tested on Rocky Linux 10.
vault-database-secrets
The credential Vault connects with is still a password somebody knows until Vault rotates it; a role with no max TTL issues credentials that renew forever; and creation statements are the privilege, so a careless one is a superuser factory. Root rotation daily, TTLs per role, statements that grant exactly the PostgreSQL role you name, and the connection verified at apply.
vault-oidc-auth
An OIDC role with no bound claims admits every user of the identity provider; a role with no bound audience accepts tokens minted for other services; and the client secret lands in state. Bound claims expected with none accepted by name, an audience required, callbacks listed rather than assumed, token ceilings set, and the write-only secret path named for Terraform 1.11+.