Vault PKI IAC
1. Creating a Root CA with Vault PKI and Ansible
- name: Check if PKI path is already mounted
community.hashi_vault.vault_read:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts"
validate_certs: false
register: mounts_info
- name: Enable PKI secrets engine at "pki"
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts/{{ certificate.path }}"
validate_certs: false
data:
type: "pki"
when: certificate.path + "/" not in mounts_info.data.keys()
- name: Tune PKI secrets engine
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts/{{ certificate.path }}/tune"
validate_certs: false
data:
max_lease_ttl: "{{ certificate.max_lease_ttl }}"
- name: Generate self-signed Root CA
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/root/generate/internal"
validate_certs: false
data:
common_name: "{{ certificate.common_name }}"
ttl: "{{ certificate.ttl }}"
- name: Configure URLs for issuing cert and CRL
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/config/urls"
validate_certs: false
data:
issuing_certificates: "{{ vault_addr }}/v1/{{ certificate.path }}/ca"
crl_distribution_points: "{{ vault_addr }}/v1/{{ certificate.path }}/crl"
Ansible tasks to create an intermediate certificate
- name: Check if PKI path is already mounted
community.hashi_vault.vault_read:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts"
validate_certs: false
register: mounts_info
- name: Enable PKI secrets engine at "pki"
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts/{{ certificate.path }}"
validate_certs: false
data:
type: "pki"
when: certificate.path + "/" not in mounts_info.data.keys()
- name: Tune intermediate PKI secrets engine
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "sys/mounts/{{ certificate.path }}/tune"
validate_certs: false
data:
max_lease_ttl: "{{ certificate.max_lease_ttl }}"
- name: Generate intermediate CSR
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/intermediate/generate/internal"
validate_certs: false
data:
common_name: "{{ certificate.common_name }}"
organization: "{{ certificate.issuer.organization }}"
country: "{{ certificate.issuer.country }}"
ou: "{{ certificate.issuer.ou }}"
format: "{{ certificate.format }}"
key_bits: "{{ certificate.issuer.key_bits }}"
key_type: "{{ certificate.issuer.key_type }}"
key_usage: "{{ certificate.key_usage }}"
ext_key_usage: "{{ certificate.ext_key_usage }}"
ttl: "{{ certificate.ttl }}"
register: intermediate_csr
- debug:
msg: "{{ intermediate_csr }}"
- name: Sign CSR with root CA
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.issuer.path }}/root/sign-intermediate"
validate_certs: false
data:
csr: "{{ intermediate_csr.data.data.csr }}"
format: pem_bundle
ttl: "{{ certificate.ttl }}"
register: signed_intermediate
- name: Import signed certificate into intermediate backend
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/intermediate/set-signed"
validate_certs: false
data:
certificate: "{{ signed_intermediate.data.data.certificate }}"
- name: Configure issuing and CRL URLs for intermediate
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/config/urls"
validate_certs: false
data:
issuing_certificates: "{{ vault_addr }}/v1/{{ certificate.path }}/ca"
crl_distribution_points: "{{ vault_addr }}/v1/{{ certificate.path }}/crl"
Creating an issuer role
- name: Create PKI role in intermediate backend
community.hashi_vault.vault_write:
url: "{{ vault_addr }}"
token: "{{ vault_token }}"
path: "{{ certificate.path }}/roles/{{ name }}"
validate_certs: false
data:
allowed_domains: "{{ role.allowed_domains }}"
allow_subdomains: true
allow_any_name: true
enforce_hostnames: true
max_ttl: "{{ role.max_ttl }}"
ttl: "{{ role.ttl }}"
allow_bare_domains: true
allow_localhost: true
allow_wildcard: true
allow_ip_sans: true
key_type: "any"
key_bits: 2048
require_cn: true