--- # included per website, expects `site` (normalized entry of _websites) - name: "{{ site.domain }}: check for existing certificate" stat: path: /etc/ssl/private/{{ site.domain }}.key register: _website_key - name: "{{ site.domain }}: request certificate" when: not _website_key.stat.exists block: - name: "{{ site.domain }}: generate reachability token" set_fact: _website_token: "ansible-check-{{ lookup('password', '/dev/null chars=ascii_letters,digits length=32') }}" - name: "{{ site.domain }}: create acme-challenge directory" file: path: "{{ site.docroot }}/.well-known/acme-challenge" owner: root group: root mode: '0755' state: directory - name: "{{ site.domain }}: place reachability token" copy: dest: "{{ site.docroot }}/.well-known/acme-challenge/{{ _website_token }}" content: "{{ _website_token }}" mode: '0644' when: site.check_dns | bool - name: "{{ site.domain }}: check that the domain points to this host" uri: url: "http://{{ site.domain }}/.well-known/acme-challenge/{{ _website_token }}" return_content: true follow_redirects: none timeout: "{{ website_check_timeout }}" register: _website_check failed_when: false delegate_to: "{{ website_check_host }}" when: site.check_dns | bool - name: "{{ site.domain }}: remove reachability token" file: path: "{{ site.docroot }}/.well-known/acme-challenge/{{ _website_token }}" state: absent - name: "{{ site.domain }}: evaluate reachability" set_fact: _website_reachable: >- {{ not site.check_dns | bool or (_website_check.status | default(-1) == 200 and (_website_check.content | default('') | trim) == _website_token) }} - name: "{{ site.domain }}: domain does not reach this host, skipping certificate" set_fact: _website_without_cert: "{{ _website_without_cert + [site.domain] }}" when: not _website_reachable | bool - name: "{{ site.domain }}: get certificate" command: >- /root/.acme.sh/acme.sh --issue --webroot {{ site.docroot }} {% if site.use_local_ca | bool and acme_sh_server is defined %}--server {{ acme_sh_server }} --insecure --force --days 10{% else %}--server letsencrypt{% endif %} -d {{ site.domain }} --email {{ acme_sh_email }} --key-file /etc/ssl/private/{{ site.domain }}.key --fullchain-file /etc/ssl/certs/{{ site.domain }}.pem --reloadcmd "service apache2 reload" args: creates: /etc/ssl/private/{{ site.domain }}.key when: _website_reachable | bool - name: "{{ site.domain }}: generate ssl vhost" template: src: apache-ssl.conf.j2 dest: /etc/apache2/sites-available/{{ site.domain }}-ssl.conf owner: root group: root mode: "0644" when: site.domain not in _website_without_cert notify: - reload apache2 - name: "{{ site.domain }}: activate ssl vhost" file: state: link src: /etc/apache2/sites-available/{{ site.domain }}-ssl.conf dest: /etc/apache2/sites-enabled/{{ site.domain }}-ssl.conf when: site.domain not in _website_without_cert notify: - reload apache2 # directives now live in the ssl vhost itself - name: "{{ site.domain }}: remove legacy optionalDirectives include" file: path: /etc/apache2/conf-available/{{ site.domain }}-ssl-optionalDirectives.conf state: absent