95 lines
3.4 KiB
YAML
95 lines
3.4 KiB
YAML
---
|
|
# 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
|