letsencrypt
Ansible Let's Encrypt role
Obtains TLS certificates through ACME from Let's Encrypt.
Once you complete the challenge(s) and obtain the Certificate(s), you are responsible for setting it/them up in your web server(s) of choice.
Requirements
openssl
- Python >= 2.7.9
Role Variables
letsencrypt_certs_dir: Path to work-dir, where all CSRs, Keys and Certs will be stored.
letsencrypt_account_key_name: Name of the Let's Encrypt account's RSA key.
letsencrypt_account_key_size: Size of the Let's Encrypt account's RSA key.
letsencrypt_certs_to_generate: List of certs to generate.
account_email: E-mail address that's going to be exchanged with the ACME server. You'll get cert expiration warnings.
account_key: Path to the RSA key file.
acme_directory: ACME API endpoint. Uses Let's Encrypt's Staging by default.
agreement: URI to TOS doc you agree with.
challenge: The accepted challenge type.
csr: Path to the CSR file.
dest: Path to the resulting Certificate file (where you want to store it).
remaining_days: Number of days for the cert to be valid.
Dependencies
N/A
Example Playbook
In this example, we are requesting a certificate from Let's Encrypt, although in theory, this Ansible module should be compatible with any ACME server.
We have three plays:
- create CSR, Key and issue request for certificate release
- complete the challenge (DNS record in Route53 in this case)
- ask to validate the challenge and grant the certificate.
- name: ACME Step 1
hosts: localhost
connection: local
roles:
- role: letsencrypt
letsencrypt_certs_dir: './files/production/certs'
letsencrypt_account_key_name: 'letsencrypt_account'
letsencrypt_account_key_size: 2048
letsencrypt_certs_to_generate:
- domain: 'your-domain.com'
key_size: 2048
account_email: '[email protected]'
account_key: "{{ letsencrypt_certs_dir }}/{{ letsencrypt_account_key_name }}.key"
challenge: 'dns-01'
agreement: 'https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'
csr: "{{ letsencrypt_certs_dir }}/your-domain.com/your.csr"
dest: "{{ letsencrypt_certs_dir }}/your-domain.com/domain.crt"
acme_directory: 'https://acme-v01.api.letsencrypt.org/directory'
tags: letsencrypt
tasks:
- name: List of Route53 records to create should be set as fact
set_fact:
route53_records_to_add: "{{
route53_records_to_add | default([]) +
[{'zone': item.1.domain,
'record': item.0.challenge_data[item.1.domain]['dns-01']['resource'] + '.' + item.1.domain + '.',
'ttl': 300,
'type': 'TXT',
'value': '\"' + item.0.challenge_data[item.1.domain]['dns-01']['resource_value'] + '\"' }]
}}"
with_together:
- "{{ letsencrypt_acme_step_one }}"
- "{{ letsencrypt_certs_to_obtain | default([]) }}"
when: item.1.domain == item.0.item.domain
tags: route53
- name: ACME challenge solving (DNS record in Route53)
hosts: localhost
connection: local
roles:
- role: route53
tags: route53
- name: ACME Step 2
hosts: localhost
connection: local
pre_tasks:
- name: We should wait for the DNS changes to propagate
pause: minutes=1
roles:
- role: letsencrypt
letsencrypt_acme_step: two
tags: letsencrypt
Completing other challenge types should be all the same and opaque to this role.
Testing
The tests are relying on the DNS challenge type and are solving it via AWS Route53.
If you want to run the tests on the provided docker environment, run the following commands:
$ cd /path/to/ansible-roles/letsencrypt
$ ansible-galaxy install \
--force \
--role-file=./tests/requirements.yml \
--roles-path=./tests/dependencies
$ docker build \
--no-cache \
--pull \
--tag ansible-roles-test \
tests/support
$ docker run \
--rm \
--interactive \
--tty \
--volume $PWD:/etc/ansible/roles/letsencrypt \
--volume $PWD/tests/dependencies:/etc/ansible/roles/letsencrypt/tests/roles:ro \
--env AWS_ACCESS_KEY=$AWS_ACCESS_KEY \
--env AWS_SECRET_KEY=$AWS_SECRET_KEY \
--workdir /etc/ansible/roles/letsencrypt/tests \
ansible-roles-test
To-do
- Support other challenge types
- Support other DNS services APIs (i.e. Cloud DNS)
- Integration with some web servers roles (i.e. NGINX, Apache)
- Support renewal
- Support multiple Ansible versions and Distros
- Update Ansible in the tests Docker image to be able to not specify the agreement for the DNS challenge.
License
This project is licensed under the terms of the GNU GPL v3.0 license.
Author Information
Role created by Dan Vaida.
Contributions
See the ToDo list. Contributions are welcome.
Obtains TLS certificates through ACME from Let's Encrypt.
ansible-galaxy install danvaida/ansible-roles-letsencrypt