diff options
| -rw-r--r-- | group_vars/all.yml | 15 | ||||
| -rw-r--r-- | host_vars/dc0.yml | 1 | ||||
| -rw-r--r-- | roles/acme/defaults/main.yml | 10 | ||||
| -rw-r--r-- | roles/acme/meta/main.yml | 53 | ||||
| -rw-r--r-- | roles/acme/tasks/main.yml | 19 | ||||
| -rw-r--r-- | roles/acme/templates/acme-client.conf.j2 | 27 | 
6 files changed, 90 insertions, 35 deletions
diff --git a/group_vars/all.yml b/group_vars/all.yml index 2ae2bbc..35abefd 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -9,13 +9,11 @@ ansible_become_method: su  wireguard_domain_controller: "{{ __global_domain_controller }}"  relayd_domain_name: "{{ __domain_name }}" -acme_domain_name: "{{ __global_domain_name }}"  nfsclient_server: stack0  httpd_use_nfs: true -relayd_rules: "[ -    {% for rule in __services if -        'domain' in rule and 'port' in rule %} -    {{ {'name': rule.name, 'domain': rule.domain, 'port': rule.port} }}, +acme_rules: "[ +    {% for rule in __services if 'domain' in rule %} +    {{ {'domain': rule.domain} }},      {% endfor %}    ]"  pf_rules: "[ @@ -24,7 +22,12 @@ pf_rules: "[      {{ {'name': rule.name, 'port': rule.port, 'protocol': rule.protocol} }},      {% endfor %}    ]" -acme_rules: "{{ __services }}" +relayd_rules: "[ +    {% for rule in __services if +        'domain' in rule and 'port' in rule %} +    {{ {'name': rule.name, 'domain': rule.domain, 'port': rule.port} }}, +    {% endfor %} +  ]"  # playbook specific diff --git a/host_vars/dc0.yml b/host_vars/dc0.yml index 1ab8872..f0866ff 100644 --- a/host_vars/dc0.yml +++ b/host_vars/dc0.yml @@ -6,6 +6,7 @@ httpd_use_nfs: false  git_dir: /var/www/data/git  sshd_listen_port: "{{ ansible_port }}"  relayd_connected_hosts: servers +acme_connected_hosts: servers  __is_vm: true diff --git a/roles/acme/defaults/main.yml b/roles/acme/defaults/main.yml index 66ca704..cd713c6 100644 --- a/roles/acme/defaults/main.yml +++ b/roles/acme/defaults/main.yml @@ -1,6 +1,10 @@  --- -acme_rules: {} -  acme_configuration_file: /etc/acme-client.conf -acme_domain_name: null +acme_certificates_dir: /etc/ssl +acme_keys_dir: /etc/ssl/private + +acme_authority: +  name: letsencrypt +  url: https://acme-v02.api.letsencrypt.org/directory +  key: /etc/acme/letsencrypt-privkey.pem diff --git a/roles/acme/meta/main.yml b/roles/acme/meta/main.yml new file mode 100644 index 0000000..924fd90 --- /dev/null +++ b/roles/acme/meta/main.yml @@ -0,0 +1,53 @@ +--- + +argument_specs: +  main: +    short_description: acme main entrypoint. +    options: + +      acme_rules: +        type: list +        elements: dict +        required: true +        options: +          domain: +            type: str +            required: true +            description: Acme domain name + +      acme_authority: +        type: dict +        required: true +        options: +          name: +            type: str +            required: true +            description: Acme authority name +          url: +            type: str +            required: true +            description: Acme authority api url +          key: +            type: path +            required: true +            description: Acme authority key file + +      acme_certificates_dir: +        type: path +        required: true +        description: Acme certificates directory + +      acme_keys_dir: +        type: path +        required: true +        description: Acme keys directory + +      acme_configuration_file: +        type: path +        required: true +        description: Acme configuration file + +      relayd_connected_hosts: +        type: str +        required: true +        description: Group name of hosts for generating certificates diff --git a/roles/acme/tasks/main.yml b/roles/acme/tasks/main.yml index f2d4ba3..c068ab5 100644 --- a/roles/acme/tasks/main.yml +++ b/roles/acme/tasks/main.yml @@ -8,23 +8,24 @@      group: 0      mode: "0644" -- name: retrieve enabled domains  # noqa: no-changed-when +- name: retrieve enabled domains    ansible.builtin.shell: |      set -o pipefail      grep "^domain" /etc/acme-client.conf | cut -d " " -f 2 -  register: subdomains +  register: acme_result_subdomains +  changed_when: false -- name: generate acme certificates  # noqa: no-changed-when +- name: generate acme certificates    ansible.builtin.command: acme-client -v {{ item }} -  loop: "{{ subdomains.stdout_lines }}" +  loop: "{{ acme_result_subdomains.stdout_lines }}"    register: acme_result_generation -  failed_when: -    - acme_result_generation.rc != 0 -    - "'certificate valid' not in acme_result_generation.stderr" +  failed_when: acme_result_generation.rc == 1 +  changed_when: acme_result_generation.rc != 2  - name: display registered certificates    ansible.builtin.debug: -    msg: "{{ acme_result_generation.results | map(attribute='stderr') }}" +    msg: "{{ acme_result_generation.results | map(attribute='stderr') +      | join('\n') }}"  - name: enable automatic acme certificates update    ansible.builtin.cron: @@ -32,4 +33,4 @@      minute: 0      hour: 6,18      job: "acme-client -v {{ item }} && rcctl reload relayd" -  loop: "{{ subdomains.stdout_lines }}" +  loop: "{{ acme_result_subdomains.stdout_lines }}" diff --git a/roles/acme/templates/acme-client.conf.j2 b/roles/acme/templates/acme-client.conf.j2 index 583c3d5..a6516c6 100644 --- a/roles/acme/templates/acme-client.conf.j2 +++ b/roles/acme/templates/acme-client.conf.j2 @@ -1,26 +1,19 @@  # managed by Ansible  {% import 'macros.j2' as macros with context %} -authority letsencrypt { -	api url "https://acme-v02.api.letsencrypt.org/directory" -	account key "/etc/acme/letsencrypt-privkey.pem" +authority {{ acme_authority.name }} { +	api url "{{ acme_authority.url }}" +	account key "{{ acme_authority.key }}"  } -domain {{ acme_domain_name }} { -	alternative names { www.{{ acme_domain_name }} } -	domain key "/etc/ssl/private/{{ acme_domain_name }}.key" -	domain full chain certificate "/etc/ssl/{{ acme_domain_name }}.crt" -	sign with letsencrypt -} +{% call(h) macros.loop_valid_hosts(relayd_connected_hosts) -%} +{% for rule in h.acme_rules %} -{% call(h) macros.loop_valid_hosts("servers") -%} -{% for name, rules in h.acme_rules.items() if rules.domain is defined %} -domain {{ rules.domain }}.{{ acme_domain_name }} { -	{% set domain = rules.domain ~ "." ~ acme_domain_name %} -	alternative names { www.{{ domain }} } -	domain key "/etc/ssl/private/{{ domain }}.key" -	domain full chain certificate "/etc/ssl/{{ domain }}.crt" -	sign with letsencrypt +domain {{ rule.domain }} { +	alternative names { www.{{ rule.domain }} } +	domain key "{{ acme_keys_dir }}/{{ rule.domain }}.key" +	domain full chain certificate "{{ acme_certificates_dir }}/{{ rule.domain }}.crt" +	sign with {{ acme_authority.name }}  }  {% endfor %}  {%- endcall %}  |