Compare commits

...
103 Commits
Author SHA1 Message Date
volker.raschekandCopilot e1d6e80837 refactor: use the file extension .yml for all yaml files
Lint Markdown files / markdown-lint (push) Successful in 8s
Ansible Linter / ansible-lint (push) Successful in 2m59s
Molecule / Molecule (push) Successful in 7m45s
Release Ansible Role / Release Ansible Role (push) Successful in 1m39s
The role used .yaml while the molecule scenario used .yml, because molecule hard codes molecule.yml and has no
fallback for the other extension. Aligning all files on .yml keeps the extension consistent across the repository
and avoids surprises when a tool only supports one of both spellings.

Co-authored-by: Copilot <copilot@github.com>
2026-09-08 12:24:25 +02:00
volker.raschekandCopilot 03f77e69d6 refactor(ci): keep community.docker out of the role requirements
Lint Markdown files / markdown-lint (push) Successful in 5s
Ansible Linter / ansible-lint (push) Successful in 2m54s
Molecule / Molecule (push) Successful in 6m52s
The collection community.docker is only used by the molecule scenario and is no runtime dependency of the role.
It is therefore declared in molecule/default/collections.yml only. Since ansible-lint also lints the scenario, the
action installs that file instead of requirements.yaml.

Co-authored-by: Copilot <copilot@github.com>
2026-09-08 11:24:57 +02:00
volker.raschekandCopilot 28d4ea523d fix: declare the dependency on the collection community.general
Lint Markdown files / markdown-lint (push) Successful in 7s
Ansible Linter / ansible-lint (push) Successful in 2m22s
Molecule / Molecule (push) Successful in 6m39s
On Archlinux ansible.builtin.package resolves to the module pacman, which is shipped by community.general and not by
ansible-core. Without the collection the role fails with "Could not find a matching action for the pacman package
manager", which surfaced in the molecule scenario as soon as only the explicitly declared collections were installed.

Co-authored-by: Copilot <copilot@github.com>
2026-09-08 11:18:29 +02:00
volker.raschek e77fe22c48 fix(ci): runs-on ubuntu-latest-amd64
Lint Markdown files / markdown-lint (push) Successful in 8s
Ansible Linter / ansible-lint (push) Successful in 3m2s
Molecule / Molecule (push) Failing after 6m18s
2026-09-08 11:00:40 +02:00
volker.raschek 8da7062c13 fix(ci): runs-on ubuntu-latest-amd64
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (push) Successful in 54s
Molecule / Molecule (push) Failing after 2m42s
2026-09-08 10:51:38 +02:00
volker.raschekandCopilot a6e8555e13 refactor(molecule): use docker instead of podman
Lint Markdown files / markdown-lint (push) Successful in 12s
Ansible Linter / ansible-lint (push) Successful in 2m6s
Molecule / Molecule (push) Failing after 3m50s
The scenario now starts its containers with community.docker instead of containers.podman, because docker is the
container runtime available on the CI runner. The connection plugin, the login command and the declared collections
were adjusted accordingly and the docker SDK for python is installed in the workflow, since the module requires it.

Co-authored-by: Copilot <copilot@github.com>
2026-09-08 10:14:20 +02:00
volker.raschekandCopilot 9cadae0ba3 fix(ci): resolve collections for ansible-lint
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (push) Successful in 1m53s
Molecule / Molecule (push) Failing after 2m36s
The ansible-lint action only installs collections from a requirements file it knows about. Since this project uses
requirements.yaml instead of the auto-detected requirements.yml, the collections were never installed and the
syntax-check rule failed with unresolvable modules. The requirements file is now passed explicitly to the action.

Additionally containers.podman is declared as dependency, because the molecule scenario uses
containers.podman.podman_container.

Co-authored-by: Copilot <copilot@github.com>
2026-09-08 09:11:56 +02:00
volker.raschekandCopilot 6d465e5dad docs: declare the dependency on the collection community.crypto
Lint Markdown files / markdown-lint (push) Successful in 12s
Ansible Linter / ansible-lint (push) Failing after 55s
Molecule / Molecule (push) Failing after 1m41s
The role uses openssl_privatekey, openssl_csr, x509_certificate and x509_certificate_info, but neither declared
that collection anywhere nor mentioned it in the readme. A standalone role cannot express collection dependencies in
its metadata, so a requirements file next to the readme section is the usual way.

The section also documents two requirements that arose from the recent changes and were undocumented as well. Facts
have to be gathered, because the package names, the trust store anchor and the update command are resolved by
distribution, os_family and architecture. And the role needs become, since it writes into /etc and updates the trust
store.

No version is pinned. All used modules exist since community.crypto 1.0.0, so a lower bound would be arbitrary.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:59 +02:00
volker.raschekandCopilot 206c057247 chore(ci): run the molecule scenario on every push and pull request
The scenario was only runnable by hand so far, which defeats its purpose. Podman is already installed and
configured on the runners, so the job only has to add molecule itself.

The repository is named ansible-role-certificate-authority while the role is named certificate_authority. Since the
scenario includes the role by its name and uses the parent of the project directory as roles path, the checkout has
to happen into a directory matching the role.

The collections are declared in molecule/default/collections.yml instead of being installed by an explicit step.
That is the path the collections invoker of molecule looks at by default, so the dependency action of the test
sequence installs them for the workflow and for local runs alike.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:59 +02:00
volker.raschekandCopilot 5dec5e4a7a docs: describe how to run the molecule tests locally
The scenario was added without any hint in the readme, so a contributor had to read molecule.yml to find out
which tools are needed and how to invoke them. Molecule ships only its default driver, therefore podman and the
collection containers.podman are prerequisites that are not obvious.

The section is placed above the parameters, because the readme generator treats the parameter section as the last
one in the file and replaces everything below it.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot b72fba0924 test: add a molecule scenario covering three distribution families
The role was only linted statically so far, which is why every bug of the recent analysis passed the ci
unnoticed. The scenario converges the role in podman containers of Archlinux, Debian and Fedora, checks
idempotence and then verifies the result.

Verification covers the chain via openssl verify, the file modes of keys, certificates and directories,
the number of certificates in the fullchain of the client, its subject alternative names and the anchor in
the systems trust store. Root and intermediate use a passphrase so the protected code paths are exercised
as well.

Molecule ships only the default driver, so create and destroy are provided as playbooks. Three details
were needed to make it work. The connection has to be declared in the instance config, since molecule
ignores ansible_connection_options of the driver. Raw commands are passed through sh explicitly, because
the podman connection plugin splits them instead of using a shell. And the roles path has to point at the
parent of the project directory, which is the role itself.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot a4be99b28b fix: update the systems trust store from a handler
The update command ran on every play with changed_when tied to its return code, so the role never
reported a converged state. It is a handler now, notified by the anchor symlink and by the three tasks
which write cert.pem of the root certificate authority. Notifying from the certificate tasks as well keeps
the trust store correct on renewal, where the symlink itself stays untouched.

The anchor path and the update command moved into the per os_family vars, because a handler cannot read
the block vars they lived in before. Debian and RedHat need dedicated files again, they agree on the
package name but differ in anchor path, file extension and update command.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 95181a18d4 refactor: extract the duplicated certificate concatenation into a shared task file
Building chain.pem, fullchain.pem and all.pem was implemented seven times across three task files with
identical stat, awk and copy tasks. The blocks now include tasks/concatenate.yaml and pass the sources, the
destination and the mode, which removes about a hundred lines.

Two side effects come with it. Every source file is checked instead of only the foreign one, so a missing
file skips the block instead of letting awk fail. And the trailing newline of the result is kept, because
stdout_lines joined by a newline dropped it.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 95ea71394e fix: make issued certificates readable for unprivileged consumers
The pki directories were created with mode 0700, so cert.pem, chain.pem and fullchain.pem stayed
unreachable for every non root process although they are declared as 0644. That defeats the main purpose of
the role, which is handing a certificate to a service such as nginx or postgres.

The directories are opened up to 0755. To keep that safe, the mode of the private keys is now pinned
explicitly to 0600 instead of relying on the default of community.crypto.openssl_privatekey.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 625e93b524 fix: install cryptography via the distribution package manager
Installing the python cryptography bindings with ansible.builtin.pip is rejected by PEP 668 on distributions
which mark their python installation as externally managed. Fedora 38+, Ubuntu 23.04+ and RHEL 10 are
affected, so the role aborted on its very first task there.

The package names are resolved from vars/ via first_found, which keeps distribution specifics out of the
task file. vars/main.yaml provides python3-cryptography as a fallback for every family without a dedicated
file, Archlinux overrides it with python-cryptography.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot e6092685e9 docs: correct copied parameter descriptions
Several parameter descriptions were carried over from unrelated variables and
described the wrong attribute. Both country name parameters claimed to document
a Common Name, the client organizational unit name repeated the Common Name text
and the two client content parameters described a passphrase and a key
algorithm.

The client content parameters now follow the wording already used for their root
and intermediate counterparts. The README tables were regenerated with
readme-generator, which also normalises the column padding of the previously
hand-edited rows.

Additionally fix the misspelled repository owner in the homepage URL and a typo
in the galaxy description.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 8cc33a29ab refactor: remove circular pip installation task
The task named "Upgrade python package manager pip" installed pip with
`state: present`, which never upgrades anything, and it did so through
`ansible.builtin.pip`. That module already requires a working pip on the target,
so the task could only ever run when its own result was already satisfied.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 2cd88df81b fix: report concatenation commands as unchanged
The `awk 1` commands assembling the chain, fullchain and all files declared
`changed_when: chain_content.rc == 0`, which holds on every successful run. As a
result the role never reported a converged state, even when no certificate was
touched.

These commands only read files and write to stdout, so mark them as unchanged.
The subsequent copy task remains responsible for reporting an actual change.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot a6e647b842 refactor: drop ineffective remote_src from copy tasks
All tasks writing the concatenated chain, fullchain and all files pass the file
body via `content`. The `remote_src` option only governs how `src` is resolved
and is ignored in that case, so it merely suggested a behaviour the tasks never
had.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot ad7b76852b feat: assert that the signing certificate authority is available
Issuing an intermediate certificate authority or a client certificate always
signs against the private key of the parent authority, regardless of whether
that authority is managed in the same run. With `certificate_authority_root_ca_skip`
or `certificate_authority_intermediate_ca_skip` enabled and no previously
provisioned key at the configured path, this surfaced as a generic module error
deep inside the signing task.

Stat the parent private key upfront and assert its presence, so the failure
names the missing path and the variables that control it. Skipping the parent
remains valid when its key already exists, because the check inspects the file
instead of the skip variable.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 9ea26dc23f fix: resolve trust store location per distribution family
The trust store import hardcoded the RHEL anchor directory and
`update-ca-trust`, although `meta/main.yaml` also declares ArchLinux and Ubuntu
as supported platforms. On those distributions the task created a dangling
symlink outside any trust source and then failed on the missing binary.

Resolve both the anchor path and the update command from a map keyed by
`ansible_facts['os_family']`. Debian based systems additionally require the file
extension `crt`, because `update-ca-certificates` ignores anchors named
otherwise.

Note that the role now depends on gathered facts.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:30:23 +02:00
volker.raschekandCopilot 2733f3929a docs: shorten SAN format hint to keep README table aligned
The previous wording exceeded the description column width generated by
readme-generator, so markdownlint reported MD060/table-column-style for all
three parameter tables. Shorten the hint to an `Example:` clause that fits the
existing column width and pad the cells accordingly, keeping the README stable
across regeneration.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:28:52 +02:00
volker.raschekandCopilot 41d06e4e6d feat!: apply subject alternative names to root and intermediate CA
The variables `certificate_authority_root_ca_subject_alternative_names` and
`certificate_authority_intermediate_ca_subject_alternative_names` were
documented but never referenced by any task, so both CA certificates were always
issued without SANs. Wire them into the corresponding CSR tasks and fall back to
`omit` when the list is empty.

SAN entries are now passed to `openssl_csr` unchanged instead of being prefixed
with `DNS:` by the role. This allows other types such as `IP:` or `email:`,
which the previous rewrite would have corrupted into values like `DNS:IP:...`.
The client tasks additionally dropped `join(',') | quote`, because `quote`
performs shell escaping and `openssl_csr` expects a list.

Since both client CSR tasks only differed in `subject_alt_name`, they collapse
into a single task per file.

BREAKING CHANGE: Entries of all `*_subject_alternative_names` variables must now
carry their type prefix, for example `DNS:example.local` instead of
`example.local`.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:28:52 +02:00
volker.raschekandCopilot 38ab2f55bb fix: drop passphrase from CSR task for unencrypted client key
This task file is only included when
`certificate_authority_client_tls_key_passphrase` is empty, so the private key
is created without encryption. Passing the empty passphrase to `openssl_csr`
made the module attempt to decrypt an unencrypted key instead of treating it as
absent. The sibling CSR task for certificates with SANs already omitted the
attribute, so this also aligns both code paths.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:28:52 +02:00
volker.raschekandCopilot 309c5e0e65 fix: use client path instead of certificate content as destination
The task importing the client certificate passed
`certificate_authority_client_tls_crt_content` to `dest`, so the PEM payload
itself was interpreted as a directory path. The certificate was written to a
bogus location derived from its own content instead of the configured client
directory. Use `certificate_authority_client_path` as destination, consistent
with the private key import above.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:28:52 +02:00
volker.raschekandCopilot 32bd44a0a6 fix: use declared variable for client private key destination
The task importing the client private key referenced
`certificate_authority_client_ca_path`, a variable that is declared neither in
`defaults/main.yaml` nor in `meta/argument_specs.yaml`. Every run with
`certificate_authority_client_create: false` therefore aborted with an undefined
variable error before the key was written. Use the actual role variable
`certificate_authority_client_path` instead.

Co-authored-by: Copilot <copilot@github.com>
2026-09-07 22:28:52 +02:00
volker.raschek b112672d5a fix(tasks): create passphrase protected client certificate 2026-09-07 22:28:52 +02:00
CSRBot b54b1774bd Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.8.0' (#33) from renovate/ansible-ansible-lint-26.x into master
Ansible Linter / ansible-lint (push) Successful in 35s
Lint Markdown files / markdown-lint (push) Successful in 12s
2026-08-12 09:04:28 +00:00
CSRBot 12abfefb62 chore(deps): update ansible/ansible-lint action to v26.8.0
Ansible Linter / ansible-lint (push) Successful in 2m12s
Lint Markdown files / markdown-lint (push) Successful in 6s
Ansible Linter / ansible-lint (pull_request) Successful in 35s
Lint Markdown files / markdown-lint (pull_request) Successful in 6s
2026-08-12 09:00:54 +00:00
CSRBot dd3529f21c chore(deps): update dependency markdownlint-cli to ^0.49.0
Lint Markdown files / markdown-lint (pull_request) Successful in 7s
Ansible Linter / ansible-lint (pull_request) Successful in 1m24s
Ansible Linter / ansible-lint (push) Failing after 0s
Lint Markdown files / markdown-lint (push) Failing after 1s
2026-07-20 21:04:16 +00:00
CSRBot 3ea8c4ac71 Merge pull request 'chore(deps): update actions/checkout action to v6.1.0' (#32) from renovate/actions-checkout-6.x into master
Ansible Linter / ansible-lint (push) Successful in 47s
Lint Markdown files / markdown-lint (push) Successful in 8s
2026-07-20 18:03:02 +00:00
CSRBot 770a17eb70 chore(deps): update actions/checkout action to v6.1.0
Lint Markdown files / markdown-lint (push) Successful in 25s
Ansible Linter / ansible-lint (push) Successful in 2m31s
Ansible Linter / ansible-lint (pull_request) Successful in 1m13s
Lint Markdown files / markdown-lint (pull_request) Successful in 9s
2026-07-20 18:00:53 +00:00
CSRBot 08e022f22f Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.6.0' (#31) from renovate/ansible-ansible-lint-26.x into master
Ansible Linter / ansible-lint (push) Successful in 56s
Lint Markdown files / markdown-lint (push) Successful in 6s
2026-07-02 18:10:00 +00:00
CSRBot c45da244e6 chore(deps): update ansible/ansible-lint action to v26.6.0
Ansible Linter / ansible-lint (pull_request) Successful in 1m39s
Ansible Linter / ansible-lint (push) Successful in 1m20s
Lint Markdown files / markdown-lint (pull_request) Successful in 14s
Lint Markdown files / markdown-lint (push) Successful in 13s
2026-07-02 18:00:45 +00:00
CSRBot 10e7eedf7b chore(deps): pin dependencies
Ansible Linter / ansible-lint (pull_request) Successful in 29s
Lint Markdown files / markdown-lint (pull_request) Successful in 11s
Lint Markdown files / markdown-lint (push) Successful in 5s
Ansible Linter / ansible-lint (push) Successful in 1m13s
2026-06-05 12:00:56 +00:00
CSRBot 0aee93b6e5 Merge pull request 'chore(deps): update davidanson/markdownlint-cli2-action action to v23' (#28) from renovate/davidanson-markdownlint-cli2-action-23.x into master
Ansible Linter / ansible-lint (push) Successful in 38s
Lint Markdown files / markdown-lint (push) Failing after 14m38s
2026-06-04 15:05:53 +00:00
CSRBot 963fb67fba chore(deps): update davidanson/markdownlint-cli2-action action to v23
Ansible Linter / ansible-lint (push) Successful in 1m30s
Ansible Linter / ansible-lint (pull_request) Successful in 1m19s
Lint Markdown files / markdown-lint (push) Successful in 11s
Lint Markdown files / markdown-lint (pull_request) Successful in 13s
2026-06-04 15:00:56 +00:00
CSRBot 3021b2ebcc Merge pull request 'chore(deps): update actions/checkout action to v6.0.3' (#27) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 39s
Lint Markdown files / markdown-lint (push) Successful in 5s
2026-06-02 15:04:49 +00:00
CSRBot ec6bc687d1 chore(deps): update actions/checkout action to v6.0.3
Ansible Linter / ansible-lint (push) Successful in 30s
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (pull_request) Successful in 1m18s
Lint Markdown files / markdown-lint (pull_request) Successful in 11s
2026-06-02 15:00:45 +00:00
CSRBot d94d98fe99 Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.4.0' (#26) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 29s
Lint Markdown files / markdown-lint (push) Successful in 4s
2026-04-14 11:02:06 +00:00
CSRBot 79a361d8f6 chore(deps): update ansible/ansible-lint action to v26.4.0
Ansible Linter / ansible-lint (push) Successful in 27s
Lint Markdown files / markdown-lint (push) Successful in 6s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
Ansible Linter / ansible-lint (pull_request) Successful in 1m59s
2026-04-14 10:46:48 +00:00
CSRBot 07df95ec3e Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.3.0' (#25) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 11s
2026-03-05 14:02:06 +00:00
CSRBot b2befe080e chore(deps): update ansible/ansible-lint action to v26.3.0
Ansible Linter / ansible-lint (push) Successful in 20s
Ansible Linter / ansible-lint (pull_request) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 6s
Lint Markdown files / markdown-lint (pull_request) Successful in 5s
2026-03-05 14:00:37 +00:00
CSRBot 7515c64989 Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.2.0' (#23) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 21s
Lint Markdown files / markdown-lint (push) Successful in 6s
2026-02-25 17:19:34 +00:00
CSRBot d41201ead2 chore(deps): update ansible/ansible-lint action to v26.2.0
Ansible Linter / ansible-lint (push) Successful in 21s
Ansible Linter / ansible-lint (pull_request) Successful in 22s
Lint Markdown files / markdown-lint (push) Successful in 4s
Lint Markdown files / markdown-lint (pull_request) Successful in 5s
2026-02-25 17:17:19 +00:00
CSRBot 2c940f8026 Merge pull request 'chore(deps): update actions/checkout action to v6.0.2' (#22) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 5s
2026-01-22 17:05:51 +00:00
CSRBot 8bbeae0394 chore(deps): update actions/checkout action to v6.0.2
Ansible Linter / ansible-lint (push) Successful in 1m4s
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (pull_request) Successful in 1m3s
Lint Markdown files / markdown-lint (pull_request) Successful in 11s
2026-01-22 17:00:46 +00:00
CSRBot 62e02d0b6e Merge pull request 'chore(deps): update ansible/ansible-lint action to v26.1.1' (#21) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 5s
2026-01-16 05:01:58 +00:00
CSRBot de9a2d70b7 chore(deps): update ansible/ansible-lint action to v26.1.1
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (pull_request) Successful in 19s
Lint Markdown files / markdown-lint (pull_request) Successful in 9s
2026-01-16 05:00:32 +00:00
volker.raschek aca86c74ab docs(meta): add argument_specs
Lint Markdown files / markdown-lint (push) Successful in 5s
Ansible Linter / ansible-lint (push) Successful in 1m4s
Release Ansible Role / Release Ansible Role (push) Successful in 58s
2026-01-14 21:53:45 +01:00
CSRBot 708c02d4b4 chore(deps): update ansible/ansible-lint action to v26
Lint Markdown files / markdown-lint (pull_request) Successful in 10s
Ansible Linter / ansible-lint (pull_request) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 5s
Ansible Linter / ansible-lint (push) Successful in 1m7s
2026-01-11 23:00:30 +00:00
volker.raschek 2355a9b3ed fix(ci): add workflow dispatch for releases
Ansible Linter / ansible-lint (push) Successful in 21s
Lint Markdown files / markdown-lint (push) Successful in 5s
2026-01-11 21:15:33 +01:00
CSRBot eadc8f6962 chore(deps): update dependency markdownlint-cli to ^0.47.0
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 44s
2026-01-07 15:21:47 +00:00
volker.raschek 41fc9dd544 fix(ci): use dynamic github repository name
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
2026-01-07 16:11:05 +01:00
volker.raschek 580ddabd36 fix(ci): add release workflow
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
2026-01-07 16:05:28 +01:00
volker.raschek f9f3968b68 fix: replace deprecated INJECT_FACTS_AS_VARS
Ansible Linter / ansible-lint (push) Successful in 18s
Lint Markdown files / markdown-lint (push) Successful in 5s
2026-01-05 10:26:11 +01:00
CSRBot e985a8bc3d Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.12.2' (#19) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 18s
Lint Markdown files / markdown-lint (push) Successful in 5s
2025-12-22 20:01:55 +00:00
CSRBot be8286448e chore(deps): update ansible/ansible-lint action to v25.12.2
Ansible Linter / ansible-lint (push) Successful in 19s
Ansible Linter / ansible-lint (pull_request) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 5s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
2025-12-22 20:00:31 +00:00
CSRBot d443cb1a0b Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.12.1' (#18) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
2025-12-10 14:02:23 +00:00
CSRBot 2a6292d5db chore(deps): update ansible/ansible-lint action to v25.12.1
Ansible Linter / ansible-lint (pull_request) Successful in 20s
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (pull_request) Successful in 5s
Lint Markdown files / markdown-lint (push) Successful in 5s
2025-12-10 14:00:35 +00:00
CSRBot 94f0cf4bee Merge pull request 'chore(deps): update actions/checkout action to v6' (#17) from renovate/actions-checkout-6.x into master
Ansible Linter / ansible-lint (push) Successful in 1m3s
Lint Markdown files / markdown-lint (push) Successful in 11s
2025-12-02 21:05:22 +00:00
CSRBot c8d44a6d00 chore(deps): update actions/checkout action to v6
Ansible Linter / ansible-lint (push) Successful in 1m3s
Ansible Linter / ansible-lint (pull_request) Successful in 1m5s
Lint Markdown files / markdown-lint (push) Successful in 10s
Lint Markdown files / markdown-lint (pull_request) Successful in 8s
2025-12-02 21:00:44 +00:00
CSRBot 9fd12d9809 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.12.0' (#16) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
2025-12-02 17:01:20 +00:00
CSRBot a4554b72c2 chore(deps): update ansible/ansible-lint action to v25.12.0
Ansible Linter / ansible-lint (pull_request) Successful in 19s
Lint Markdown files / markdown-lint (pull_request) Successful in 5s
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 4s
2025-12-02 17:00:29 +00:00
CSRBot 5a4b487779 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.11.1' (#15) from renovate/actions into master
Lint Markdown files / markdown-lint (push) Successful in 12s
Ansible Linter / ansible-lint (push) Successful in 19s
2025-11-24 23:01:58 +00:00
CSRBot be8a4d32d0 chore(deps): update ansible/ansible-lint action to v25.11.1
Ansible Linter / ansible-lint (pull_request) Successful in 20s
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
Lint Markdown files / markdown-lint (push) Successful in 5s
2025-11-24 23:00:34 +00:00
volker.raschek 972c43c8fa fix: rename files to .yaml
Ansible Linter / ansible-lint (push) Successful in 21s
Lint Markdown files / markdown-lint (push) Successful in 5s
2025-11-23 16:14:35 +01:00
CSRBot 3c77bd5999 Merge pull request 'chore(deps): update davidanson/markdownlint-cli2-action action to v21' (#12) from renovate/davidanson-markdownlint-cli2-action-21.x into master
Ansible Linter / ansible-lint (push) Successful in 1m4s
Lint Markdown files / markdown-lint (push) Successful in 10s
2025-11-18 17:00:41 +00:00
CSRBot 8ebcea867b chore(deps): update davidanson/markdownlint-cli2-action action to v21
Ansible Linter / ansible-lint (push) Successful in 1m2s
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (pull_request) Successful in 1m4s
Lint Markdown files / markdown-lint (pull_request) Successful in 10s
2025-11-17 20:00:37 +00:00
CSRBot 5d1e67786d Merge pull request 'chore(deps): update actions/checkout action to v5.0.1' (#13) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 1m4s
Lint Markdown files / markdown-lint (push) Successful in 10s
2025-11-17 17:05:37 +00:00
CSRBot 3b7dee1bbc chore(deps): update actions/checkout action to v5.0.1
Ansible Linter / ansible-lint (pull_request) Successful in 1m4s
Ansible Linter / ansible-lint (push) Successful in 1m5s
Lint Markdown files / markdown-lint (pull_request) Successful in 11s
Lint Markdown files / markdown-lint (push) Successful in 8s
2025-11-17 17:00:41 +00:00
CSRBot bc4627cccf Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.11.0' (#11) from renovate/actions into master
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Successful in 18s
2025-11-10 14:02:21 +00:00
CSRBot b2848e76d2 chore(deps): update ansible/ansible-lint action to v25.11.0
Ansible Linter / ansible-lint (push) Successful in 18s
Ansible Linter / ansible-lint (pull_request) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 5s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
2025-11-10 14:00:43 +00:00
CSRBot 93f20bb614 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.9.2' (#10) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 1m4s
Lint Markdown files / markdown-lint (push) Successful in 5s
2025-10-08 13:01:58 +00:00
CSRBot e7a60501f0 chore(deps): update ansible/ansible-lint action to v25.9.2
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (pull_request) Successful in 18s
Lint Markdown files / markdown-lint (pull_request) Successful in 5s
2025-10-08 13:00:45 +00:00
CSRBot 609eb4bc06 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.9.1' (#9) from renovate/actions into master
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (push) Successful in 1m5s
2025-10-01 13:02:15 +00:00
CSRBot f14fda1ed0 chore(deps): update ansible/ansible-lint action to v25.9.1
Ansible Linter / ansible-lint (push) Successful in 20s
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (pull_request) Successful in 18s
Lint Markdown files / markdown-lint (pull_request) Successful in 10s
2025-10-01 13:00:46 +00:00
CSRBot e3ab2af58d Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.9.0' (#7) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 19s
Lint Markdown files / markdown-lint (push) Successful in 4s
2025-09-19 20:01:31 +00:00
CSRBot 8b45a728d1 chore(deps): update ansible/ansible-lint action to v25.9.0
Lint Markdown files / markdown-lint (push) Successful in 12s
Lint Markdown files / markdown-lint (pull_request) Successful in 10s
Ansible Linter / ansible-lint (push) Successful in 22s
Ansible Linter / ansible-lint (pull_request) Successful in 1m8s
2025-09-18 22:01:06 +00:00
volker.raschek e38f894c8f chore(deps): update actions/checkout to v5.0.0
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (push) Successful in 17s
2025-09-18 22:31:07 +02:00
CSRBot 3432d1dc89 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.8.2' (#6) from renovate/actions into master
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (push) Successful in 49s
2025-08-21 16:01:33 +00:00
CSRBot 42b3e7a5db chore(deps): update ansible/ansible-lint action to v25.8.2
Lint Markdown files / markdown-lint (push) Successful in 4s
Ansible Linter / ansible-lint (pull_request) Successful in 16s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
Ansible Linter / ansible-lint (push) Successful in 1m22s
2025-08-21 16:00:48 +00:00
CSRBot 3344723187 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.8.1' (#5) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 16s
Lint Markdown files / markdown-lint (push) Successful in 18s
2025-08-14 01:01:42 +00:00
CSRBot 085ad44e8f chore(deps): update ansible/ansible-lint action to v25.8.1
Ansible Linter / ansible-lint (push) Successful in 25s
Lint Markdown files / markdown-lint (push) Successful in 3s
Ansible Linter / ansible-lint (pull_request) Successful in 16s
Lint Markdown files / markdown-lint (pull_request) Successful in 4s
2025-08-14 01:00:42 +00:00
CSRBot 786a4e9385 Merge pull request 'chore(deps): update ansible/ansible-lint action to v25.8.0' (#4) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 16s
Lint Markdown files / markdown-lint (push) Successful in 22s
2025-08-13 16:01:32 +00:00
CSRBot 75241aa759 chore(deps): update ansible/ansible-lint action to v25.8.0
Ansible Linter / ansible-lint (push) Successful in 16s
Lint Markdown files / markdown-lint (push) Successful in 4s
Lint Markdown files / markdown-lint (pull_request) Successful in 14s
Ansible Linter / ansible-lint (pull_request) Successful in 15s
2025-08-13 16:00:40 +00:00
CSRBot f9592e9a03 Merge pull request 'chore(deps): update actions/checkout action to v4.3.0' (#2) from renovate/actions into master
Ansible Linter / ansible-lint (push) Successful in 1m3s
Lint Markdown files / markdown-lint (push) Successful in 10s
2025-08-11 13:07:07 +00:00
CSRBot a71af04b83 chore(deps): update actions/checkout action to v4.3.0
Ansible Linter / ansible-lint (push) Successful in 1m1s
Lint Markdown files / markdown-lint (push) Successful in 9s
Ansible Linter / ansible-lint (pull_request) Successful in 1m0s
Lint Markdown files / markdown-lint (pull_request) Successful in 10s
2025-08-11 13:01:17 +00:00
CSRBot 60e11b1276 Merge pull request 'Update ansible/ansible-lint action to v25.7.0' (#1) from renovate/actions into master
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (push) Successful in 1m1s
2025-08-06 16:02:03 +00:00
CSRBot dfac82a1f8 chore(deps): update ansible/ansible-lint action to v25.7.0
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Successful in 38s
Lint Markdown files / markdown-lint (pull_request) Successful in 13s
Ansible Linter / ansible-lint (pull_request) Successful in 1m0s
2025-08-06 16:00:40 +00:00
volker.raschek 594325b852 fix(ansible-galaxy): adapt indentation
Ansible Linter / ansible-lint (push) Successful in 43s
Lint Markdown files / markdown-lint (push) Successful in 11s
2025-08-06 16:10:23 +02:00
volker.raschek f3e818b07c fix(ansible-galaxy): add namespace
Ansible Linter / ansible-lint (push) Failing after 42s
Lint Markdown files / markdown-lint (push) Successful in 11s
2025-08-06 15:22:26 +02:00
volker.raschek 29c166acda fix(ansible-galaxy): adapt list of supported platforms
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (push) Failing after 37s
2025-08-06 11:44:49 +02:00
volker.raschek a14c799290 fix(ansible-galaxy): remove namespace
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Failing after 31s
2025-08-06 11:39:09 +02:00
volker.raschek 6208d55dcb fix(linter): be compliant with ansible-linter
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Successful in 33s
2025-08-06 10:55:42 +02:00
volker.raschek ac6f54d360 fix(galaxy): change namespace from volker-raschek to volker_raschek
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Failing after 45s
2025-08-06 10:53:30 +02:00
volker.raschek 9267a743e7 docs(README): update documentation
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Failing after 59s
2025-07-31 19:12:06 +02:00
volker.raschek ef2c31e64e fix: remove state
Lint Markdown files / markdown-lint (push) Successful in 11s
Ansible Linter / ansible-lint (push) Failing after 41s
2025-07-31 19:08:10 +02:00
volker.raschek 1c40b1d59b feat: support further TLS certification properties
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Failing after 46s
2025-07-31 18:46:19 +02:00
volker.raschek c3fb49bbd4 fix(root_ca): set passphrase correctly
Lint Markdown files / markdown-lint (push) Successful in 13s
Ansible Linter / ansible-lint (push) Failing after 57s
2025-07-31 11:56:27 +02:00
volker.raschek 61b0a7c9ec fix: set cipher correctly
Ansible Linter / ansible-lint (push) Failing after 59s
Lint Markdown files / markdown-lint (push) Successful in 11s
2025-07-31 09:53:01 +02:00
volker.raschek dbbaacdc69 fix(root_ca): set passphrase correctly
Lint Markdown files / markdown-lint (push) Successful in 10s
Ansible Linter / ansible-lint (push) Failing after 1m0s
2025-07-31 09:49:12 +02:00
volker.raschek 505f0450d4 fix(intermediate_ca): set passphrase correctly
Lint Markdown files / markdown-lint (push) Has been cancelled
Ansible Linter / ansible-lint (push) Has been cancelled
2025-07-31 09:48:51 +02:00
45 changed files with 1144 additions and 890 deletions
-20
View File
@@ -1,20 +0,0 @@
name: Ansible Linter
on:
pull_request:
types: [ "opened", "reopened", "synchronize" ]
push:
branches: [ '**' ]
tags-ignore: [ '**' ]
jobs:
ansible-lint:
runs-on:
- ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ansible-lint
uses: ansible/ansible-lint@v25.6.1
with:
args: "--config-file .ansible-lint"
setup_python: "true"
+22
View File
@@ -0,0 +1,22 @@
name: Ansible Linter
on:
pull_request:
types: [ "opened", "reopened", "synchronize" ]
push:
branches: [ '**' ]
tags-ignore: [ '**' ]
jobs:
ansible-lint:
runs-on:
- ubuntu-latest
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Run ansible-lint
uses: ansible/ansible-lint@665d9e07a1943254d2910faffc106adaf7ea7294 # v26.8.0
with:
args: "--config-file .ansible-lint"
# The molecule scenario is linted as well, so its collections are required beside the ones of the role.
requirements_file: "molecule/default/collections.yml"
setup_python: "true"
@@ -12,7 +12,7 @@ jobs:
runs-on:
- ubuntu-latest
steps:
- uses: actions/checkout@v4.2.2
- uses: DavidAnson/markdownlint-cli2-action@v20.0.0
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- uses: DavidAnson/markdownlint-cli2-action@ded1f9488f68a970bc66ea5619e13e9b52e601cd # v23.2.0
with:
globs: '**/*.md'
+30
View File
@@ -0,0 +1,30 @@
name: Molecule
on:
pull_request:
types: [ "opened", "reopened", "synchronize" ]
push:
branches: [ '**' ]
tags-ignore: [ '**' ]
permissions:
contents: read
jobs:
molecule:
name: Molecule
runs-on: ubuntu-latest-amd64
steps:
# The scenario includes the role by its name, so the directory must be named like the role and not like the
# repository. Its parent is used as roles path.
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
path: certificate_authority
- name: Install molecule
run: |
apt update --yes
apt install --yes python3-pip
pip3 install --break-system-packages molecule docker
- name: Run molecule
run: molecule test
working-directory: certificate_authority
+22
View File
@@ -0,0 +1,22 @@
name: Release Ansible Role
on:
push:
tags:
- '**'
workflow_dispatch: {}
jobs:
release:
name: Release Ansible Role
runs-on: ubuntu-latest
steps:
- name: Install Ansible Galaxy
run: |
apt update --yes
apt install --yes ansible
- env:
ANSIBLE_GALAXY_TOKEN: ${{ secrets.ANSIBLE_GALAXY_TOKEN }}
name: Update Ansible Role in Ansible Galaxy
run: |
ansible-galaxy role import --token=${ANSIBLE_GALAXY_TOKEN} volker-raschek ${GITHUB_REPOSITORY#*/}
+11
View File
@@ -0,0 +1,11 @@
{
"ansible.python.interpreterPath": "/bin/python",
"files.associations": {
"**/.gitea/**/*.yml": "yaml",
"docker-compose*.yml": "dockercompose",
"*.yml": "ansible",
".yamllint": "yaml",
".yamllint.yml": "yaml"
},
"rewrap.wrappingColumn": 120
}
+83 -17
View File
@@ -4,6 +4,20 @@ This Ansible role can be used to create a root and intermediate certificate auth
them. Additionally offers the ansible role the feature to import the certificates of the authority into the systems
trust store.
## Requirements
The role relies on the modules of the collection `community.crypto`. On Archlinux the collection `community.general`
is additionally required, because it provides the `pacman` module.
```bash
ansible-galaxy collection install -r requirements.yml
```
Facts must be gathered, because the names of the required python packages, the location of the trust store anchor and
the command to update the trust store are looked up by `ansible_facts['distribution']`, `ansible_facts['os_family']`
and `ansible_facts['architecture']`. Archlinux, Debian and RedHat based distributions are supported. Furthermore the
role writes into `/etc` and updates the systems trust store, so it has to be executed with `become: true`.
## Examples
The following minimal example creates a root and intermediate certificate authority and issues a client certificate from
@@ -13,8 +27,45 @@ the intermediate certificate authority.
certificate_authority_client_skip: false
certificate_authority_client_common_name: "{{ inventory_hostname }}"
certificate_authority_client_subject_alternative_names:
- "{{ inventory_hostname }}"
- san.example.local
- "DNS:{{ inventory_hostname }}"
- "DNS:san.example.local"
- "IP:10.11.12.13"
```
## Tests
The role is tested with [Molecule](https://ansible.readthedocs.io/projects/molecule/). The scenario starts one docker
container per supported distribution family, applies the role, asserts that a second run reports no change and finally
verifies the issued certificates with `openssl verify`, their file permissions and the anchor in the systems trust
store.
Molecule ships only its `default` driver, therefore `docker` is required besides molecule itself. The collections are
declared in `molecule/default/collections.yml` and installed by molecule.
```bash
pip install molecule docker
```
The complete sequence creates the containers, tests them and removes them afterwards.
```bash
molecule test
```
While working on the role the containers are better kept alive.
```bash
# create the containers and apply the role
molecule converge
# run the assertions of molecule/default/verify.yml against the running containers
molecule verify
# open a shell in one of the containers
molecule login --host certificate-authority-debian
# remove the containers
molecule destroy
```
## Parameters
@@ -28,7 +79,12 @@ certificate_authority_client_subject_alternative_names:
| `certificate_authority_root_ca_import` | Import the TLS certificate of the root certificate authority into the systems trust store. | `true` |
| `certificate_authority_root_ca_path` | Directory where the private and public TLS key of the root certificate authority should be stored. | `/etc/ansible-playbook/pki/ca` |
| `certificate_authority_root_ca_common_name` | Common Name (CN) of the root certificate authority. | `Ansible Root CA` |
| `certificate_authority_root_ca_subject_alternative_names` | Subject Alternative Names (SAN) of the root certificate authority. | `[]` |
| `certificate_authority_root_ca_country_name` | Country name of the root certificate authority. For example `US`, `FR` or `DE`. | `""` |
| `certificate_authority_root_ca_email_address` | E-Mail Address of the root certificate authority owner. | `""` |
| `certificate_authority_root_ca_organization_name` | Organization name of the root certificate authority owner. | `""` |
| `certificate_authority_root_ca_organizational_unit_name` | Organizational unit name of the root certificate authority. | `""` |
| `certificate_authority_root_ca_state_or_province_name` | State or province name where the owner of the root certificate authority is located. | `""` |
| `certificate_authority_root_ca_subject_alternative_names` | Subject Alternative Names (SAN) of the root certificate authority. Example: `DNS:example.local`, `IP:10.11.12.13`. | `[]` |
| `certificate_authority_root_ca_not_after` | Time in the future from now when the TLS certificate should expire | `+3650d` |
| `certificate_authority_root_ca_not_before` | Time in the past from now when the TLS certificate should be valid. | `+0s` |
| `certificate_authority_root_ca_tls_key_content` | Content of a custom used root certificate authority. Will only be imported, when `certificate_authority_root_ca_create: false`. | `""` |
@@ -44,7 +100,12 @@ certificate_authority_client_subject_alternative_names:
| `certificate_authority_intermediate_ca_create` | Create intermediate certificate from scratch or import via `certificate_authority_intermediate_ca_tls` prefixed variables. | `true` |
| `certificate_authority_intermediate_ca_path` | Directory where the private and public TLS key of the intermediate certificate authority should be stored. | `/etc/ansible-playbook/pki/intermediate` |
| `certificate_authority_intermediate_ca_common_name` | Common Name (CN) of the intermediate certificate authority. | `Ansible Intermediate CA` |
| `certificate_authority_intermediate_ca_subject_alternative_names` | Subject Alternative Names (SAN) of the intermediate certificate authority. | `[]` |
| `certificate_authority_intermediate_ca_country_name` | Country name of the intermediate certificate authority. For example `US`, `FR` or `DE`. | `""` |
| `certificate_authority_intermediate_ca_email_address` | E-Mail Address of the intermediate certificate authority owner. | `""` |
| `certificate_authority_intermediate_ca_organization_name` | Organization name of the intermediate certificate authority owner. | `""` |
| `certificate_authority_intermediate_ca_organizational_unit_name` | Organizational unit name of the intermediate certificate authority. | `""` |
| `certificate_authority_intermediate_ca_state_or_province_name` | State or province name where the owner of the intermediate certificate authority is located. | `""` |
| `certificate_authority_intermediate_ca_subject_alternative_names` | Subject Alternative Names (SAN) of the intermediate certificate authority. Example: `DNS:example.local`, `IP:10.11.12.13`. | `[]` |
| `certificate_authority_intermediate_ca_not_after` | Time in the future from now when the TLS certificate should expire | `+1825d` |
| `certificate_authority_intermediate_ca_not_before` | Time in the past from now when the TLS certificate should be valid. | `+0s` |
| `certificate_authority_intermediate_ca_tls_key_content` | Content of a custom used intermediate certificate authority. Will only be imported, when `certificate_authority_intermediate_ca_create: false`. | `""` |
@@ -54,16 +115,21 @@ certificate_authority_client_subject_alternative_names:
### Client Certificate
| Name | Description | Value |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `certificate_authority_client_skip` | Skip creation or import of a client certificate in general. | `true` |
| `certificate_authority_client_create` | Create client certificate from scratch or import via `certificate_authority_client_tls` prefixed variables. | `true` |
| `certificate_authority_client_path` | Directory where the private and public TLS key of the client certificate authority should be stored. | `/etc/ansible-playbook/pki/client` |
| `certificate_authority_client_common_name` | Common Name (CN) of the client certificate. | `Ansible Client Certificate` |
| `certificate_authority_client_subject_alternative_names` | Subject Alternative Names (SAN) of the client certificate. | `[]` |
| `certificate_authority_client_not_after` | Time in the future from now when the TLS certificate should expire | `+397d` |
| `certificate_authority_client_not_before` | Time in the past from now when the TLS certificate should be valid. | `+0s` |
| `certificate_authority_client_tls_key_passphrase` | Passphrase for the private key of the generated or imported client certificate. | `""` |
| `certificate_authority_client_tls_key_type` | Algorithm of the private key of the client certificate. | `RSA` |
| `certificate_authority_client_tls_crt_content` | Passphrase for the private key of the generated or imported client certificate. | `""` |
| `certificate_authority_client_tls_key_content` | Algorithm of the private key of the client certificate | `""` |
| Name | Description | Value |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `certificate_authority_client_skip` | Skip creation or import of a client certificate in general. | `true` |
| `certificate_authority_client_create` | Create client certificate from scratch or import via `certificate_authority_client_tls` prefixed variables. | `true` |
| `certificate_authority_client_path` | Directory where the private and public TLS key of the client certificate authority should be stored. | `/etc/ansible-playbook/pki/client` |
| `certificate_authority_client_common_name` | Common Name (CN) of the client certificate. | `Ansible Client Certificate` |
| `certificate_authority_client_country_name` | Country name of the client certificate. For example `US`, `FR` or `DE`. | `""` |
| `certificate_authority_client_email_address` | E-Mail Address of the client certificate owner. | `""` |
| `certificate_authority_client_organization_name` | Organization name of the client certificate owner. | `""` |
| `certificate_authority_client_organizational_unit_name` | Organizational unit name of the client certificate. | `""` |
| `certificate_authority_client_state_or_province_name` | State or province name where the owner of the client certificate is located. | `""` |
| `certificate_authority_client_subject_alternative_names` | Subject Alternative Names (SAN) of the client certificate. Example: `DNS:example.local`, `IP:10.11.12.13`. | `[]` |
| `certificate_authority_client_not_after` | Time in the future from now when the TLS certificate should expire | `+397d` |
| `certificate_authority_client_not_before` | Time in the past from now when the TLS certificate should be valid. | `+0s` |
| `certificate_authority_client_tls_key_passphrase` | Passphrase for the private key of the generated or imported client certificate. | `""` |
| `certificate_authority_client_tls_key_type` | Algorithm of the private key of the client certificate. | `RSA` |
| `certificate_authority_client_tls_crt_content` | Content of a custom used client certificate. Will only be imported, when `certificate_authority_client_create: false`. | `""` |
| `certificate_authority_client_tls_key_content` | Content of the private key of a custom used client certificate. Will only be imported, when `certificate_authority_client_create: false`. | `""` |
+35 -5
View File
@@ -10,11 +10,21 @@ certificate_authority_root_ca_import: true
## @param certificate_authority_root_ca_path Directory where the private and public TLS key of the root certificate authority should be stored.
## @param certificate_authority_root_ca_common_name Common Name (CN) of the root certificate authority.
## @param certificate_authority_root_ca_subject_alternative_names Subject Alternative Names (SAN) of the root certificate authority.
## @param certificate_authority_root_ca_country_name Country name of the root certificate authority. For example `US`, `FR` or `DE`.
## @param certificate_authority_root_ca_email_address E-Mail Address of the root certificate authority owner.
## @param certificate_authority_root_ca_organization_name Organization name of the root certificate authority owner.
## @param certificate_authority_root_ca_organizational_unit_name Organizational unit name of the root certificate authority.
## @param certificate_authority_root_ca_state_or_province_name State or province name where the owner of the root certificate authority is located.
## @param certificate_authority_root_ca_subject_alternative_names Subject Alternative Names (SAN) of the root certificate authority. Example: `DNS:example.local`, `IP:10.11.12.13`.
## @param certificate_authority_root_ca_not_after Time in the future from now when the TLS certificate should expire
## @param certificate_authority_root_ca_not_before Time in the past from now when the TLS certificate should be valid.
certificate_authority_root_ca_path: "/etc/ansible-playbook/pki/ca"
certificate_authority_root_ca_common_name: "Ansible Root CA"
certificate_authority_root_ca_country_name: ""
certificate_authority_root_ca_email_address: ""
certificate_authority_root_ca_organization_name: ""
certificate_authority_root_ca_organizational_unit_name: ""
certificate_authority_root_ca_state_or_province_name: ""
certificate_authority_root_ca_subject_alternative_names: []
certificate_authority_root_ca_not_after: "+3650d"
certificate_authority_root_ca_not_before: "+0s"
@@ -38,11 +48,21 @@ certificate_authority_intermediate_ca_create: true
## @param certificate_authority_intermediate_ca_path Directory where the private and public TLS key of the intermediate certificate authority should be stored.
## @param certificate_authority_intermediate_ca_common_name Common Name (CN) of the intermediate certificate authority.
## @param certificate_authority_intermediate_ca_subject_alternative_names Subject Alternative Names (SAN) of the intermediate certificate authority.
## @param certificate_authority_intermediate_ca_country_name Country name of the intermediate certificate authority. For example `US`, `FR` or `DE`.
## @param certificate_authority_intermediate_ca_email_address E-Mail Address of the intermediate certificate authority owner.
## @param certificate_authority_intermediate_ca_organization_name Organization name of the intermediate certificate authority owner.
## @param certificate_authority_intermediate_ca_organizational_unit_name Organizational unit name of the intermediate certificate authority.
## @param certificate_authority_intermediate_ca_state_or_province_name State or province name where the owner of the intermediate certificate authority is located.
## @param certificate_authority_intermediate_ca_subject_alternative_names Subject Alternative Names (SAN) of the intermediate certificate authority. Example: `DNS:example.local`, `IP:10.11.12.13`.
## @param certificate_authority_intermediate_ca_not_after Time in the future from now when the TLS certificate should expire
## @param certificate_authority_intermediate_ca_not_before Time in the past from now when the TLS certificate should be valid.
certificate_authority_intermediate_ca_path: "/etc/ansible-playbook/pki/intermediate"
certificate_authority_intermediate_ca_common_name: "Ansible Intermediate CA"
certificate_authority_intermediate_ca_country_name: ""
certificate_authority_intermediate_ca_email_address: ""
certificate_authority_intermediate_ca_organization_name: ""
certificate_authority_intermediate_ca_organizational_unit_name: ""
certificate_authority_intermediate_ca_state_or_province_name: ""
certificate_authority_intermediate_ca_subject_alternative_names: []
certificate_authority_intermediate_ca_not_after: "+1825d"
certificate_authority_intermediate_ca_not_before: "+0s"
@@ -66,11 +86,21 @@ certificate_authority_client_create: true
## @param certificate_authority_client_path Directory where the private and public TLS key of the client certificate authority should be stored.
## @param certificate_authority_client_common_name Common Name (CN) of the client certificate.
## @param certificate_authority_client_subject_alternative_names Subject Alternative Names (SAN) of the client certificate.
## @param certificate_authority_client_country_name Country name of the client certificate. For example `US`, `FR` or `DE`.
## @param certificate_authority_client_email_address E-Mail Address of the client certificate owner.
## @param certificate_authority_client_organization_name Organization name of the client certificate owner.
## @param certificate_authority_client_organizational_unit_name Organizational unit name of the client certificate.
## @param certificate_authority_client_state_or_province_name State or province name where the owner of the client certificate is located.
## @param certificate_authority_client_subject_alternative_names Subject Alternative Names (SAN) of the client certificate. Example: `DNS:example.local`, `IP:10.11.12.13`.
## @param certificate_authority_client_not_after Time in the future from now when the TLS certificate should expire
## @param certificate_authority_client_not_before Time in the past from now when the TLS certificate should be valid.
certificate_authority_client_path: "/etc/ansible-playbook/pki/client"
certificate_authority_client_common_name: "Ansible Client Certificate"
certificate_authority_client_country_name: ""
certificate_authority_client_email_address: ""
certificate_authority_client_organization_name: ""
certificate_authority_client_organizational_unit_name: ""
certificate_authority_client_state_or_province_name: ""
certificate_authority_client_subject_alternative_names: []
certificate_authority_client_not_after: "+397d"
certificate_authority_client_not_before: "+0s"
@@ -80,7 +110,7 @@ certificate_authority_client_not_before: "+0s"
certificate_authority_client_tls_key_passphrase: ""
certificate_authority_client_tls_key_type: "RSA"
## @param certificate_authority_client_tls_crt_content Passphrase for the private key of the generated or imported client certificate.
## @param certificate_authority_client_tls_key_content Algorithm of the private key of the client certificate
## @param certificate_authority_client_tls_crt_content Content of a custom used client certificate. Will only be imported, when `certificate_authority_client_create: false`.
## @param certificate_authority_client_tls_key_content Content of the private key of a custom used client certificate. Will only be imported, when `certificate_authority_client_create: false`.
certificate_authority_client_tls_crt_content: ""
certificate_authority_client_tls_key_content: ""
+8
View File
@@ -0,0 +1,8 @@
---
- name: Update systems SSL/TLS trust store
ansible.builtin.command:
cmd: "{{ certificate_authority_trust_store_update_command }}"
changed_when: true
when: certificate_authority_root_ca_import is defined and
certificate_authority_root_ca_import
+228
View File
@@ -0,0 +1,228 @@
---
argument_specs:
main:
short_description: "Role to create and manage an existing PKI infrastructure"
description:
- "This Ansible role can be used to create a root and intermediate certificate authority and issue client certificates from them."
- "Additionally offers the ansible role the feature to import the certificates of the authority into the systems trust store."
author: "Markus Pesch"
options:
# Root Certificate Authority (CA)
certificate_authority_root_ca_skip:
description: "Skip creation or import of a root certificate authority in general."
type: bool
default: false
certificate_authority_root_ca_create:
description: "Create root certificate from scratch or import via certificate_authority_root_ca_tls prefixed variables."
type: bool
default: true
certificate_authority_root_ca_import:
description: "Import the TLS certificate of the root certificate authority into the systems trust store."
type: bool
default: true
certificate_authority_root_ca_path:
description: "Directory where the private and public TLS key of the root certificate authority should be stored."
type: str
default: "/etc/ansible-playbook/pki/ca"
certificate_authority_root_ca_common_name:
description: "Common Name (CN) of the root certificate authority."
type: str
default: "Ansible Root CA"
certificate_authority_root_ca_country_name:
description: "Country name of the root certificate authority. For example US, FR or DE."
type: str
default: ""
certificate_authority_root_ca_email_address:
description: "E-Mail Address of the root certificate authority owner."
type: str
default: ""
certificate_authority_root_ca_organization_name:
description: "Organization name of the root certificate authority owner."
type: str
default: ""
certificate_authority_root_ca_organizational_unit_name:
description: "Organizational unit name of the root certificate authority."
type: str
default: ""
certificate_authority_root_ca_state_or_province_name:
description: "State or province name where the owner of the root certificate authority is located."
type: str
default: ""
certificate_authority_root_ca_subject_alternative_names:
description: "Subject Alternative Names (SAN) of the root certificate authority. Example: DNS:example.local, IP:10.11.12.13."
type: list
elements: str
default: []
certificate_authority_root_ca_not_after:
description: "Time in the future from now when the TLS certificate should expire"
type: str
default: "+3650d"
certificate_authority_root_ca_not_before:
description: "Time in the past from now when the TLS certificate should be valid."
type: str
default: "+0s"
certificate_authority_root_ca_tls_key_content:
description: "Content of a custom used root certificate authority. Will only be imported, when certificate_authority_root_ca_create: false."
type: str
default: ""
certificate_authority_root_ca_tls_crt_content:
description: "Content of a custom used certificate of the certificate authority. Will only be imported, when certificate_authority_root_ca_create: false."
type: str
default: ""
certificate_authority_root_ca_tls_key_passphrase:
description: "Passphrase for the private key of the generated or imported root certificate authority."
type: str
default: ""
no_log: true
certificate_authority_root_ca_tls_key_type:
description: "Algorithm of the private key of the root certificate authority."
type: str
default: "RSA"
choices:
- RSA
- DSA
- ECC
# Intermediate Certificate Authority (CA)
certificate_authority_intermediate_ca_skip:
description: "Skip creation or import of a intermediate certificate authority in general."
type: bool
default: false
certificate_authority_intermediate_ca_create:
description: "Create intermediate certificate from scratch or import via certificate_authority_intermediate_ca_tls prefixed variables."
type: bool
default: true
certificate_authority_intermediate_ca_path:
description: "Directory where the private and public TLS key of the intermediate certificate authority should be stored."
type: str
default: "/etc/ansible-playbook/pki/intermediate"
certificate_authority_intermediate_ca_common_name:
description: "Common Name (CN) of the intermediate certificate authority."
type: str
default: "Ansible Intermediate CA"
certificate_authority_intermediate_ca_country_name:
description: "Country name of the intermediate certificate authority. For example US, FR or DE."
type: str
default: ""
certificate_authority_intermediate_ca_email_address:
description: "E-Mail Address of the intermediate certificate authority owner."
type: str
default: ""
certificate_authority_intermediate_ca_organization_name:
description: "Organization name of the intermediate certificate authority owner."
type: str
default: ""
certificate_authority_intermediate_ca_organizational_unit_name:
description: "Organizational unit name of the intermediate certificate authority."
type: str
default: ""
certificate_authority_intermediate_ca_state_or_province_name:
description: "State or province name where the owner of the intermediate certificate authority is located."
type: str
default: ""
certificate_authority_intermediate_ca_subject_alternative_names:
description: "Subject Alternative Names (SAN) of the intermediate certificate authority. Example: DNS:example.local, IP:10.11.12.13."
type: list
elements: str
default: []
certificate_authority_intermediate_ca_not_after:
description: "Time in the future from now when the TLS certificate should expire"
type: str
default: "+1825d"
certificate_authority_intermediate_ca_not_before:
description: "Time in the past from now when the TLS certificate should be valid."
type: str
default: "+0s"
certificate_authority_intermediate_ca_tls_key_content:
description: "Content of a custom used intermediate certificate authority. Will only be imported, when certificate_authority_intermediate_ca_create: false."
type: str
default: ""
certificate_authority_intermediate_ca_tls_crt_content:
description: "Content of a custom used certificate of the certificate authority. Will only be imported, when certificate_authority_intermediate_ca_create: false."
type: str
default: ""
certificate_authority_intermediate_ca_tls_key_passphrase:
description: "Passphrase for the private key of the generated or imported intermediate certificate authority."
type: str
default: ""
no_log: true
certificate_authority_intermediate_ca_tls_key_type:
description: "Algorithm of the private key of the intermediate certificate authority."
type: str
default: "RSA"
choices:
- RSA
- DSA
- ECC
# Client Certificate
certificate_authority_client_skip:
description: "Skip creation or import of a client certificate in general."
type: bool
default: true
certificate_authority_client_create:
description: "Create client certificate from scratch or import via certificate_authority_client_tls prefixed variables."
type: bool
default: true
certificate_authority_client_path:
description: "Directory where the private and public TLS key of the client certificate authority should be stored."
type: str
default: "/etc/ansible-playbook/pki/client"
certificate_authority_client_common_name:
description: "Common Name (CN) of the client certificate."
type: str
default: "Ansible Client Certificate"
certificate_authority_client_country_name:
description: "Country name of the client certificate. For example US, FR or DE."
type: str
default: ""
certificate_authority_client_email_address:
description: "E-Mail Address of the client certificate owner."
type: str
default: ""
certificate_authority_client_organization_name:
description: "Organization name of the client certificate owner."
type: str
default: ""
certificate_authority_client_organizational_unit_name:
description: "Organizational unit name of the client certificate."
type: str
default: ""
certificate_authority_client_state_or_province_name:
description: "State or province name where the owner of the client certificate is located."
type: str
default: ""
certificate_authority_client_subject_alternative_names:
description: "Subject Alternative Names (SAN) of the client certificate. Example: DNS:example.local, IP:10.11.12.13."
type: list
elements: str
default: []
certificate_authority_client_not_after:
description: "Time in the future from now when the TLS certificate should expire"
type: str
default: "+397d"
certificate_authority_client_not_before:
description: "Time in the past from now when the TLS certificate should be valid."
type: str
default: "+0s"
certificate_authority_client_tls_key_passphrase:
description: "Passphrase for the private key of the generated or imported client certificate."
type: str
default: ""
no_log: true
certificate_authority_client_tls_key_type:
description: "Algorithm of the private key of the client certificate."
type: str
default: "RSA"
choices:
- RSA
- DSA
- ECC
certificate_authority_client_tls_crt_content:
description: "Content of a custom used client certificate. Will only be imported, when certificate_authority_client_create: false."
type: str
default: ""
certificate_authority_client_tls_key_content:
description: "Content of the private key of a custom used client certificate. Will only be imported, when certificate_authority_client_create: false."
type: str
default: ""
+14 -13
View File
@@ -1,25 +1,26 @@
dependencies: []
galaxy_info:
namespace: volker-raschek
role_name: "certificate_authority"
author: "Markus Pesch"
description: "Role to create and managed an existing PKI infrastructure"
company: "Cryptic Systems"
description: "Role to create and manage an existing PKI infrastructure"
galaxy_tags:
- ca
- ssl
- tls
license: "MIT"
min_ansible_version: "2.9"
namespace: volker-raschek
platforms:
- name: ArchLinux
versions:
- all
- name: EL
versions:
- all
- name: Fedora
versions:
- all
- name: Ubuntu
versions:
- all
- name: Fedora
versions:
- "35"
galaxy_tags:
- certificate-authority
- ca
- ssl
- tls
dependencies: []
role_name: "certificate_authority"
+6
View File
@@ -0,0 +1,6 @@
---
collections:
- name: community.crypto
- name: community.docker
- name: community.general
+19
View File
@@ -0,0 +1,19 @@
---
- name: Converge
hosts: all
# Passphrases are fixtures, they exercise the protected code paths of the role.
vars:
certificate_authority_root_ca_common_name: "Molecule Root CA"
certificate_authority_root_ca_tls_key_passphrase: "molecule-root-ca"
certificate_authority_intermediate_ca_common_name: "Molecule Intermediate CA"
certificate_authority_intermediate_ca_tls_key_passphrase: "molecule-intermediate-ca"
certificate_authority_client_skip: false
certificate_authority_client_common_name: "molecule.example.local"
certificate_authority_client_subject_alternative_names:
- "DNS:molecule.example.local"
- "IP:10.11.12.13"
tasks:
- name: Include the role certificate_authority
ansible.builtin.include_role:
name: certificate_authority
+25
View File
@@ -0,0 +1,25 @@
---
- name: Create
hosts: localhost
gather_facts: false
tasks:
- name: Start a container per platform
community.docker.docker_container:
name: "{{ item.name }}"
image: "{{ item.image }}"
command: "sleep infinity"
state: started
loop: "{{ molecule_yml.platforms }}"
loop_control:
label: "{{ item.name }}"
- name: Write the instance config
ansible.builtin.copy:
content: |
{% for platform in molecule_yml.platforms %}
- instance: {{ platform.name }}
connection: community.docker.docker
{% endfor %}
dest: "{{ molecule_instance_config }}"
mode: "0600"
+19
View File
@@ -0,0 +1,19 @@
---
- name: Destroy
hosts: localhost
gather_facts: false
tasks:
- name: Remove the container of every platform
community.docker.docker_container:
name: "{{ item.name }}"
state: absent
loop: "{{ molecule_yml.platforms }}"
loop_control:
label: "{{ item.name }}"
- name: Empty the instance config
ansible.builtin.copy:
content: "[]"
dest: "{{ molecule_instance_config }}"
mode: "0600"
+24
View File
@@ -0,0 +1,24 @@
---
driver:
name: default
options:
managed: true
login_cmd_template: "docker exec --interactive --tty {instance} bash"
platforms:
- name: certificate-authority-archlinux
image: docker.io/library/archlinux:base
- name: certificate-authority-debian
image: docker.io/library/debian:13
- name: certificate-authority-fedora
image: registry.fedoraproject.org/fedora:43
provisioner:
name: ansible
# The role under test is the project directory itself, so its parent has to be on the roles path.
env:
ANSIBLE_ROLES_PATH: "${MOLECULE_PROJECT_DIRECTORY}/.."
config_options:
defaults:
interpreter_python: auto_silent
+22
View File
@@ -0,0 +1,22 @@
---
- name: Prepare
hosts: all
gather_facts: false
vars:
# The base images ship neither a python interpreter for ansible nor the tools the role shells out to.
_bootstrap: |
set -eu
if command -v pacman > /dev/null; then
pacman --sync --refresh --noconfirm ca-certificates gawk openssl python
elif command -v apt-get > /dev/null; then
apt-get update
apt-get install --yes ca-certificates gawk openssl python3
else
dnf install --assumeyes ca-certificates gawk openssl python3
fi
tasks:
# The raw command is wrapped explicitly, because the bootstrap relies on shell builtins.
- name: Bootstrap the python interpreter and the tools required by the role
ansible.builtin.raw: "/bin/sh -c {{ _bootstrap | quote }}"
changed_when: true
+4
View File
@@ -0,0 +1,4 @@
---
# The role has no role dependencies, but molecule warns about the missing file.
roles: []
+88
View File
@@ -0,0 +1,88 @@
---
- name: Verify
hosts: all
vars:
_root_ca_path: "/etc/ansible-playbook/pki/ca"
_intermediate_ca_path: "/etc/ansible-playbook/pki/intermediate"
_client_path: "/etc/ansible-playbook/pki/client"
# cert.pem and cert-req.pem are left out on purpose, the role does not pin their mode.
_expected_modes:
/etc/ansible-playbook/pki/ca: "0755"
/etc/ansible-playbook/pki/ca/privkey.pem: "0600"
/etc/ansible-playbook/pki/ca/all.pem: "0600"
/etc/ansible-playbook/pki/intermediate: "0755"
/etc/ansible-playbook/pki/intermediate/privkey.pem: "0600"
/etc/ansible-playbook/pki/intermediate/chain.pem: "0644"
/etc/ansible-playbook/pki/intermediate/fullchain.pem: "0644"
/etc/ansible-playbook/pki/intermediate/all.pem: "0600"
/etc/ansible-playbook/pki/client: "0755"
/etc/ansible-playbook/pki/client/privkey.pem: "0600"
/etc/ansible-playbook/pki/client/chain.pem: "0644"
/etc/ansible-playbook/pki/client/fullchain.pem: "0644"
/etc/ansible-playbook/pki/client/all.pem: "0600"
_trust_store_anchor:
Archlinux: "/etc/ca-certificates/trust-source/anchors/Molecule_Root_CA.pem"
Debian: "/usr/local/share/ca-certificates/Molecule_Root_CA.crt"
RedHat: "/etc/pki/ca-trust/source/anchors/Molecule_Root_CA.pem"
tasks:
- name: Stat the generated files
ansible.builtin.stat:
path: "{{ item.key }}"
register: _pki_files
loop: "{{ _expected_modes | dict2items }}"
loop_control:
label: "{{ item.key }}"
- name: Assert that the generated files exist with the expected mode
ansible.builtin.assert:
that:
- item.stat.exists
- item.stat.mode == item.item.value
fail_msg: "{{ item.item.key }} has mode {{ item.stat.mode | default('none') }} instead of {{ item.item.value }}"
loop: "{{ _pki_files.results }}"
loop_control:
label: "{{ item.item.key }}"
- name: Verify the client certificate against the root certificate authority
ansible.builtin.command:
cmd: >-
openssl verify
-CAfile {{ _root_ca_path }}/cert.pem
-untrusted {{ _intermediate_ca_path }}/cert.pem
{{ _client_path }}/cert.pem
changed_when: false
- name: Read the fullchain file of the client
ansible.builtin.slurp:
src: "{{ _client_path }}/fullchain.pem"
register: _client_fullchain
- name: Assert that the fullchain of the client holds the complete chain and ends with a newline
vars:
_content: "{{ _client_fullchain.content | b64decode }}"
ansible.builtin.assert:
that:
- _content | regex_findall('BEGIN CERTIFICATE') | length == 3
- _content.endswith('\n')
fail_msg: "unexpected content in {{ _client_path }}/fullchain.pem"
- name: Read the subject alternative names of the client certificate
community.crypto.x509_certificate_info:
path: "{{ _client_path }}/cert.pem"
register: _client_cert_info
- name: Assert that the requested subject alternative names are present
ansible.builtin.assert:
that: _client_cert_info.subject_alt_name | sort == ['DNS:molecule.example.local', 'IP:10.11.12.13']
fail_msg: "unexpected subject alternative names {{ _client_cert_info.subject_alt_name }}"
- name: Stat the anchor in the systems trust store
ansible.builtin.stat:
path: "{{ _trust_store_anchor[ansible_facts['os_family']] }}"
register: _anchor
- name: Assert that the root certificate authority was imported into the systems trust store
ansible.builtin.assert:
that: _anchor.stat.exists
fail_msg: "{{ _trust_store_anchor[ansible_facts['os_family']] }} is missing"
+173 -499
View File
@@ -8,7 +8,7 @@
"license": "MIT",
"devDependencies": {
"@bitnami/readme-generator-for-helm": "^2.5.0",
"markdownlint-cli": "^0.45.0"
"markdownlint-cli": "^0.49.0"
},
"engines": {
"node": ">=16.0.0",
@@ -32,47 +32,6 @@
"readme-generator": "bin/index.js"
}
},
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/brace-expansion": {
"version": "5.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/@types/debug/-/debug-4.1.12.tgz",
@@ -105,9 +64,9 @@
"license": "MIT"
},
"node_modules/ansi-regex": {
"version": "6.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -117,19 +76,6 @@
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/argparse/-/argparse-2.0.1.tgz",
@@ -188,26 +134,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "13.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/commander/-/commander-13.1.0.tgz",
@@ -225,21 +151,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/debug": {
"version": "4.4.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/debug/-/debug-4.4.1.tgz",
@@ -330,20 +241,6 @@
"node": ">= 6"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true,
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"license": "MIT"
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/entities/-/entities-4.5.0.tgz",
@@ -357,21 +254,22 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/foreground-child": {
"version": "3.3.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"license": "MIT",
"engines": {
"node": ">=14"
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/fs.realpath": {
@@ -381,6 +279,19 @@
"dev": true,
"license": "ISC"
},
"node_modules/get-east-asian-width": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/glob/-/glob-7.2.3.tgz",
@@ -404,9 +315,9 @@
}
},
"node_modules/ignore": {
"version": "7.0.5",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz",
"integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -433,13 +344,13 @@
"license": "ISC"
},
"node_modules/ini": {
"version": "4.1.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ini/-/ini-4.1.3.tgz",
"integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-7.0.0.tgz",
"integrity": "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
}
},
"node_modules/is-alphabetical": {
@@ -479,16 +390,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/is-hexadecimal": {
"version": "2.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
@@ -500,40 +401,27 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "4.1.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/jackspeak/-/jackspeak-4.1.1.tgz",
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.1.tgz",
"integrity": "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/nodeca"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
"js-yaml": "bin/js-yaml.mjs"
}
},
"node_modules/jsonc-parser": {
@@ -581,10 +469,20 @@
}
},
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT",
"dependencies": {
"uc.micro": "^2.0.0"
@@ -597,26 +495,26 @@
"dev": true,
"license": "MIT"
},
"node_modules/lru-cache": {
"version": "11.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/lru-cache/-/lru-cache-11.1.0.tgz",
"integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
"dev": true,
"license": "ISC",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"entities": "^4.5.0",
"linkify-it": "^5.0.2",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
@@ -640,9 +538,9 @@
}
},
"node_modules/markdownlint": {
"version": "0.38.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/markdownlint/-/markdownlint-0.38.0.tgz",
"integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==",
"version": "0.41.1",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.41.1.tgz",
"integrity": "sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -653,76 +551,87 @@
"micromark-extension-gfm-footnote": "2.1.0",
"micromark-extension-gfm-table": "2.1.1",
"micromark-extension-math": "3.1.0",
"micromark-util-types": "2.0.2"
"micromark-util-types": "2.0.2",
"string-width": "8.2.1"
},
"engines": {
"node": ">=20"
"node": ">=22"
},
"funding": {
"url": "https://github.com/sponsors/DavidAnson"
}
},
"node_modules/markdownlint-cli": {
"version": "0.45.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz",
"integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==",
"version": "0.49.1",
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.49.1.tgz",
"integrity": "sha512-qpYqJbSYf3jv57bdnFmCaZ/Wlu6IYHp2b6SOKrKBJ7OnPrDHIKmx4NERWH49QH9viTI6yO6raVDDn5nrf60VQQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"commander": "~13.1.0",
"glob": "~11.0.2",
"ignore": "~7.0.4",
"js-yaml": "~4.1.0",
"commander": "~15.0.0",
"deep-extend": "~0.6.0",
"ignore": "~7.0.6",
"js-yaml": "~5.2.1",
"jsonc-parser": "~3.3.1",
"jsonpointer": "~5.0.1",
"markdown-it": "~14.1.0",
"markdownlint": "~0.38.0",
"minimatch": "~10.0.1",
"run-con": "~1.3.2",
"smol-toml": "~1.3.4"
"markdown-it": "~14.3.0",
"markdownlint": "~0.41.1",
"minimatch": "~10.2.5",
"run-con": "~1.3.3",
"smol-toml": "~1.7.0",
"tinyglobby": "~0.2.17"
},
"bin": {
"markdownlint": "markdownlint.js"
},
"engines": {
"node": ">=20"
"node": ">=22"
}
},
"node_modules/markdownlint-cli/node_modules/glob": {
"version": "11.0.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/glob/-/glob-11.0.3.tgz",
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
"node_modules/markdownlint-cli/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "ISC",
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/markdownlint-cli/node_modules/brace-expansion": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
"integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
"dev": true,
"license": "MIT",
"dependencies": {
"foreground-child": "^3.3.1",
"jackspeak": "^4.1.1",
"minimatch": "^10.0.3",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
},
"bin": {
"glob": "dist/esm/bin.mjs"
"balanced-match": "^4.0.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
"node": "18 || 20 || >=22"
}
},
"node_modules/markdownlint-cli/node_modules/commander": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz",
"integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=22.12.0"
}
},
"node_modules/markdownlint-cli/node_modules/minimatch": {
"version": "10.0.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/minimatch/-/minimatch-10.0.3.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
"dev": true,
"license": "ISC",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/brace-expansion": "^5.0.0"
"brace-expansion": "^5.0.5"
},
"engines": {
"node": "20 || >=22"
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -1294,16 +1203,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ms/-/ms-2.1.3.tgz",
@@ -1321,13 +1220,6 @@
"wrappy": "1"
}
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/parse-entities": {
"version": "4.0.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/parse-entities/-/parse-entities-4.0.2.tgz",
@@ -1358,31 +1250,17 @@
"node": ">=0.10.0"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"node_modules/picomatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
"integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/path-scurry": {
"version": "2.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/path-scurry/-/path-scurry-2.0.0.tgz",
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "20 || >=22"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/punycode.js": {
@@ -1406,14 +1284,14 @@
}
},
"node_modules/run-con": {
"version": "1.3.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/run-con/-/run-con-1.3.2.tgz",
"integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.3.tgz",
"integrity": "sha512-Lb7OKM9aaykzyoNiHGhSVCjZsvbyy6qDMp2vDXL+MoCfz3GfNJtHYH7uYsU3QNMyInBk++xx+EZ8xZ8Sxs5fNQ==",
"dev": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~4.1.0",
"ini": "~7.0.0",
"minimist": "^1.2.8",
"strip-json-comments": "~3.1.1"
},
@@ -1421,46 +1299,10 @@
"run-con": "cli.js"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/smol-toml": {
"version": "1.3.4",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/smol-toml/-/smol-toml-1.3.4.tgz",
"integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz",
"integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -1471,77 +1313,30 @@
}
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz",
"integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
"get-east-asian-width": "^1.5.0",
"strip-ansi": "^7.1.2"
},
"engines": {
"node": ">=12"
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/string-width-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/string-width-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
@@ -1550,30 +1345,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -1587,127 +1358,30 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/tinyglobby": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
"integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/uc.micro/-/uc.micro-2.1.0.tgz",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
"dev": true,
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://repo-nexus.orbis.dedalus.com/nexus/repository/npm-all/wrappy/-/wrappy-1.0.2.tgz",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "certificate-authority-ansible-role",
"homepage": "https://git.cryptic.systems/volker.raschel/certificate-authority-ansible-role.git",
"homepage": "https://git.cryptic.systems/volker.raschek/certificate-authority-ansible-role.git",
"license": "MIT",
"private": true,
"engineStrict": true,
@@ -10,10 +10,10 @@
},
"scripts": {
"readme:lint": "markdownlint *.md -f",
"readme:parameters": "readme-generator -v defaults/main.yaml -r README.md"
"readme:parameters": "readme-generator -v defaults/main.yml -r README.md"
},
"devDependencies": {
"@bitnami/readme-generator-for-helm": "^2.5.0",
"markdownlint-cli": "^0.45.0"
"markdownlint-cli": "^0.49.0"
}
}
+5
View File
@@ -0,0 +1,5 @@
---
collections:
- name: community.crypto
- name: community.general
-112
View File
@@ -1,112 +0,0 @@
---
- name: Create directory to store tls keys and certificates of the client
ansible.builtin.file:
path: "{{ certificate_authority_client_path }}"
owner: "root"
group: "root"
mode: "0700"
state: directory
- name: Create unprotected client certificate
ansible.builtin.include_tasks: client_certificate_unprotected.yaml
when: certificate_authority_client_create is defined and
certificate_authority_client_create and
certificate_authority_client_tls_key_passphrase is defined and
certificate_authority_client_tls_key_passphrase | length <= 0
- name: Create passphrase protected client certificate
ansible.builtin.include_tasks: client_certificate_unprotected.yaml
when: certificate_authority_client_create is defined and
certificate_authority_client_create and
certificate_authority_client_tls_key_passphrase is defined and
certificate_authority_client_tls_key_passphrase | length > 0
- name: Import client certificate
ansible.builtin.include_tasks: client_certificate_import.yaml
when: certificate_authority_client_create is defined and
not certificate_authority_client_create
- name: Create certificate chain file
block:
- name: Check if intermediate certificate exists
ansible.builtin.stat:
path: "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
register: _stat_result
- name: Concatenate client certificate and intermediate certificate
vars:
_chain_files:
- "{{ certificate_authority_client_path }}/cert.pem"
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated chain file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_client_path }}/chain.pem"
owner: "root"
group: "root"
mode: "0644"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create certificate fullchain file
block:
- name: Check if intermediate chain exists
ansible.builtin.stat:
path: "{{ certificate_authority_intermediate_ca_path }}/chain.pem"
register: _stat_result
- name: Concatenate client certificate and intermediate chain file
vars:
_chain_files:
- "{{ certificate_authority_client_path }}/cert.pem"
- "{{ certificate_authority_intermediate_ca_path }}/chain.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated fullchain file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_client_path }}/fullchain.pem"
owner: "root"
group: "root"
mode: "0644"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create file with private key and fullchain file of the client
block:
- name: Check if fullchain exists
ansible.builtin.stat:
path: "{{ certificate_authority_client_path }}/fullchain.pem"
register: _stat_result
- name: Concatenate private key and fullchain file of the client
vars:
_chain_files:
- "{{ certificate_authority_client_path }}/privkey.pem"
- "{{ certificate_authority_client_path }}/fullchain.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_client_path }}/all.pem"
owner: "root"
group: "root"
mode: "0600"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
+72
View File
@@ -0,0 +1,72 @@
---
- name: Create directory to store tls keys and certificates of the client
ansible.builtin.file:
path: "{{ certificate_authority_client_path }}"
owner: "root"
group: "root"
mode: "0755"
state: directory
- name: Verify that the signing intermediate Certificate Authority (CA) is available
when: certificate_authority_client_create is defined and
certificate_authority_client_create
block:
- name: Check private key of the intermediate Certificate Authority (CA)
ansible.builtin.stat:
path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
register: _intermediate_ca_privkey
- name: Assert that the private key of the intermediate Certificate Authority (CA) exists
ansible.builtin.assert:
that: _intermediate_ca_privkey.stat.exists
fail_msg: >-
Signing the client certificate requires
{{ certificate_authority_intermediate_ca_path }}/privkey.pem. Either unset
certificate_authority_intermediate_ca_skip so the intermediate certificate authority is
created or imported, or point certificate_authority_intermediate_ca_path to an existing one.
- name: Create unprotected client certificate
ansible.builtin.include_tasks: client_certificate_unprotected.yml
when: certificate_authority_client_create is defined and
certificate_authority_client_create and
certificate_authority_client_tls_key_passphrase is defined and
certificate_authority_client_tls_key_passphrase | length <= 0
- name: Create passphrase protected client certificate
ansible.builtin.include_tasks: client_certificate_protected.yml
when: certificate_authority_client_create is defined and
certificate_authority_client_create and
certificate_authority_client_tls_key_passphrase is defined and
certificate_authority_client_tls_key_passphrase | length > 0
- name: Import client certificate
ansible.builtin.include_tasks: client_certificate_import.yml
when: certificate_authority_client_create is defined and
not certificate_authority_client_create
- name: Create certificate chain file
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_client_path }}/cert.pem"
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
_concat_dest: "{{ certificate_authority_client_path }}/chain.pem"
_concat_mode: "0644"
- name: Create certificate fullchain file
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_client_path }}/cert.pem"
- "{{ certificate_authority_intermediate_ca_path }}/chain.pem"
_concat_dest: "{{ certificate_authority_client_path }}/fullchain.pem"
_concat_mode: "0644"
- name: Create file with private key and fullchain file of the client
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_client_path }}/privkey.pem"
- "{{ certificate_authority_client_path }}/fullchain.pem"
_concat_dest: "{{ certificate_authority_client_path }}/all.pem"
_concat_mode: "0600"
@@ -3,7 +3,7 @@
- name: Import private key of a client
ansible.builtin.copy:
content: "{{ certificate_authority_client_tls_key_content }}"
dest: "{{ certificate_authority_client_ca_path }}/privkey.pem"
dest: "{{ certificate_authority_client_path }}/privkey.pem"
owner: "root"
group: "root"
mode: "0600"
@@ -12,7 +12,7 @@
- name: Import certificate of a client
ansible.builtin.copy:
content: "{{ certificate_authority_client_tls_crt_content }}"
dest: "{{ certificate_authority_client_tls_crt_content }}/cert.pem"
dest: "{{ certificate_authority_client_path }}/cert.pem"
owner: "root"
group: "root"
mode: "0644"
@@ -3,35 +3,26 @@
- name: Create private key for client
community.crypto.openssl_privatekey:
path: "{{ certificate_authority_client_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_client_tls_key_type }}"
passphrase: "{{ certificate_authority_client_tls_key_passphrase }}"
cipher: auto
- name: Create a certificate signing request (CSR) for client certificate without subject alternative names (SANs)
- name: Create a certificate signing request (CSR) for client certificate
community.crypto.openssl_csr:
common_name: "{{ certificate_authority_client_common_name }}"
countryName: "{{ certificate_authority_client_country_name }}"
email_address: "{{ certificate_authority_client_email_address }}"
extendedKeyUsage:
- clientAuth
- serverAuth
organization_name: "{{ certificate_authority_client_organization_name }}"
organizational_unit_name: "{{ certificate_authority_client_organizational_unit_name }}"
path: "{{ certificate_authority_client_path }}/cert-req.pem"
privatekey_passphrase: "{{ certificate_authority_client_tls_key_passphrase }}"
privatekey_path: "{{ certificate_authority_client_path }}/privkey.pem"
when: |
certificate_authority_client_subject_alternative_names is not defined or
(certificate_authority_client_subject_alternative_names is defined and
certificate_authority_client_subject_alternative_names | length <= 0)
- name: Create a certificate signing request (CSR) for client certificate with subject alternative names (SANs)
community.crypto.openssl_csr:
common_name: "{{ certificate_authority_client_common_name }}"
extendedKeyUsage:
- clientAuth
- serverAuth
path: "{{ certificate_authority_client_path }}/cert-req.pem"
privatekey_path: "{{ certificate_authority_client_path }}/privkey.pem"
privatekey_passphrase: "{{ certificate_authority_client_tls_key_passphrase }}"
subject_alt_name: "{{ certificate_authority_client_subject_alternative_names | map('regex_replace', '^', 'DNS:') | list | join(',') | quote }}"
when: certificate_authority_client_subject_alternative_names is defined and
certificate_authority_client_subject_alternative_names | length > 0
state_or_province_name: "{{ certificate_authority_client_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_client_subject_alternative_names if certificate_authority_client_subject_alternative_names | length > 0 else omit }}"
- name: Create signed client certificate - unprotected intermediate Certificate Authority (CA)
community.crypto.x509_certificate:
@@ -3,32 +3,23 @@
- name: Create private key for client
community.crypto.openssl_privatekey:
path: "{{ certificate_authority_client_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_client_tls_key_type }}"
- name: Create a certificate signing request (CSR) for client certificate without subject alternative names (SANs)
- name: Create a certificate signing request (CSR) for client certificate
community.crypto.openssl_csr:
common_name: "{{ certificate_authority_client_common_name }}"
countryName: "{{ certificate_authority_client_country_name }}"
email_address: "{{ certificate_authority_client_email_address }}"
extendedKeyUsage:
- clientAuth
- serverAuth
organization_name: "{{ certificate_authority_client_organization_name }}"
organizational_unit_name: "{{ certificate_authority_client_organizational_unit_name }}"
path: "{{ certificate_authority_client_path }}/cert-req.pem"
privatekey_path: "{{ certificate_authority_client_path }}/privkey.pem"
when: |
certificate_authority_client_subject_alternative_names is not defined or
(certificate_authority_client_subject_alternative_names is defined and
certificate_authority_client_subject_alternative_names | length <= 0)
- name: Create a certificate signing request (CSR) for client certificate with subject alternative names (SANs)
community.crypto.openssl_csr:
common_name: "{{ certificate_authority_client_common_name }}"
extendedKeyUsage:
- clientAuth
- serverAuth
path: "{{ certificate_authority_client_path }}/cert-req.pem"
privatekey_path: "{{ certificate_authority_client_path }}/privkey.pem"
subject_alt_name: "{{ certificate_authority_client_subject_alternative_names | map('regex_replace', '^', 'DNS:') | list | join(',') | quote }}"
when: certificate_authority_client_subject_alternative_names is defined and
certificate_authority_client_subject_alternative_names | length > 0
state_or_province_name: "{{ certificate_authority_client_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_client_subject_alternative_names if certificate_authority_client_subject_alternative_names | length > 0 else omit }}"
- name: Create signed client certificate - unprotected intermediate Certificate Authority (CA)
community.crypto.x509_certificate:
+24
View File
@@ -0,0 +1,24 @@
---
# awk 1 prints every line and thereby normalizes source files whose last line lacks a newline.
- name: Check the source files of {{ _concat_dest }}
ansible.builtin.stat:
path: "{{ item }}"
register: _concat_stat
loop: "{{ _concat_sources }}"
- name: Read the source files of {{ _concat_dest }}
ansible.builtin.command:
cmd: "awk 1 {{ _concat_sources | join(' ') }}"
register: _concat_content
changed_when: false
when: _concat_stat.results | rejectattr('stat.exists') | list | length == 0
- name: Write {{ _concat_dest }}
ansible.builtin.copy:
content: "{{ _concat_content.stdout }}\n"
dest: "{{ _concat_dest }}"
owner: "root"
group: "root"
mode: "{{ _concat_mode }}"
when: _concat_content is not skipped
@@ -1,112 +0,0 @@
---
- name: Create directory to store tls keys and certificates of the intermediate CA
ansible.builtin.file:
path: "{{ certificate_authority_intermediate_ca_path }}"
owner: "root"
group: "root"
mode: "0700"
state: "directory"
- name: Create unprotected intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_unprotected.yaml
when: certificate_authority_intermediate_ca_create is defined and
certificate_authority_intermediate_ca_create and
certificate_authority_intermediate_ca_tls_key_passphrase is defined and
certificate_authority_intermediate_ca_tls_key_passphrase | length <= 0
- name: Create passphrase protected intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_unprotected.yaml
when: certificate_authority_intermediate_ca_create is defined and
certificate_authority_intermediate_ca_create and
certificate_authority_intermediate_ca_tls_key_passphrase is defined and
certificate_authority_intermediate_ca_tls_key_passphrase | length > 0
- name: Import intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_import.yaml
when: certificate_authority_intermediate_ca_create is defined and
not certificate_authority_intermediate_ca_create
- name: Create certificate chain file
block:
- name: Check if root certificate exists
ansible.builtin.stat:
path: "{{ certificate_authority_root_ca_path }}/cert.pem"
register: _stat_result
- name: Concatenate intermediate certificate and root certificate
vars:
_chain_files:
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
- "{{ certificate_authority_root_ca_path }}/cert.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated chain file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_intermediate_ca_path }}/chain.pem"
owner: "root"
group: "root"
mode: "0644"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create certificate fullchain file
block:
- name: Check if root chain exists
ansible.builtin.stat:
path: "{{ certificate_authority_root_ca_path }}/chain.pem"
register: _stat_result
- name: Concatenate intermediate certificate and root chain file
vars:
_chain_files:
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
- "{{ certificate_authority_root_ca_path }}/chain.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated fullchain file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_intermediate_ca_path }}/fullchain.pem"
owner: "root"
group: "root"
mode: "0644"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create file with private key and fullchain file of intermediate Certificate Authority (CA)
block:
- name: Check if private key exists
ansible.builtin.stat:
path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
register: _stat_result
- name: Concatenate private key and fullchain file of intermediate Certificate Authority (CA)
vars:
_chain_files:
- "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
- "{{ certificate_authority_intermediate_ca_path }}/fullchain.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_intermediate_ca_path }}/all.pem"
owner: "root"
group: "root"
mode: "0600"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
@@ -0,0 +1,72 @@
---
- name: Create directory to store tls keys and certificates of the intermediate CA
ansible.builtin.file:
path: "{{ certificate_authority_intermediate_ca_path }}"
owner: "root"
group: "root"
mode: "0755"
state: "directory"
- name: Verify that the signing root Certificate Authority (CA) is available
when: certificate_authority_intermediate_ca_create is defined and
certificate_authority_intermediate_ca_create
block:
- name: Check private key of the root Certificate Authority (CA)
ansible.builtin.stat:
path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
register: _root_ca_privkey
- name: Assert that the private key of the root Certificate Authority (CA) exists
ansible.builtin.assert:
that: _root_ca_privkey.stat.exists
fail_msg: >-
Signing the intermediate certificate authority requires
{{ certificate_authority_root_ca_path }}/privkey.pem. Either unset
certificate_authority_root_ca_skip so the root certificate authority is created or
imported, or point certificate_authority_root_ca_path to an existing one.
- name: Create unprotected intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_unprotected.yml
when: certificate_authority_intermediate_ca_create is defined and
certificate_authority_intermediate_ca_create and
certificate_authority_intermediate_ca_tls_key_passphrase is defined and
certificate_authority_intermediate_ca_tls_key_passphrase | length <= 0
- name: Create passphrase protected intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_protected.yml
when: certificate_authority_intermediate_ca_create is defined and
certificate_authority_intermediate_ca_create and
certificate_authority_intermediate_ca_tls_key_passphrase is defined and
certificate_authority_intermediate_ca_tls_key_passphrase | length > 0
- name: Import intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority_import.yml
when: certificate_authority_intermediate_ca_create is defined and
not certificate_authority_intermediate_ca_create
- name: Create certificate chain file
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
- "{{ certificate_authority_root_ca_path }}/cert.pem"
_concat_dest: "{{ certificate_authority_intermediate_ca_path }}/chain.pem"
_concat_mode: "0644"
- name: Create certificate fullchain file
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_intermediate_ca_path }}/cert.pem"
- "{{ certificate_authority_root_ca_path }}/chain.pem"
_concat_dest: "{{ certificate_authority_intermediate_ca_path }}/fullchain.pem"
_concat_mode: "0644"
- name: Create file with private key and fullchain file of intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
- "{{ certificate_authority_intermediate_ca_path }}/fullchain.pem"
_concat_dest: "{{ certificate_authority_intermediate_ca_path }}/all.pem"
_concat_mode: "0600"
@@ -4,16 +4,24 @@
community.crypto.openssl_privatekey:
passphrase: "{{ certificate_authority_intermediate_ca_tls_key_passphrase }}"
path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_intermediate_ca_tls_key_type }}"
cipher: auto
- name: Create a certificate signing request (CSR) for intermediate CA
community.crypto.openssl_csr:
basic_constraints:
- "CA:TRUE"
common_name: "{{ certificate_authority_intermediate_ca_common_name }}"
countryName: "{{ certificate_authority_intermediate_ca_country_name }}"
email_address: "{{ certificate_authority_intermediate_ca_email_address }}"
organization_name: "{{ certificate_authority_intermediate_ca_organization_name }}"
organizational_unit_name: "{{ certificate_authority_intermediate_ca_organizational_unit_name }}"
path: "{{ certificate_authority_intermediate_ca_path }}/cert-req.pem"
privatekey_passphrase: "{{ certificate_authority_intermediate_ca_tls_key_passphrase }}"
privatekey_path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
state_or_province_name: "{{ certificate_authority_intermediate_ca_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_intermediate_ca_subject_alternative_names if certificate_authority_intermediate_ca_subject_alternative_names | length > 0 else omit }}"
use_common_name_for_san: false
- name: Create signed client certificate - unprotected root Certificate Authority (CA)
@@ -3,6 +3,7 @@
- name: Create private key for intermediate CA
community.crypto.openssl_privatekey:
path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_intermediate_ca_tls_key_type }}"
- name: Create a certificate signing request (CSR) for intermediate CA
@@ -10,8 +11,14 @@
basic_constraints:
- "CA:TRUE"
common_name: "{{ certificate_authority_intermediate_ca_common_name }}"
countryName: "{{ certificate_authority_intermediate_ca_country_name }}"
email_address: "{{ certificate_authority_intermediate_ca_email_address }}"
organization_name: "{{ certificate_authority_intermediate_ca_organization_name }}"
organizational_unit_name: "{{ certificate_authority_intermediate_ca_organizational_unit_name }}"
path: "{{ certificate_authority_intermediate_ca_path }}/cert-req.pem"
privatekey_path: "{{ certificate_authority_intermediate_ca_path }}/privkey.pem"
state_or_province_name: "{{ certificate_authority_intermediate_ca_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_intermediate_ca_subject_alternative_names if certificate_authority_intermediate_ca_subject_alternative_names | length > 0 else omit }}"
use_common_name_for_san: false
- name: Create signed client certificate - unprotected root Certificate Authority (CA)
-26
View File
@@ -1,26 +0,0 @@
---
- name: Upgrade python package manager pip
ansible.builtin.pip:
name: pip
state: latest
- name: Install required python library cryptography
ansible.builtin.pip:
name: cryptography>=1.2.3
state: present
- name: Create or import a root Certificate Authority (CA)
ansible.builtin.include_tasks: root_certificate_authority.yaml
when: certificate_authority_root_ca_skip is defined and
not certificate_authority_root_ca_skip
- name: Create or import a intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority.yaml
when: certificate_authority_intermediate_ca_skip is defined and
not certificate_authority_intermediate_ca_skip
- name: Create or import a client certificate
ansible.builtin.include_tasks: client_certificate.yaml
when: certificate_authority_client_skip is defined and
not certificate_authority_client_skip
+34
View File
@@ -0,0 +1,34 @@
---
- name: Include OS-specific variables
ansible.builtin.include_vars: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "{{ ansible_facts['distribution'] }}_{{ ansible_facts['architecture'] }}.yml"
- "{{ ansible_facts['distribution'] }}.yml"
- "{{ ansible_facts['os_family'] }}_{{ ansible_facts['architecture'] }}.yml"
- "{{ ansible_facts['os_family'] }}.yml"
- main.yml
paths:
- vars
- name: Install required python libraries
ansible.builtin.package:
name: "{{ certificate_authority_python_packages }}"
state: present
- name: Create or import a root Certificate Authority (CA)
ansible.builtin.include_tasks: root_certificate_authority.yml
when: certificate_authority_root_ca_skip is defined and
not certificate_authority_root_ca_skip
- name: Create or import a intermediate Certificate Authority (CA)
ansible.builtin.include_tasks: intermediate_certificate_authority.yml
when: certificate_authority_intermediate_ca_skip is defined and
not certificate_authority_intermediate_ca_skip
- name: Create or import a client certificate
ansible.builtin.include_tasks: client_certificate.yml
when: certificate_authority_client_skip is defined and
not certificate_authority_client_skip
@@ -5,25 +5,25 @@
path: "{{ certificate_authority_root_ca_path }}"
owner: "root"
group: "root"
mode: "0700"
mode: "0755"
state: "directory"
- name: Create unprotected root Certificate Authority (CA)
ansible.builtin.include_tasks: root_certificate_authority_unprotected.yaml
ansible.builtin.include_tasks: root_certificate_authority_unprotected.yml
when: certificate_authority_root_ca_create is defined and
certificate_authority_root_ca_create and
certificate_authority_root_ca_tls_key_passphrase is defined and
certificate_authority_root_ca_tls_key_passphrase | length <= 0
- name: Create passphrase protected root Certificate Authority (CA)
ansible.builtin.include_tasks: root_certificate_authority_unprotected.yaml
ansible.builtin.include_tasks: root_certificate_authority_protected.yml
when: certificate_authority_root_ca_create is defined and
certificate_authority_root_ca_create and
certificate_authority_root_ca_tls_key_passphrase is defined and
certificate_authority_root_ca_tls_key_passphrase | length > 0
- name: Import protected root Certificate Authority (CA)
ansible.builtin.include_tasks: root_certificate_authority_import.yaml
ansible.builtin.include_tasks: root_certificate_authority_import.yml
when: certificate_authority_root_ca_create is defined and
not certificate_authority_root_ca_create
@@ -38,47 +38,21 @@
- fullchain.pem
- name: Create file with private key and fullchain file of root Certificate Authority (CA)
block:
- name: Check if private key exists
ansible.builtin.stat:
path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
register: _stat_result
- name: Concatenate private key and fullchain file of root Certificate Authority (CA)
vars:
_chain_files:
- "{{ certificate_authority_root_ca_path }}/privkey.pem"
- "{{ certificate_authority_root_ca_path }}/fullchain.pem"
ansible.builtin.command:
cmd: awk 1 {{ _chain_files | join(' ') }}
register: chain_content
changed_when: chain_content.rc == 0
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
- name: Create concatenated file
ansible.builtin.copy:
content: "{{ chain_content.stdout_lines | join('\n') }}"
dest: "{{ certificate_authority_root_ca_path }}/all.pem"
owner: "root"
group: "root"
mode: "0600"
remote_src: true
when: _stat_result.stat.exists is defined and
_stat_result.stat.exists
ansible.builtin.include_tasks: concatenate.yml
vars:
_concat_sources:
- "{{ certificate_authority_root_ca_path }}/privkey.pem"
- "{{ certificate_authority_root_ca_path }}/fullchain.pem"
_concat_dest: "{{ certificate_authority_root_ca_path }}/all.pem"
_concat_mode: "0600"
- name: Import certificate of root Certificate Authority (CA) into systems trust store
ansible.builtin.file:
src: "{{ certificate_authority_root_ca_path }}/cert.pem"
dest: "{{ certificate_authority_trust_store_anchor }}"
owner: root
group: root
state: link
notify: Update systems SSL/TLS trust store
when: certificate_authority_root_ca_import is defined and
certificate_authority_root_ca_import
block:
- name: Create symolic link
ansible.builtin.file:
src: "{{ certificate_authority_root_ca_path }}/cert.pem"
dest: "/etc/pki/ca-trust/source/anchors/{{ certificate_authority_root_ca_common_name | replace(' ', '_') }}.pem"
owner: root
group: root
state: link
- name: Update systems SSL/TLS trust store
ansible.builtin.command:
cmd: /usr/bin/update-ca-trust
register: _update_ca_trust
changed_when: _update_ca_trust.rc == 0
failed_when: _update_ca_trust.rc > 0
@@ -16,4 +16,5 @@
owner: "root"
group: "root"
mode: "0644"
notify: Update systems SSL/TLS trust store
when: certificate_authority_root_ca_tls_crt_content | length > 0
@@ -4,15 +4,24 @@
community.crypto.openssl_privatekey:
passphrase: "{{ certificate_authority_root_ca_tls_key_passphrase }}"
path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_root_ca_tls_key_type }}"
cipher: auto
- name: Create a certificate signing request (CSR) for root CA
community.crypto.openssl_csr:
basic_constraints:
- "CA:TRUE"
common_name: "{{ certificate_authority_root_ca_common_name }}"
countryName: "{{ certificate_authority_root_ca_country_name }}"
email_address: "{{ certificate_authority_root_ca_email_address }}"
organization_name: "{{ certificate_authority_root_ca_organization_name }}"
organizational_unit_name: "{{ certificate_authority_root_ca_organizational_unit_name }}"
path: "{{ certificate_authority_root_ca_path }}/cert-req.pem"
privatekey_passphrase: "{{ certificate_authority_root_ca_tls_key_passphrase }}"
privatekey_path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
state_or_province_name: "{{ certificate_authority_root_ca_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_root_ca_subject_alternative_names if certificate_authority_root_ca_subject_alternative_names | length > 0 else omit }}"
use_common_name_for_san: false
- name: Create self-signed certificate for root CA
@@ -24,3 +33,4 @@
provider: selfsigned
selfsigned_not_after: "{{ certificate_authority_root_ca_not_after }}"
selfsigned_not_before: "{{ certificate_authority_root_ca_not_before }}"
notify: Update systems SSL/TLS trust store
@@ -3,6 +3,7 @@
- name: Create private key for root CA
community.crypto.openssl_privatekey:
path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
mode: "0600"
type: "{{ certificate_authority_root_ca_tls_key_type }}"
- name: Create a certificate signing request (CSR) for root CA
@@ -10,8 +11,14 @@
basic_constraints:
- "CA:TRUE"
common_name: "{{ certificate_authority_root_ca_common_name }}"
countryName: "{{ certificate_authority_root_ca_country_name }}"
email_address: "{{ certificate_authority_root_ca_email_address }}"
organization_name: "{{ certificate_authority_root_ca_organization_name }}"
organizational_unit_name: "{{ certificate_authority_root_ca_organizational_unit_name }}"
path: "{{ certificate_authority_root_ca_path }}/cert-req.pem"
privatekey_path: "{{ certificate_authority_root_ca_path }}/privkey.pem"
state_or_province_name: "{{ certificate_authority_root_ca_state_or_province_name }}"
subject_alt_name: "{{ certificate_authority_root_ca_subject_alternative_names if certificate_authority_root_ca_subject_alternative_names | length > 0 else omit }}"
use_common_name_for_san: false
- name: Create self-signed certificate for root CA
@@ -22,3 +29,4 @@
provider: selfsigned
selfsigned_not_after: "{{ certificate_authority_root_ca_not_after }}"
selfsigned_not_before: "{{ certificate_authority_root_ca_not_before }}"
notify: Update systems SSL/TLS trust store
+7
View File
@@ -0,0 +1,7 @@
---
certificate_authority_python_packages:
- python-cryptography
certificate_authority_trust_store_anchor: "/etc/ca-certificates/trust-source/anchors/{{ certificate_authority_root_ca_common_name | replace(' ', '_') }}.pem"
certificate_authority_trust_store_update_command: "/usr/bin/update-ca-trust"
+8
View File
@@ -0,0 +1,8 @@
---
certificate_authority_python_packages:
- python3-cryptography
# Debian based distributions only consider anchors with the file extension crt.
certificate_authority_trust_store_anchor: "/usr/local/share/ca-certificates/{{ certificate_authority_root_ca_common_name | replace(' ', '_') }}.crt"
certificate_authority_trust_store_update_command: "/usr/sbin/update-ca-certificates"
+7
View File
@@ -0,0 +1,7 @@
---
certificate_authority_python_packages:
- python3-cryptography
certificate_authority_trust_store_anchor: "/etc/pki/ca-trust/source/anchors/{{ certificate_authority_root_ca_common_name | replace(' ', '_') }}.pem"
certificate_authority_trust_store_update_command: "/usr/bin/update-ca-trust"
+6
View File
@@ -0,0 +1,6 @@
---
# Fallback for distributions without a dedicated vars file. Overridden by the
# os-specific file included in tasks/main.yml.
certificate_authority_python_packages:
- python3-cryptography