From 6b643863fd9e1c55c02542b779af9043940f6208 Mon Sep 17 00:00:00 2001 From: ace Date: Tue, 6 Sep 2022 14:31:23 +0300 Subject: [PATCH] rewrite role with group cert support --- README.md | 66 ++++++++-------- defaults/main.yaml | 41 +++++++--- tasks/ca.yaml | 123 +++++++++++++++++++++++------ tasks/certs.yaml | 108 ------------------------- tasks/cn_certs.yaml | 170 ++++++++++++++++++++++++++++++++++++++++ tasks/group_certs.yaml | 173 +++++++++++++++++++++++++++++++++++++++++ tasks/main.yaml | 20 +++-- 7 files changed, 521 insertions(+), 180 deletions(-) delete mode 100644 tasks/certs.yaml create mode 100644 tasks/cn_certs.yaml create mode 100644 tasks/group_certs.yaml diff --git a/README.md b/README.md index 2b31eaa..5ac8b5a 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,38 @@ Inventory example: - cacert_ca_name: "kojiCA" - cacert_ca_copy_to: - - { host: "dev-1", path: "/opt/koji/certs" } + cacert_ca_name: "myCA" cacert_ca_trust_anchors_update: True - - cacert_certs: - - name: kojiadmin - dest: - - { host: "dev-1", path: "/opt/koji/certs" } - - { host: "dev-1", name: "client", path: "/opt/koji/certs", concat: "crt" } - - name: koji.lan - dest: - - { host: "dev-1", path: "/opt/koji/certs" } - - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } - - name: koji-hub.lan - subject_alt_names: - - koji-files.lan - dest: - - { host: "dev-1", path: "/opt/koji/certs" } - - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } - - name: koji-web.lan - dest: - - { host: "dev-1", path: "/opt/koji/certs" } - - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } - - { host: "dev-1", path: "/opt/koji/certs", concat: "pem" } - - name: kojibuilder1.lan - dest: - - { host: "kojibuilder1.lan", path: "/opt/koji/certs" } - - { host: "kojibuilder1.lan", path: "/opt/koji/certs", concat: "pem" } - - name: kojira.lan - dest: - - { host: "dev-1", path: "/opt/koji/certs" } - - { host: "dev-1", path: "/opt/koji/certs", concat: "pem" } + cacert_ca_copy_to: + hosts: + - { host: "server-1", path: "/opt/certs" } + - { host: "server-2", path: "/opt/certs" } + groups: + - { group: "cacert_clients", path: "/opt/certs" } + - { group: "mygroupname", path: "/opt/certs" } + + cacert_cn_certs: + - name: mycertname.example.com + hosts: + - { host: "server-1", path: "/opt/certs" } + - { host: "server-2", path: "/opt/certs" } + - { host: "server-1", path: "/opt/certs", concat: "pem" } + - { host: "server-2", path: "/opt/certs", concat: "pem" } + groups: + - { group: "cacert_clients", path: "/opt/certs" } + - { group: "mygroupname", path: "/opt/certs" } + + cacert_group_certs: + - name: mygroupcert + host_groups: + - consul + - patroni + hosts: + - { host: "server-1", path: "/opt/certs" } + - { host: "server-2", path: "/opt/certs" } + - { host: "server-1", path: "/opt/certs", concat: "pem" } + - { host: "server-2", path: "/opt/certs", concat: "pem" } + groups: + - { group: "cacert_clients", path: "/opt/certs" } + - { group: "mygroupname", path: "/opt/certs" } + diff --git a/defaults/main.yaml b/defaults/main.yaml index b23d6cc..64d1981 100644 --- a/defaults/main.yaml +++ b/defaults/main.yaml @@ -1,16 +1,39 @@ +cacert_ca_group: cacert_ca +cacert_clients_group: cacert_clients cacert_ssl_gen_path: "/tmp/cacert" cacert_ca_name: "myCA" cacert_ca_trust_anchors_update: False #cacert_ca_copy_to: -# - { host: "host-1", path: "/tmp" } +# hosts: +# - { host: "server-1", path: "/opt/certs" } +# - { host: "server-2", path: "/opt/certs" } +# groups: +# - { group: "cacert_clients", path: "/opt/certs" } +# - { group: "mygroupname", path: "/opt/certs" } # -#cacert_certs: -# - name: example1.com -# dest: -# - { host: "host-1", path: "/tmp" } -# - { host: "host-1", name: "newname", path: "/tmp", concat: "pem" } -# - name: example2.com -# dest: -# - { host: "host-1", path: "/tmp" } +#cacert_cn_certs: +# - name: mycertname.example.com +# hosts: +# - { host: "server-1", path: "/opt/certs" } +# - { host: "server-2", path: "/opt/certs" } +# - { host: "server-1", path: "/opt/certs", concat: "pem" } +# - { host: "server-2", path: "/opt/certs", concat: "pem" } +# groups: +# - { group: "cacert_clients", path: "/opt/certs" } +# - { group: "mygroupname", path: "/opt/certs" } +# +#cacert_group_certs: +# - name: mygroupcert +# host_groups: +# - consul +# - patroni +# hosts: +# - { host: "server-1", path: "/opt/certs" } +# - { host: "server-2", path: "/opt/certs" } +# - { host: "server-1", path: "/opt/certs", concat: "pem" } +# - { host: "server-2", path: "/opt/certs", concat: "pem" } +# groups: +# - { group: "cacert_clients", path: "/opt/certs" } +# - { group: "mygroupname", path: "/opt/certs" } diff --git a/tasks/ca.yaml b/tasks/ca.yaml index 7852c49..ea7314d 100644 --- a/tasks/ca.yaml +++ b/tasks/ca.yaml @@ -1,4 +1,5 @@ - name: Create CA {{ cacert_ca_name }} + when: inventory_hostname in groups[cacert_ca_group] block: - name: Generate an OpenSSL private CA key with the default values (4096 bits, RSA) community.crypto.openssl_privatekey: @@ -27,41 +28,113 @@ provider: selfsigned register: cacert_ca_cert_gen -- name: Distribute CA + - name: Get CA cert content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + register: cacert_ca_cert_b64 + + - name: Get CA key content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + register: cacert_ca_key_b64 + + - name: Set facts about key and cert + set_fact: + cacert_ca_key: "{{ cacert_ca_key_b64.content | b64decode }}" + cacert_ca_cert: "{{ cacert_ca_cert_b64.content | b64decode }}" + delegate_to: "{{ item }}" + delegate_facts: true + run_once: true + with_items: + - "{{ groups[cacert_ca_group] | default([]) }}" + - "{{ groups[cacert_clients_group] | default([]) }}" + +- name: Distribute CA certificate to hosts become: true + when: inventory_hostname in groups.cacert_clients block: - - name: CA and cert | Check if dest dir exist on remote hosts + - name: CA and cert | Check if dest dir exist on remote host file: - name: "{{ item.path }}" + name: "{{ host_item.path }}" state: directory - delegate_to: "{{ item.host }}" - loop: "{{ cacert_ca_copy_to }}" - when: - - cacert_ca_copy_to is defined - - - name: Put CA OpenSSL cert - copy: - src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" - dest: "{{ item.path }}/{{ cacert_ca_name }}.crt" - delegate_to: "{{ item.host }}" - loop: "{{ cacert_ca_copy_to }}" - when: - - cacert_ca_copy_to is defined - + loop: "{{ cacert_ca_copy_to.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put CA cert for host + copy: + content: "{{ cacert_ca_cert }}" + dest: "{{ host_item.path }}/{{ cacert_ca_name }}.crt" + loop: "{{ cacert_ca_copy_to.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + - name: Put CA OpenSSL cert to PKI copy: - src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + content: "{{ cacert_ca_cert }}" dest: "/etc/pki/ca-trust/source/anchors/{{ cacert_ca_name }}.crt" - when: - - cacert_ca_trust_anchors_update + loop: "{{ cacert_ca_copy_to.hosts }}" + loop_control: + loop_var: host_item register: ca_trust_anchors - delegate_to: "{{ item.host }}" - loop: "{{ cacert_ca_copy_to }}" + when: + - inventory_hostname == host_item.host - name: Update CA trust shell: update-ca-trust extract - when: + loop: "{{ cacert_ca_copy_to.hosts }}" + loop_control: + loop_var: host_item + when: - ca_trust_anchors.changed - cacert_ca_trust_anchors_update - delegate_to: "{{ item.host }}" - loop: "{{ cacert_ca_copy_to }}" + - inventory_hostname == host_item.host + +- name: Distribute CA certificate to groups + become: true + when: inventory_hostname in groups[cacert_clients_group] + block: + - name: CA and cert | Check if dest dir exist on remote host in group + file: + name: "{{ group_item.path }}" + state: directory + loop: "{{ cacert_ca_copy_to.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put CA cert for host in group + copy: + content: "{{ cacert_ca_cert }}" + dest: "{{ group_item.path }}/{{ cacert_ca_name }}.crt" + loop: "{{ cacert_ca_copy_to.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put CA OpenSSL cert to PKI + copy: + content: "{{ cacert_ca_cert }}" + dest: "/etc/pki/ca-trust/source/anchors/{{ cacert_ca_name }}.crt" + loop: "{{ cacert_ca_copy_to.groups }}" + loop_control: + loop_var: group_item + register: ca_trust_anchors + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Update CA trust + shell: update-ca-trust extract + loop: "{{ cacert_ca_copy_to.groups }}" + loop_control: + loop_var: group_item + when: + - ca_trust_anchors.changed + - cacert_ca_trust_anchors_update + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" diff --git a/tasks/certs.yaml b/tasks/certs.yaml deleted file mode 100644 index 4388d4c..0000000 --- a/tasks/certs.yaml +++ /dev/null @@ -1,108 +0,0 @@ -- name: CA and cert | Check if dest dir exist on remote hosts - become: true - file: - name: "{{ dest.path }}" - state: directory - delegate_to: "{{ dest.host }}" - loop: "{{ item.dest }}" - loop_control: - loop_var: dest - -- name: CA and certs | Generate clients certs and keys - block: - - name: Generate an OpenSSL private client key with the default values (4096 bits, RSA) - community.crypto.openssl_privatekey: - path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" - when: cacert_cert is not defined - register: cacert_client_key_gen - - - name: Generate subject_alt_ips - set_fact: - client_subject_alt_ips: "{{ item.subject_alt_ips | map('regex_replace', '^', 'IP:') | list }}" - when: item.subject_alt_ips is defined - - - name: Generate subject_alt_names - set_fact: - client_subject_alt_names: "{{ item.subject_alt_names | map('regex_replace', '^', 'DNS:') | list }}" - when: item.subject_alt_names is defined - - - name: Generate an OpenSSL Certificate Signing Request for client - community.crypto.openssl_csr: - path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" - privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" - common_name: "{{ item.name }}" - register: cacert_client_csr - when: - - item.subject_alt_names is not defined - - item.subject_alt_ips is not defined - - - name: Generate an OpenSSL Certificate Signing Request for client with subject_alt_name - community.crypto.openssl_csr: - path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" - privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" - common_name: "{{ item.name }}" - subject_alt_name: "{{ ((client_subject_alt_ips | default([])) + (client_subject_alt_names | default([]) + (['DNS:' ~ item.name]))) }}" - register: cacert_client_csr - when: item.subject_alt_names is defined or item.subject_alt_ips is defined - - - name: Generate an OpenSSL certificate for client signed with your own CA certificate - community.crypto.x509_certificate: - path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" - csr_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" - ownca_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" - ownca_privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" - provider: ownca - register: cacert_client_cert - - - name: Get {{ item.name }} OpenSSL crt and key content - ansible.builtin.shell: | - cat {{ cacert_ssl_gen_path }}/{{ item.name }}.{crt,key} - register: concated_crt_key - changed_when: false - - - name: Concatenate and save {{ item.name }} OpenSSL crt and key to single file - copy: - content: "{{ concated_crt_key.stdout }}" - dest: "{{ cacert_ssl_gen_path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" - loop: "{{ item.dest }}" - loop_control: - loop_var: dest - when: - - dest.concat is defined - -- name: Distribute client certs - become: true - block: - - name: Write {{ item.name }} OpenSSL key - copy: - src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" - dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.key" - mode: 0600 - delegate_to: "{{ dest.host }}" - loop: "{{ item.dest }}" - loop_control: - loop_var: dest - when: - - dest.concat is not defined - - - name: Write {{ item.name }} OpenSSL crt - copy: - src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" - dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.crt" - delegate_to: "{{ dest.host }}" - loop: "{{ item.dest }}" - loop_control: - loop_var: dest - when: - - dest.concat is not defined - - - name: Write concatenated {{ item.name }} OpenSSL crt and key - copy: - src: "{{ cacert_ssl_gen_path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" - dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" - delegate_to: "{{ dest.host }}" - loop: "{{ item.dest }}" - loop_control: - loop_var: dest - when: - - dest.concat is defined diff --git a/tasks/cn_certs.yaml b/tasks/cn_certs.yaml new file mode 100644 index 0000000..156dd0f --- /dev/null +++ b/tasks/cn_certs.yaml @@ -0,0 +1,170 @@ +- name: CA and certs | Generate CN certs and keys + when: inventory_hostname in groups[cacert_ca_group] + block: + - name: Generate an OpenSSL private client key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + when: cacert_cert is not defined + register: cacert_client_key_gen + + - name: Generate subject_alt_ips + set_fact: + client_subject_alt_ips: "{{ item.subject_alt_ips | map('regex_replace', '^', 'IP:') | list }}" + when: item.subject_alt_ips is defined + + - name: Generate subject_alt_names + set_fact: + client_subject_alt_names: "{{ item.subject_alt_names | map('regex_replace', '^', 'DNS:') | list }}" + when: item.subject_alt_names is defined + + - name: Generate an OpenSSL Certificate Signing Request for client + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + common_name: "{{ item.name }}" + register: cacert_client_csr + when: + - item.subject_alt_names is not defined + - item.subject_alt_ips is not defined + + - name: Generate an OpenSSL Certificate Signing Request for client with subject_alt_name + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + common_name: "{{ item.name }}" + subject_alt_name: "{{ ((client_subject_alt_ips | default([])) + (client_subject_alt_names | default([]) + (['DNS:' ~ item.name]))) }}" + register: cacert_client_csr + when: item.subject_alt_names is defined or item.subject_alt_ips is defined + + - name: Generate an OpenSSL certificate for client signed with your own CA certificate + community.crypto.x509_certificate: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + csr_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + ownca_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + ownca_privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + provider: ownca + register: cacert_client_cert + + - name: Get {{ item.name }} OpenSSL crt and key content + ansible.builtin.shell: | + cat {{ cacert_ssl_gen_path }}/{{ item.name }}.{crt,key} + register: concated_crt_key + changed_when: false + + - name: Concatenate and save {{ item.name }} OpenSSL crt and key to single file + copy: + content: "{{ concated_crt_key.stdout }}" + dest: "{{ cacert_ssl_gen_path }}/{{ item.name }}.pem" + + - name: Get CN key content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + register: cacert_cn_certs_key_b64 + + - name: Get CN cert content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + register: cacert_cn_certs_cert_b64 + + - name: Get CN cert and key concat content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.pem" + register: cacert_cn_certs_concat_b64 + + - name: Set facts about key and cert + set_fact: + cacert_cn_certs_key: "{{ cacert_cn_certs_key_b64.content | b64decode }}" + cacert_cn_certs_cert: "{{ cacert_cn_certs_cert_b64.content | b64decode }}" + cacert_cn_certs_concat: "{{ cacert_cn_certs_concat_b64.content | b64decode }}" + delegate_to: "{{ fact_item }}" + delegate_facts: true + run_once: true + with_items: + - "{{ groups[cacert_ca_group] | default([]) }}" + - "{{ groups[cacert_clients_group] | default([]) }}" + loop_control: + loop_var: fact_item + +- name: Distribute CN certificates + become: true + when: inventory_hostname in groups[cacert_clients_group] + block: + - name: CA and cert | Check if dest dir exist on remote hosts + file: + name: "{{ host_item.path }}" + state: directory + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: CA and cert | Check if dest dir exist on remote hosts for groups + file: + name: "{{ group_item.path }}" + state: directory + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put CN key for host + copy: + content: "{{ cacert_cn_certs_key }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.key" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put CN cert for host + copy: + content: "{{ cacert_cn_certs_cert }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.crt" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put CN key and cert concat for host + copy: + content: "{{ cacert_cn_certs_concat }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.{{ host_item.concat | default('pem') }}" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put CN key for group + copy: + content: "{{ cacert_cn_certs_key }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.key" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put CN cert for group + copy: + content: "{{ cacert_cn_certs_cert }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.crt" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put CN key and cert concat for group + copy: + content: "{{ cacert_cn_certs_concat }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.{{ group_item.concat | default('pem') }}" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" diff --git a/tasks/group_certs.yaml b/tasks/group_certs.yaml new file mode 100644 index 0000000..5a06ca9 --- /dev/null +++ b/tasks/group_certs.yaml @@ -0,0 +1,173 @@ +- name: CA and certs | Generate group certs and keys + when: inventory_hostname in groups[cacert_ca_group] + block: + - name: Generate subject_alt_ips + set_fact: + client_subject_alt_ips: "{{ groups[group_item] | map('extract', hostvars, ['ansible_host']) | map('regex_replace', '^', 'IP:') | list }}" + loop: "{{ item.host_groups }}" + loop_control: + loop_var: group_item + when: + - groups[group_item] is defined + + - debug: + msg: "{{ client_subject_alt_ips }}" + + - name: Generate subject_alt_names + set_fact: + client_subject_alt_names: "{{ groups[group_item] | map('extract', hostvars, ['inventory_hostname']) | map('regex_replace', '^', 'DNS:') | list }}" + loop: "{{ item.host_groups }}" + loop_control: + loop_var: group_item + when: + - groups[group_item] is defined + + - debug: + msg: "{{ client_subject_alt_names }}" + + - name: Generate an OpenSSL private client key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + register: cacert_client_key_gen + + - name: Generate an OpenSSL Certificate Signing Request for client with subject_alt_name + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + common_name: "{{ item.name }}" + subject_alt_name: "{{ ((client_subject_alt_ips | default([])) + (client_subject_alt_names | default([]))) }}" + register: cacert_client_csr + + - name: Generate an OpenSSL certificate for client signed with your own CA certificate + community.crypto.x509_certificate: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + csr_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + ownca_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + ownca_privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + provider: ownca + register: cacert_client_cert + + - name: Get {{ item.name }} OpenSSL crt and key content + ansible.builtin.shell: | + cat {{ cacert_ssl_gen_path }}/{{ item.name }}.{crt,key} + register: concated_crt_key + changed_when: false + + - name: Concatenate and save {{ item.name }} OpenSSL crt and key to single file + copy: + content: "{{ concated_crt_key.stdout }}" + dest: "{{ cacert_ssl_gen_path }}/{{ item.name }}.pem" + + - name: Get group key content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + register: cacert_group_certs_key_b64 + + - name: Get group cert content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + register: cacert_group_certs_cert_b64 + + - name: Get group cert and key concat content + slurp: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.pem" + register: cacert_group_certs_concat_b64 + + - name: Set facts about key and cert + set_fact: + cacert_group_certs_key: "{{ cacert_group_certs_key_b64.content | b64decode }}" + cacert_group_certs_cert: "{{ cacert_group_certs_cert_b64.content | b64decode }}" + cacert_group_certs_concat: "{{ cacert_group_certs_concat_b64.content | b64decode }}" + delegate_to: "{{ fact_item }}" + delegate_facts: true + run_once: true + with_items: + - "{{ groups[cacert_ca_group] | default([]) }}" + - "{{ groups[cacert_clients_group] | default([]) }}" + loop_control: + loop_var: fact_item + +- name: Distribute group certificates + become: true + when: inventory_hostname in groups[cacert_clients_group] + block: + - name: CA and cert | Check if dest dir exist on remote host + file: + name: "{{ host_item.path }}" + state: directory + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: CA and cert | Check if dest dir exist on remote host for group + file: + name: "{{ group_item.path }}" + state: directory + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put group key for host + copy: + content: "{{ cacert_group_certs_key }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.key" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put group cert for host + copy: + content: "{{ cacert_group_certs_cert }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.crt" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put group key and cert concat for host + copy: + content: "{{ cacert_group_certs_concat }}" + dest: "{{ host_item.path }}/{{ host_item.name | default(item.name) }}.{{ host_item.concat | default('pem') }}" + loop: "{{ item.hosts }}" + loop_control: + loop_var: host_item + when: + - inventory_hostname == host_item.host + + - name: Put group key for group + copy: + content: "{{ cacert_group_certs_key }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.key" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put group cert for group + copy: + content: "{{ cacert_group_certs_cert }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.crt" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + + - name: Put group key and cert concat for group + copy: + content: "{{ cacert_group_certs_concat }}" + dest: "{{ group_item.path }}/{{ group_item.name | default(item.name) }}.{{ group_item.concat | default('pem') }}" + loop: "{{ item.groups }}" + loop_control: + loop_var: group_item + when: + - "inventory_hostname in (groups[group_item.group] | map('extract', hostvars, ['inventory_hostname']) | join(','))" + diff --git a/tasks/main.yaml b/tasks/main.yaml index f784227..1a564ca 100644 --- a/tasks/main.yaml +++ b/tasks/main.yaml @@ -2,12 +2,20 @@ file: name: "{{ cacert_ssl_gen_path }}" state: directory + when: + - inventory_hostname in groups[cacert_ca_group] -- name: CA and certs | Include CA creation +- name: CA and certs | Include CA include_tasks: ca.yaml - when: "inventory_hostname in groups.cacert_ca" -- name: CA and certs | Include certs creation - include_tasks: certs.yaml - loop: "{{ cacert_certs }}" - when: "inventory_hostname in groups.cacert_ca" +- name: CA and certs | Include CN certs + include_tasks: cn_certs.yaml + loop: "{{ cacert_cn_certs }}" + when: + - cacert_cn_certs is defined + +- name: CA and certs | Include group certs + include_tasks: group_certs.yaml + loop: "{{ cacert_group_certs }}" + when: + - cacert_group_certs is defined