Generating self-signed OpenSSL certs with Ansible 2.4's crypto modules

Ansible 2.4 is notable for a number of improvements and changes, but one that flew under my radar was the addition of a set of new openssl_* crypto-related modules.

The following modules were added in Ansible 2.4.0:

In the past, when I've had to generate OpenSSL certs on my servers (usually for CI purposes or in local test environments), I've used the command or shell module and openssl with a bunch of flags (example), and while that technique still works, it's slightly annoying to try to make it easy to read and be configurable for different situations.

With these new Ansible modules, though, it's a lot simpler to go through the process of generating a self-signed cert:

- name: Ensure directory exists for local self-signed TLS certs.
    path: /etc/letsencrypt/live/{{ server_hostname }}
    state: directory

- name: Generate an OpenSSL private key.
    path: /etc/letsencrypt/live/{{ server_hostname }}/privkey.pem

- name: Generate an OpenSSL CSR.
    path: /etc/ssl/private/{{ server_hostname }}.csr
    privatekey_path: /etc/letsencrypt/live/{{ server_hostname }}/privkey.pem
    common_name: "{{ server_hostname }}"

- name: Generate a Self Signed OpenSSL certificate.
    path: /etc/letsencrypt/live/{{ server_hostname }}/fullchain.pem
    privatekey_path: /etc/letsencrypt/live/{{ server_hostname }}/privkey.pem
    csr_path: /etc/ssl/private/{{ server_hostname }}.csr
    provider: selfsigned

I used the above set of tasks to generate example letsencrypt/certbot certs for use when developing locally on some infrastructure which has HSTS enabled, so all requests to the domain and it's subdomains requires working SSL. Note that you might need to install pyOpenSSL if it's not already present; you can use the pip module to do that prior to running the openssl_* tasks:

- name: Ensure python OpenSSL dependencies are installed.
    name: pyOpenSSL
    state: present

And if you need pip, you can install it with my geerlingguy.pip role!

Certbot still has a bit of a chicken-and-egg problem when it comes to fully automating the cert and webserver setup process, but using tasks like the ones above can make it easier to shim in some valid (but self-signed) certs when Let's Encrypt can't work (e.g. in CI infrastructure, or in infrastructure behind proxies or NAT).


This is some really amazing information that you've published. Keep up the good work

When the provider is selfsigned, where can I get the ca.pem and cakey.pem files? Does the modules suppose it is already in place, or does PyOpenssl take cares oy configuring openssl.cnf and set up the CA?

I think when the cert is self-signed, that means that the cert itself *is* the ca.

What about the {{ server_hostname }} variable? Isn't it supposed to be defined beforehand?