---
- name: "β
CA | ensure base directory exists"
become: true
ansible.builtin.file:
path: "{{ CA_ROOT.base_dir }}"
state: directory
mode: "0755"
owner: root
group: root
- name: "β
CA | ensure openssl is installed"
include_role:
name: sys-openssl
when: run_once_sys_openssl is not defined
- name: "π CA | check openssl availability"
ansible.builtin.command: "openssl version"
register: _openssl_version
changed_when: false
- name: "ποΈ CA | mint the shared Root CA once on the stack host (workers fetch it below)"
ansible.builtin.include_tasks:
file: 01_mint.yml
apply:
become: true
run_once: true
delegate_to: "{{ STACK_HOST }}"
- name: "β¬οΈ CA | (swarm worker) fetch + install shared Root CA cert from stack host"
become: true
when: not (IS_STACK_HOST | bool)
block:
- name: "π CA | (swarm worker) read the shared Root CA cert from the stack host"
ansible.builtin.slurp:
src: "{{ CA_ROOT.cert_host }}"
register: _ca_cert_from_stack_host
delegate_to: "{{ STACK_HOST }}"
- name: "π CA | (swarm worker) write shared Root CA cert locally (cert only, no key)"
ansible.builtin.copy:
dest: "{{ CA_ROOT.cert_host }}"
content: "{{ _ca_cert_from_stack_host.content | b64decode }}"
owner: root
group: root
mode: "0644"
- name: "π CA | enforce permissions (certificate)"
become: true
ansible.builtin.file:
path: "{{ CA_ROOT.cert_host }}"
owner: root
group: root
mode: "0644"
- name: "β
CA | sanity check: verify certificate is CA:TRUE"
become: true
ansible.builtin.command: "openssl x509 -in {{ CA_ROOT.cert_host }} -noout -text"
register: _ca_cert_text
changed_when: false
- name: "β
CA | assert certificate contains CA:TRUE"
ansible.builtin.assert:
that:
- (_ca_cert_text.stdout | default('')) is search('CA:TRUE')
fail_msg: >-
Generated certificate does not appear to be a CA certificate (CA:TRUE missing).
Please inspect {{ CA_ROOT.cert_host }}.
- name: "π CA | locate the distribution's public CA bundle"
become: true
ansible.builtin.stat:
path: "{{ item }}"
loop: "{{ CA_BUNDLE_CANDIDATES }}"
register: _ca_public_bundle_candidates
- name: "π CA | keep the first public CA bundle the host ships"
ansible.builtin.set_fact:
_ca_public_bundle: "{{ (_ca_public_bundle_candidates.results | selectattr('stat.exists') | map(attribute='item') | list)[:1] }}"
- name: "π CA | stat host CA-trust bind-mount sources"
become: true
ansible.builtin.stat:
path: "{{ item }}"
loop:
- "{{ BIN_CA_TRUST }}"
- "{{ CA_TRUST.php_ini_host }}"
- "{{ CA_TRUST.bundle_host }}"
register: _ca_trust_bind_sources
- name: "π§Ή CA | remove stray directory shadowing a CA-trust bind source"
become: true
ansible.builtin.file:
path: "{{ item.item }}"
state: absent
loop: "{{ _ca_trust_bind_sources.results }}"
loop_control:
label: "{{ item.item }}"
when:
- item.stat.exists
- item.stat.isdir
- name: "π CA | build the trust bundle its readers name with no fallback"
become: true
ansible.builtin.script:
cmd: >-
{{ role_path }}/files/shell/build-trust-bundle.sh
{{ ([CA_TRUST.bundle_host, CA_ROOT.cert_host] + _ca_public_bundle) | map('quote') | join(' ') }}
register: _ca_trust_bundle_build
changed_when: "'bundle-rewritten' in _ca_trust_bundle_build.stdout"
- name: "π CA | enforce permissions (trust bundle)"
become: true
ansible.builtin.file:
path: "{{ CA_TRUST.bundle_host }}"
owner: root
group: root
mode: "0644"
- name: "π¦ CA | install trust helper script (SPOT) on host"
become: true
ansible.builtin.copy:
src: "shell/with-ca-trust.sh"
dest: "{{ BIN_CA_TRUST }}"
owner: root
group: root
mode: "0755"
register: _ca_trust_wrapper
- name: "π¦ CA | install PHP CA-trust ini (SPOT) on host"
become: true
ansible.builtin.template: # nocheck: stack-host-template (host tool install, same gate as the adjacent wrapper copy)
src: "ca-trust-php.ini.j2"
dest: "{{ CA_TRUST.php_ini_host }}"
owner: root
group: root
mode: "0644"
- name: "π CA | check whether the host trust store already trusts the Root CA"
become: true
ansible.builtin.command:
argv:
- openssl
- verify
- -no-CApath
- -CAfile
- "{{ _ca_public_bundle | first }}"
- "{{ CA_ROOT.cert_host }}"
register: _ca_trusted_by_host
changed_when: false
failed_when: _ca_trusted_by_host.rc not in [0, 2]
when: _ca_public_bundle | length > 0
- name: "π¦ CA | Install Root CA into host trust store"
become: true
ansible.builtin.command:
argv:
- /usr/bin/env
- sh
- "{{ BIN_CA_TRUST }}"
environment:
CA_TRUST_CERT: "{{ CA_ROOT.cert_host }}"
CA_TRUST_NAME: "{{ DOMAIN_PRIMARY | lower }}"
changed_when: true
when: >-
_ca_trust_wrapper is changed
or _ca_trusted_by_host is skipped
or _ca_trusted_by_host.rc != 0
- name: "β
TLS | (self_signed) ensure CA trust env vars in {{ FILE_ENVIRONMENT }}"
become: true
ansible.builtin.lineinfile:
path: "{{ FILE_ENVIRONMENT }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
create: true
mode: "0644"
loop:
- regexp: "^CA_TRUST_CERT_HOST="
line: "CA_TRUST_CERT_HOST={{ CA_TRUST.cert_host }}"
- regexp: "^CA_TRUST_WRAPPER_HOST="
line: "CA_TRUST_WRAPPER_HOST={{ CA_TRUST.wrapper_host }}"
- regexp: "^CA_TRUST_NAME="
line: "CA_TRUST_NAME={{ CA_TRUST.trust_name }}"
- name: "π TLS | (self_signed) let the next letsencrypt role remove the env vars again"
ansible.builtin.set_fact:
tls_selfsigned_env_disabled: false
- include_tasks: utils/once/flag.yml