|
| 1 | +# How to: Setup externally signed TLS certificates |
| 2 | + |
| 3 | +The playbook is able to provision an internal CA and automatically sign the host certificates. |
| 4 | + |
| 5 | +However, it is more likely that an external CA will be used in production environments. |
| 6 | + |
| 7 | +This guide will run through specifics for deploying clusters using an external CA to sign the host certificates. |
| 8 | + |
| 9 | +At a high-level, the playbook generates and distributes the TLS keys and certificates in three steps: |
| 10 | + |
| 11 | +- Phase 1 (generation) |
| 12 | + * Create the host keys |
| 13 | + * Generate the keystores |
| 14 | + * Generate the CSRs |
| 15 | + * Copy the CSRs to the Ansible controller |
| 16 | +- Phase 2 (signing) |
| 17 | + * Sign the certificates |
| 18 | +- Phase 3 (installation) |
| 19 | + * Copy the signed certificates to the hosts |
| 20 | + * Copy the CA certificates to the hosts |
| 21 | + |
| 22 | +When `ca_server` is used, this all occurs automatically. |
| 23 | + |
| 24 | +However, when an external CA is used, a few manual steps are required to complete the deployment: |
| 25 | + |
| 26 | +Starting with the definition, assuming nothing has been deployed: |
| 27 | + |
| 28 | +## Ensure that `ca_server` is **not** present in the inventory |
| 29 | + |
| 30 | +The `ca_server` is the playbook's internal CA. |
| 31 | + |
| 32 | +As we wish to use an external CA, it should be omitted from the inventory file. |
| 33 | + |
| 34 | +## Set `tls_ca_certs` to point to the external CA certificates |
| 35 | + |
| 36 | +Here, we need to set `tls_ca_certs` in `extra_vars.yml` to point to the external CA certificates (on the Ansible controller): |
| 37 | + |
| 38 | +``` |
| 39 | +tls_ca_certs: |
| 40 | + - alias: ipaca |
| 41 | + path: /root/ca.crt |
| 42 | +``` |
| 43 | + |
| 44 | +In this example, our CA certificate exists on the Ansible controller at `/root/ca.crt`. |
| 45 | + |
| 46 | +**Note:** If you have an intermediate CA and a root CA, please include both certificates here. |
| 47 | + |
| 48 | +## Run the playbook deployment as usual |
| 49 | + |
| 50 | +If everything is configured correctly, it should run as usual until we reach `prepare_tls.yml`. |
| 51 | + |
| 52 | +Here, in `prepare_tls.yml`, it will fail with a message: |
| 53 | + |
| 54 | +> Signed cert for <hostname> could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set. |
| 55 | +
|
| 56 | +E.g. |
| 57 | + |
| 58 | +``` |
| 59 | +TASK [security/tls_install_certs : fail] ************************************************************************************************************** |
| 60 | +fatal: [host-1.example.com] FAILED! => {"changed": false, "msg": "\"Signed cert for host-1.example.com could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set.\n"} |
| 61 | +fatal: [host-2.example.com] FAILED! => {"changed": false, "msg": "\"Signed cert for host-1.example.com could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set.\n"} |
| 62 | +fatal: [host-3.example.com] FAILED! => {"changed": false, "msg": "\"Signed cert for host-1.example.com could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set.\n"} |
| 63 | +fatal: [host-4.example.com] FAILED! => {"changed": false, "msg": "\"Signed cert for host-1.example.com could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set.\n"} |
| 64 | +``` |
| 65 | + |
| 66 | +This is expected. |
| 67 | + |
| 68 | +At this point, the playbook will have generated the TLS keys and CSRs and copied the CSRs to the Ansible controller (stage 1). |
| 69 | + |
| 70 | +It is up to us now to sign the CSRs and copy the signed certificates back to the Ansible controller: |
| 71 | + |
| 72 | +## Sign the CSRs generated by the playbook |
| 73 | + |
| 74 | +You will find copies of the TLS CSRs in `{{ local_temp_dir }}/csrs` on the Ansible controller (default `/tmp/csrs`). |
| 75 | + |
| 76 | +``` |
| 77 | +# ls /tmp/csrs |
| 78 | +host-1.example.com.csr host-3.example.com.csr |
| 79 | +host-2.example.com.csr host-4.example.com.csr |
| 80 | +``` |
| 81 | + |
| 82 | +Sign the CSRs and copy the signed certificates to the Ansible controller using the same filename, replacing `.csr` with `.pem`. |
| 83 | + |
| 84 | +Place these signed certificates in `{{ local_temp_dir }}/certs` on the Ansible controller (default `/tmp/certs`). |
| 85 | + |
| 86 | +``` |
| 87 | +# ls /tmp/certs |
| 88 | +host-1.example.com.pem host-3.example.com.pem |
| 89 | +host-2.example.com.pem host-4.example.com.pem |
| 90 | +``` |
| 91 | + |
| 92 | +## Rerun the playbook |
| 93 | + |
| 94 | +The playbook can be restarted now that the signed certificates exist on the Ansible controller (stage 2). |
| 95 | + |
| 96 | +**Note:** To save time, you can start the playbook from `prepare_tls.yml` – skipping completed steps. |
| 97 | + |
| 98 | +The playbook will distribute the new signed certificates and continue as usual. |
| 99 | + |
| 100 | +No other steps are required. |
0 commit comments