
If you are not familiar with modules, check out Ansible - Getting Started with Modules.
Let's say https://www.example.com uses a certificate chain consisting of a root CA, and intermediate CA, and a server certificate to create a secured connection.
community.crypto.get_certificate can be used to get the SSL certificate being presented by a URL.
---
- hosts: localhost
tasks:
- name: get the server certificate being presented by https://www.example.com
community.crypto.get_certificate:
host: www.example.com
port: 443
register: server_cert
- ansible.builtin.debug:
var: server_cert
...
Running this playbook should return something like this.
ok: [localhost] => {
"server_cert": {
"cert": "-----BEGIN CERTIFICATE-----\nMII...9NFcE=\n-----END CERTIFICATE-----\n",
"changed": false,
"deprecations": [
{
"collection_name": "community.crypto",
"msg": "The default value `false` for asn1_base64 is deprecated and will change to `true` in community.crypto 3.0.0. If you need this value, it is best to set the value explicitly and adjust your roles/playbooks to use `asn1_base64=true` as soon as possible",
"version": "3.0.0"
}
],
"expired": false,
"extensions": [],
"failed": false,
"issuer": {
"CN": "RootCA",
"DC": "example"
},
"not_after": "20250717143450Z",
"not_before": "20240717143450Z",
"serial_number": 123456789012123456789012123456789012123456789012123456789012,
"signature_algorithm": "sha256WithRSAEncryption",
"subject": {
"C": "US",
"CN": "www.example.com",
"L": "Guam",
"O": "Acme",
"ST": "California"
},
"version": 2
}
}
By default, only the server certificate will be returned. get_certificate_chain can be used to return the full certificate chain, the root CA, the intermediate CA, and the server certificate.
I am not exactly sure which version of the community.crypto collection added get_certificate_chain. If you are using an older version of the community.crypto collection, such as version 2.18.0, you will need to update the community.crypto collection to a recent version, such as version 2.26.3. Check out my article FreeKB - Ansible - Install a collection using the ansible-galaxy collection install command.
---
- hosts: localhost
tasks:
- name: get the server certificate being presented by https://www.example.com
community.crypto.get_certificate:
host: www.example.com
port: 443
get_certificate_chain: true
register: ssl_chain
- ansible.builtin.debug:
var: ssl_chain
...
Almost always, you are going to want to do something with the certificate data, such as determine when the certificate expires, or to base64 encode the certificate data.
- Use ansible.bulitin.file to create an empty file
- Use ansible.builtin.lineinfile to append each line of the certificate data to the file
- Use ansible.builtin.shell to get the certificate subject
- Use ansible.builtin.shell to base64 encode the certificate data
- Use ansible.bulitin.file to delete the file
---
- hosts: localhost
tasks:
- name: get the server certificate being presented by https://www.example.com
community.crypto.get_certificate:
host: www.example.com
port: 443
get_certificate_chain: true
register: ssl_chain
- ansible.builtin.debug:
var: ssl_chain
- block:
- name: touch /tmp/my.pem
ansible.builtin.file:
path: /tmp/my.pem
state: touch
- name: append certificate_chain.verified_chain[0] to /tmp/my.pem
ansible.builtin.lineinfile:
path: /tmp/my.pem
line: "{{ item }}"
with_items: "{{ certificate_chain.verified_chain[0].split('\n') }}"
when: item != ''
- name: register SSL certificate subject
ansible.builtin.shell: cat /tmp/my.pem | openssl x509 -subject -noout
register: subject
- ansible.builtin.debug:
var: subject
- block:
- name: base64 encode /tmp/my.pem
ansible.builtin.shell: cat /tmp/my.pem | base64 | xargs | sed 's| ||g'
register: base64_encode
- name: set_fact intermediateCA
ansible.builtin.set_fact:
intermediateCA: "{{ base64_encode.stdout }}"
when: subject.stdout == "subject=DC = com, DC = example, CN = IntermediateCA"
- block:
- name: base64 encode /tmp/my.pem
ansible.builtin.shell: cat /tmp/my.pem | base64 | xargs | sed 's| ||g'
register: base64_encode
- name: set_fact rootCA
ansible.builtin.set_fact:
rootCA: "{{ base64_encode.stdout }}"
when: subject.stdout == "subject=CN = rootCA"
always:
- name: always delete /tmp/my.pem
ansible.builtin.file:
path: /tmp/my.pem
state: absent
...
Did you find this article helpful?
If so, consider buying me a coffee over at