ansiblessl-certificateansible-galaxy

Copy the ssl certificate from a server to a host in ansible


I'm trying to copy the Certificate of a local Container registry to a Docker host with ansible version 2.9.6. The registry is managed by someone else but within our local network.

With the shell I would do it in this way:

openssl s_client -showcerts -connect registry.example:443 < /dev/null 2> /dev/null | openssl x509 -outform PEM > ca.crt

So far I worked my way around the community.crypto module for ansible ans managed to get the certificate with:

- name: get certificate from registry
  community.crypto.get_certificate:
    host: "{{ registry_url }}"
    port: "{{ registry_port }}"
  delegate_to: localhost
  become: no
  register: cert

This behaves like the first half of the shell alternative. What I still haven't figured out is how to do the job of the second half, which would be creating the certificate with the content received from the server.

I tried using community.crypto.x509_certificate but I can not make it behave like the openssl_client would in the following shell example.

openssl x509 -outform PEM -in server_content_file -text -out ca.crt

Is there a way to do this with the community.crypto module or in any other way using ansible?


Solution

  • One option you haven't pursued is just running the openssl commands in Ansible. The following example assumes you've set the remotehost variable to e.g. registry.example:

    - hosts: localhost
      gather_facts: false
      tasks:
        - name: get remote certificate
          command: openssl s_client -showcerts -connect {{ remotehost }}
          register: remotecert
    
        - name: extract certificate
          command: openssl x509 -outform PEM
          args:
            stdin: "{{ remotecert.stdout }}"
          register: remotex509
    
        - name: write ca.crt
          copy:
            dest: ./ca.crt
            content: "{{ remotex509.stdout }}"
    

    And while somewhat less granular, you can of course combine everything into a single shell script:

    - hosts: localhost
      gather_facts: false
      tasks:
        - name: get remote certificate
          shell: >-
            openssl s_client -showcerts -connect {{ remotehost }} |
            openssl x509 -outform PEM > ca.crt
          args:
            creates: ca.crt
          register: remotecert
    

    The creates args will cause the task to be skipped if the target file (ca.crt) already exists.