created tasks to handle minimal-ca, self-signed and letsencrypt-certbot certificates
This commit is contained in:
parent
84c2277e80
commit
066d95535e
114
README.md
114
README.md
|
|
@ -1,23 +1,28 @@
|
|||
# Ansible Role for certificate generation
|
||||
# Certificate Generator Role
|
||||
|
||||
**Tested:**
|
||||
* Debian 11
|
||||
|
||||
## Functionality
|
||||
|
||||
* Package installation
|
||||
* **Package installation**
|
||||
* Ansible dependencies (_minimal_)
|
||||
*
|
||||
* Configuration
|
||||
* Two Possible Modes
|
||||
* Generate Self-Signed certificate
|
||||
* Create an internal-ca and generate certificates using it
|
||||
* Default config:
|
||||
* Crypto Dependencies
|
||||
|
||||
|
||||
* **Configuration**
|
||||
* **Four Possible Modes**:
|
||||
* Generate **Self-Signed** certificate
|
||||
* Use a **minimal Certificate Authority** to create signed certificates
|
||||
* Configure **LetsEncrypt-Certbot** to generate publicly valid certificates
|
||||
* Supported for Nginx and Apache
|
||||
* Host needs to have a valid public dns record pointed at it
|
||||
* Needs to be publicly reachable over port 80/tcp
|
||||
* _Use a proper **Certificate Authority** (_full PKI_) to create **signed certificates**_ => not yet available
|
||||
|
||||
|
||||
* **Default config**:
|
||||
* Mode => Self-Signed
|
||||
* Default opt-ins:
|
||||
*
|
||||
* Default opt-outs:
|
||||
*
|
||||
|
||||
|
||||
## Info
|
||||
|
|
@ -28,6 +33,10 @@
|
|||
* **Note:** Most of this functionality can be opted in or out using the main defaults file and variables!
|
||||
|
||||
|
||||
* **Note:** The certificate file-name (_name variable as defined or else CommonName_) will be updated:
|
||||
* spaces are transformed into underlines
|
||||
* all Characters except "0-9a-zA-Z." are removed
|
||||
* the file-extension (_crt/chain.crt/key/csr_) will be appended
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
@ -36,20 +45,89 @@
|
|||
|
||||
## Usage
|
||||
|
||||
Define the config as needed:
|
||||
### Notes
|
||||
The **self-signed and minimal-ca** modes will only create a single certificate per run.
|
||||
|
||||
Re-runs can save some overhead by using the 'certs' tag.
|
||||
|
||||
|
||||
The **LetsEncrypt** mode will create/remove multiple certificates as defined.
|
||||
|
||||
|
||||
### Config
|
||||
|
||||
Example for LetsEncrypt config:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
|
||||
certs:
|
||||
mode: 'le_certbot'
|
||||
path: '/etc/apache2/ssl'
|
||||
letsencrypt:
|
||||
certs:
|
||||
myNiceSite:
|
||||
domains: ['myRandomSite.net', 'ansibleguy.net']
|
||||
email: 'certs@template.ansibleguy.net'
|
||||
service: 'apache'
|
||||
```
|
||||
|
||||
Example for Self-Signed config:
|
||||
|
||||
```yaml
|
||||
certs:
|
||||
mode: 'selfsigned'
|
||||
path: '/etc/nginx/ssl'
|
||||
group_key: 'nginx'
|
||||
owner_cert: 'nginx'
|
||||
cert:
|
||||
cn: 'My great certificate!'
|
||||
org: 'AnsibleGuy'
|
||||
country: 'AT'
|
||||
email: 'certs@template.ansibleguy.net'
|
||||
domains: ['mySoGreat.site', 'ansibleguy.net']
|
||||
ips: ['192.168.44.2']
|
||||
pwd: !vault ...
|
||||
```
|
||||
|
||||
Example for minimal-CA config:
|
||||
|
||||
```yaml
|
||||
certs:
|
||||
mode: 'ca'
|
||||
path: '/etc/ca/certs'
|
||||
mode_key: '0400'
|
||||
cert:
|
||||
name: 'custom_file_name' # extension will be appended
|
||||
cn: 'My great certificate!'
|
||||
org: 'AnsibleGuy'
|
||||
country: 'AT'
|
||||
email: 'certs@template.ansibleguy.net'
|
||||
domains: ['mySoGreat.site', 'ansibleguy.net']
|
||||
ca:
|
||||
path: '/etc/ca'
|
||||
cn: 'SUPER CertificateAuthority'
|
||||
org: 'AnsibleGuy'
|
||||
country: 'AT'
|
||||
email: 'certs@template.ansibleguy.net'
|
||||
pwd: !vault ...
|
||||
```
|
||||
|
||||
Using the minimal-CA you can create multiple certificates signed by the CA by re-running the role with changed 'cert' settings.
|
||||
|
||||
|
||||
You might want to use 'ansible-vault' to encrypt your passwords:
|
||||
```bash
|
||||
ansible-vault encrypt_string
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
Run the playbook:
|
||||
```bash
|
||||
ansible-playbook -K -D -i inventory/hosts.yml playbook.yml
|
||||
ansible-playbook -K -D -i inventory/hosts.yml playbook.yml --ask-vault-pass
|
||||
```
|
||||
|
||||
There are also some useful **tags** available:
|
||||
* base => only configure basics; sites will not be touched
|
||||
* sites
|
||||
* certs => ignore ca tasks; only generate certs
|
||||
* selfsigned
|
||||
* config
|
||||
* certs
|
||||
|
|
|
|||
|
|
@ -1,8 +1,85 @@
|
|||
---
|
||||
|
||||
# default config => is overwritten by provided config
|
||||
default_app: {}
|
||||
default_certs:
|
||||
mode: 'selfsigned' # selfsigned, ca, ca_min, le_certbot
|
||||
path: '/etc/certs'
|
||||
|
||||
APP_CONFIG: "{{ default_app | combine(app, recursive=true) }}"
|
||||
cert:
|
||||
name:
|
||||
key_size: 4096 # 1024, 2048, 4096
|
||||
key_type: 'RSA'
|
||||
cipher: 'AES-256-CBC' # see: 'openssl list -cipher-algorithms'
|
||||
digest: 'sha256'
|
||||
regenerate: 'partial_idempotence'
|
||||
pwd:
|
||||
domains: []
|
||||
ips: []
|
||||
|
||||
default_instance_config: {}
|
||||
# certificate config
|
||||
cn: 'Ansible Certificate'
|
||||
org:
|
||||
ou:
|
||||
country:
|
||||
state:
|
||||
locality:
|
||||
email: # if using letsencrypt you might pass an email per domain => see letsencrypt-certs
|
||||
key_usage: 'serverAuth' # serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning
|
||||
ocsp_staple: false
|
||||
crl_distribution: []
|
||||
# - full_name:
|
||||
# - "URI:https://ca.example.com/revocations.crl"
|
||||
# crl_issuer:
|
||||
# - "URI:https://ca.example.com/"
|
||||
# reasons:
|
||||
# - key_compromise
|
||||
# - ca_compromise
|
||||
# - cessation_of_operation
|
||||
valid_days: 730
|
||||
|
||||
mode_key: '0640'
|
||||
mode_cert: '0644'
|
||||
|
||||
owner_key: 'root'
|
||||
group_key: 'root'
|
||||
owner_cert: 'root'
|
||||
group_cert: 'root'
|
||||
|
||||
extension_cert: 'crt'
|
||||
extension_key: 'key'
|
||||
extension_csr: 'csr'
|
||||
|
||||
letsencrypt:
|
||||
path: '/etc/letsencrypt'
|
||||
service: # apache, nginx
|
||||
renew_timer: 'Mon *-*-* 01:00:00'
|
||||
verbosity: 'v'
|
||||
certs: {} # see 'default_le_certbot_cert_config'
|
||||
renew: false # if a renewal should be started by the role; the renewal service will auto-renew the certificates otherwise
|
||||
|
||||
ca:
|
||||
path: '/etc/certs/ca'
|
||||
valid_days: 7300
|
||||
key_size: 8192 # 1024, 2048, 4096, 8192
|
||||
key_type: 'RSA'
|
||||
cipher: 'AES-256-CBC' # see: 'openssl list -cipher-algorithms'
|
||||
digest: 'sha512'
|
||||
regenerate: 'partial_idempotence'
|
||||
pwd:
|
||||
|
||||
# certificate config
|
||||
cn: 'CA Certificate'
|
||||
org:
|
||||
ou:
|
||||
country:
|
||||
state:
|
||||
locality:
|
||||
email:
|
||||
|
||||
|
||||
CERT_CONFIG: "{{ default_certs | combine(certs, recursive=true) }}"
|
||||
|
||||
default_le_certbot_cert_config:
|
||||
domains: []
|
||||
state: 'present'
|
||||
email:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from re import sub as regex_replace
|
||||
from re import match as regex_match
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
|
|
@ -6,16 +7,35 @@ class FilterModule(object):
|
|||
def filters(self):
|
||||
return {
|
||||
"safe_key": self.safe_key,
|
||||
"fallback": self.fallback,
|
||||
"valid_domain": self.valid_domain,
|
||||
"valid_ip": self.valid_ip,
|
||||
"check_email": self.check_email,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def safe_key(key: str) -> str:
|
||||
return regex_replace('[^0-9a-zA-Z]+', '', key.replace(' ', '_'))
|
||||
return regex_replace(r'[^0-9a-zA-Z\.]+', '', key.replace(' ', '_'))
|
||||
|
||||
@staticmethod
|
||||
def fallback(opt1: str, opt2: str) -> str:
|
||||
if opt1 not in [None, '', 'None', 'none', ' ']:
|
||||
return opt1
|
||||
def valid_domain(domain: str) -> bool:
|
||||
expr = r'^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$'
|
||||
return True if regex_match(expr, domain) is not None else False
|
||||
|
||||
@staticmethod
|
||||
def valid_ip(ip: str) -> bool:
|
||||
expr_ipv4 = r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$'
|
||||
expr_ipv6 = r'^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$'
|
||||
|
||||
if regex_match(expr_ipv4, ip) is not None or regex_match(expr_ipv6, ip) is not None:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def check_email(certs: dict) -> bool:
|
||||
for settings in certs.values():
|
||||
if 'email' not in settings or settings['email'] in ['', ' ', None, 'null', 'None']:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
return opt2
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
|
||||
# ansible-playbook -K -D -i inventory/hosts.yml playbook.yml
|
||||
# ansible-playbook -K -D -i inventory/hosts.yml playbook.yml --ask-vault-pass
|
||||
|
||||
- hosts: all # should be limited
|
||||
- hosts: localhost # should be limited
|
||||
become: true
|
||||
gather_facts: yes
|
||||
roles:
|
||||
- ansibleguy.ROLE
|
||||
- ansibleguy.infra_certs
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
# install: ansible-galaxy install -r requirements.yml
|
||||
|
||||
collections: []
|
||||
# - name: 'community.general'
|
||||
# source: 'https://galaxy.ansible.com'
|
||||
- name: 'community.crypto'
|
||||
source: 'https://galaxy.ansible.com'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
|
||||
# creating ca with full pki
|
||||
# to be continued (;
|
||||
|
||||
- name: Certificates | Debian | Internal | CA | Not yet implemented
|
||||
ansible.builtin.debug:
|
||||
msg: "The certificate mode 'ca_full' is not yet implemented!"
|
||||
tags: ca
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Install package
|
||||
ansible.builtin.package:
|
||||
name: ['python3-certbot-apache']
|
||||
state: present
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Checking sites
|
||||
ansible.builtin.shell: 'ls /etc/apache2/sites-enabled/'
|
||||
changed_when: false
|
||||
register: enabled_apache_sites
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Deploying temporary apache site
|
||||
ansible.builtin.template:
|
||||
src: 'templates/etc/apache2/sites-enabled/le_dummy.conf.j2'
|
||||
dest: '/etc/apache2/sites-enabled/tmp_le_dummy.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0644
|
||||
register: tmp_site_enable
|
||||
when: enabled_apache_sites.stdout == ''
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Reloading apache
|
||||
ansible.builtin.systemd:
|
||||
name: 'apache2.service'
|
||||
state: reloaded
|
||||
when:
|
||||
- enabled_apache_sites.stdout == ''
|
||||
- tmp_site_enable.changed
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Disable temporary site
|
||||
ansible.builtin.file:
|
||||
state: absent
|
||||
path: '/etc/apache2/sites-enabled/tmp_le_dummy.conf'
|
||||
register: tmp_site_disable
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Apache | Reloading apache
|
||||
ansible.builtin.systemd:
|
||||
name: 'apache2.service'
|
||||
state: reloaded
|
||||
when: tmp_site_disable.changed
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
|
||||
- name: Apache | Debian | LetsEncrypt Certbot | Dependencies | Deploying temporary apache site
|
||||
ansible.builtin.template:
|
||||
src: 'templates/etc/apache2/sites-available/le_dummy.conf.j2'
|
||||
dest: '/etc/apache2/sites-available/tmp_le_dummy.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0644
|
||||
|
||||
- name: Apache | Debian | LetsEncrypt Certbot | Dependencies | Enable apache site
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: '/etc/apache2/sites-available/tmp_le_dummy.conf'
|
||||
dest: '/etc/apache2/sites-enabled/tmp_le_dummy.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0644
|
||||
|
||||
- name: Apache | Debian | LetsEncrypt Certbot | Dependencies | Reload apache
|
||||
ansible.builtin.systemd:
|
||||
name: 'apache2.service'
|
||||
state: reloaded
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
|
||||
# todo: check domains registered in current certificate (certbot certificates) and remove it if there are more than configured before re-configuring it
|
||||
|
||||
- name: "Certificates | Debian | LetsEncrypt Certbot | {{ le_name }} | Creating directory"
|
||||
ansible.builtin.file:
|
||||
path: "{{ le_path }}"
|
||||
state: directory
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0755
|
||||
|
||||
- name: "Certificates | Debian | LetsEncrypt Certbot | {{ le_name }} | Command to be executed"
|
||||
ansible.builtin.debug:
|
||||
msg: "certbot certonly --non-interactive --agree-tos --no-redirect
|
||||
--{{ CERT_CONFIG.letsencrypt.service }} --cert-name {{ le_name }}
|
||||
-{{ CERT_CONFIG.letsencrypt.verbosity }}
|
||||
--rsa-key-size {{ le_cert.key_size | default(CERT_CONFIG.cert.key_size, true) }}
|
||||
--config-dir {{ CERT_CONFIG.letsencrypt.path }}
|
||||
{% for domain in le_cert.domains %}{% if domain | valid_domain %}--domain {{ domain }} {% endif %}{% endfor %}
|
||||
{% if le_cert.email is not none %}--email {{ le_cert.email }} {% elif CERT_CONFIG.cert.email | default(none, true) is not none %}--email {{ CERT_CONFIG.cert.email }} {% endif %}"
|
||||
when: existing_certs_raw.stdout.find(name) == -1
|
||||
|
||||
- name: "Certificates | Debian | LetsEncrypt Certbot | {{ le_name }} | Starting certbot"
|
||||
ansible.builtin.command: "certbot certonly --non-interactive --agree-tos --no-redirect
|
||||
--{{ CERT_CONFIG.letsencrypt.service }} --cert-name {{ le_name }}
|
||||
-{{ CERT_CONFIG.letsencrypt.verbosity }}
|
||||
--rsa-key-size {{ le_cert.key_size | default(CERT_CONFIG.cert.key_size, true) }}
|
||||
--config-dir {{ CERT_CONFIG.letsencrypt.path }}
|
||||
{% for domain in le_cert.domains %}{% if domain | valid_domain %}--domain {{ domain }} {% endif %}{% endfor %}
|
||||
{% if le_cert.email is not none %}--email {{ le_cert.email }} {% elif CERT_CONFIG.cert.email | default(none, true) is not none %}--email {{ CERT_CONFIG.cert.email }} {% endif %}"
|
||||
when: existing_certs_raw.stdout.find(name) == -1
|
||||
|
||||
- name: "Certificates | Debian | LetsEncrypt Certbot | {{ le_name }} | Linking cert"
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dst }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
follow: true
|
||||
force: true
|
||||
loop:
|
||||
- {'dst': "{{ CERT_CONFIG.path }}/{{ le_name }}.{{ CERT_CONFIG.extension_cert }}", 'src': "{{ le_path }}/cert.pem"}
|
||||
- {'dst': "{{ CERT_CONFIG.path }}/{{ le_name }}.chain.{{ CERT_CONFIG.extension_cert }}", 'src': "{{ le_path }}/chain.pem"}
|
||||
- {'dst': "{{ CERT_CONFIG.path }}/{{ le_name }}.fullchain.{{ CERT_CONFIG.extension_cert }}", 'src': "{{ le_path }}/fullchain.pem"}
|
||||
|
||||
- name: "Certificates | Debian | LetsEncrypt Certbot | {{ le_name }} | Linking key"
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: "{{ le_path }}/privkey.pem"
|
||||
dest: "{{ CERT_CONFIG.path }}/{{ le_name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
mode: "{{ CERT_CONFIG.mode_key }}"
|
||||
owner: "{{ CERT_CONFIG.owner_key }}"
|
||||
group: "{{ CERT_CONFIG.group_key }}"
|
||||
follow: true
|
||||
force: true
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Checking config
|
||||
ansible.builtin.fail:
|
||||
msg: "The required configuration was not provided!
|
||||
Needed: 'certs.letsencrypt.certs', 'certs.letsencrypt.service',
|
||||
'certs.letsencrypt.email or certs.letsencrypt.email.certs.email'"
|
||||
when: >
|
||||
CERT_CONFIG.letsencrypt.certs | length == 0 or
|
||||
CERT_CONFIG.letsencrypt.service is none | default(none, true) or
|
||||
(CERT_CONFIG.letsencrypt.email | default(none, true) is none and not CERT_CONFIG.letsencrypt.certs|check_email)
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Checking service
|
||||
ansible.builtin.fail:
|
||||
msg: "You need to supply a supported LetsEncrypt Certbot service to use! (apache/nginx)"
|
||||
when: "CERT_CONFIG.letsencrypt.service | default(none, true) is none or CERT_CONFIG.letsencrypt.service not in ['apache', 'nginx']"
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Configure for Apache2
|
||||
ansible.builtin.import_tasks: apache.yml
|
||||
when: CERT_CONFIG.letsencrypt.service == 'apache'
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Configure for Nginx
|
||||
ansible.builtin.import_tasks: nginx.yml
|
||||
when: CERT_CONFIG.letsencrypt.service == 'nginx'
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Pulling existing certs
|
||||
ansible.builtin.shell: 'certbot certificates'
|
||||
register: existing_certs_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Adding certificates
|
||||
ansible.builtin.include_tasks: cert.yml
|
||||
when:
|
||||
- le_cert.domains | length > 0
|
||||
- le_cert.state == 'present'
|
||||
vars:
|
||||
le_cert: "{{ default_le_certbot_cert_config | combine(cert_item.value, recursive=true) }}"
|
||||
le_name: "{{ cert_item.key | safe_key }}"
|
||||
le_path: "{{ CERT_CONFIG.letsencrypt.path }}/live/{{ name }}"
|
||||
loop_control:
|
||||
loop_var: cert_item
|
||||
with_dict: "{{ CERT_CONFIG.letsencrypt.certs }}"
|
||||
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Removing certificates
|
||||
ansible.builtin.command: "certbot revoke --cert-name {{ le_name }} && certbot delete --cert-name {{ le_name }}"
|
||||
when:
|
||||
- le_cert.state != 'present'
|
||||
- existing_certs_raw.stdout.find(le_name) != -1
|
||||
vars:
|
||||
le_cert: "{{ default_le_certbot_cert_config | combine(cert_item.value, recursive=true) }}"
|
||||
le_name: "{{ cert_item.key | safe_key }}"
|
||||
loop_control:
|
||||
loop_var: cert_item
|
||||
with_dict: "{{ CERT_CONFIG.letsencrypt.certs }}"
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Cleanup for Apache2
|
||||
ansible.builtin.import_tasks: apache_cleanup.yml
|
||||
when: CERT_CONFIG.letsencrypt.service == 'apache'
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Cleanup for Nginx
|
||||
ansible.builtin.import_tasks: nginx_cleanup.yml
|
||||
when: CERT_CONFIG.letsencrypt.service == 'nginx'
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Adding service for certbot renewal
|
||||
ansible.builtin.template:
|
||||
src: "templates/etc/systemd/system/{{ item }}.j2"
|
||||
dest: "/etc/systemd/system/{{ item }}"
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0644
|
||||
with_items:
|
||||
- 'ansibleguy.infra_certs.LetsEncryptCertbot.service'
|
||||
- 'ansibleguy.infra_certs.LetsEncryptCertbot.timer'
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Enabling cert-renewal timer
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: yes
|
||||
name: 'ansibleguy.infra_certs.LetsEncryptCertbot.timer'
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Running renewal
|
||||
ansible.builtin.command: 'certbot renew --force-renewal'
|
||||
when: CERT_CONFIG.letsencrypt.renew
|
||||
ignore_errors: true
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Install package
|
||||
ansible.builtin.package:
|
||||
name: ['python3-certbot-nginx']
|
||||
state: present
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Checking sites
|
||||
ansible.builtin.shell: 'ls /etc/nginx/sites-enabled/'
|
||||
changed_when: false
|
||||
register: enabled_nginx_sites
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Deploying temporary apache site
|
||||
ansible.builtin.template:
|
||||
src: 'templates/etc/nginx/sites-enabled/le_dummy.j2'
|
||||
dest: '/etc/nginx/sites-enabled/tmp_le_dummy'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: 0644
|
||||
register: tmp_site_enable
|
||||
when: enabled_nginx_sites.stdout == ''
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Reloading apache
|
||||
ansible.builtin.systemd:
|
||||
name: 'nginx.service'
|
||||
state: reloaded
|
||||
when:
|
||||
- enabled_nginx_sites.stdout == ''
|
||||
- tmp_site_enable.changed
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Disable temporary site
|
||||
ansible.builtin.file:
|
||||
state: absent
|
||||
path: '/etc/nginx/sites-enabled/tmp_le_dummy'
|
||||
register: tmp_site_disable
|
||||
|
||||
- name: Certificates | Debian | LetsEncrypt Certbot | Nginx | Reloading apache
|
||||
ansible.builtin.systemd:
|
||||
name: 'nginx.service'
|
||||
state: reloaded
|
||||
when: tmp_site_disable.changed
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
|
||||
- name: ROLE | Debian | Task
|
||||
ansible.builtin.apt:
|
||||
pkg: "{{ something }}"
|
||||
tags: [base]
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
|
||||
# creating a minimal ca
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Creating ca directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ CERT_CONFIG.ca.path }}"
|
||||
state: directory
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generate ca private key (encrypted key)
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
passphrase: "{{ CERT_CONFIG.ca.pwd }}"
|
||||
cipher: "{{ CERT_CONFIG.ca.cipher }}"
|
||||
size: "{{ CERT_CONFIG.ca.key_size }}"
|
||||
type: "{{ CERT_CONFIG.ca.key_type }}"
|
||||
regenerate: "{{ CERT_CONFIG.ca.regenerate }}"
|
||||
mode: "{{ CERT_CONFIG.mode_key }}"
|
||||
owner: "{{ CERT_CONFIG.owner_key }}"
|
||||
group: "{{ CERT_CONFIG.group_key }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is not none
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generate ca private key (plain key)
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
size: "{{ CERT_CONFIG.ca.key_size }}"
|
||||
type: "{{ CERT_CONFIG.ca.key_type }}"
|
||||
regenerate: "{{ CERT_CONFIG.ca.regenerate }}"
|
||||
mode: "{{ CERT_CONFIG.mode_key }}"
|
||||
owner: "{{ CERT_CONFIG.owner_key }}"
|
||||
group: "{{ CERT_CONFIG.group_key }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is none
|
||||
|
||||
# NOTE: for details see https://www.openssl.org/docs/man1.0.2/man5/x509v3_config.html
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generating ca signing-request (encrypted key)
|
||||
community.crypto.openssl_csr:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_csr }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase: "{{ CERT_CONFIG.ca.pwd }}"
|
||||
basic_constraints: ['CA:TRUE', 'pathlen:2']
|
||||
basic_constraints_critical: true
|
||||
key_usage: ['cRLSign', 'digitalSignature', 'keyCertSign']
|
||||
key_usage_critical: true
|
||||
digest: "{{ CERT_CONFIG.ca.digest }}"
|
||||
common_name: "{{ CERT_CONFIG.ca.cn }}"
|
||||
organization_name: "{{ CERT_CONFIG.ca.org }}"
|
||||
country_name: "{{ CERT_CONFIG.ca.country }}"
|
||||
state_or_province_name: "{{ CERT_CONFIG.ca.state }}"
|
||||
locality_name: "{{ CERT_CONFIG.ca.locality }}"
|
||||
email_address: "{{ CERT_CONFIG.ca.email }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is not none
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generating ca signing-request (plain key)
|
||||
community.crypto.openssl_csr:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_csr }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
basic_constraints: ['CA:TRUE', 'pathlen:2']
|
||||
basic_constraints_critical: true
|
||||
key_usage: ['cRLSign', 'digitalSignature', 'keyCertSign']
|
||||
key_usage_critical: true
|
||||
digest: "{{ CERT_CONFIG.ca.digest }}"
|
||||
common_name: "{{ CERT_CONFIG.ca.cn }}"
|
||||
organization_name: "{{ CERT_CONFIG.ca.org }}"
|
||||
country_name: "{{ CERT_CONFIG.ca.country }}"
|
||||
state_or_province_name: "{{ CERT_CONFIG.ca.state }}"
|
||||
locality_name: "{{ CERT_CONFIG.ca.locality }}"
|
||||
email_address: "{{ CERT_CONFIG.ca.email }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is none
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generating ca certificate (encrypted key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
csr_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_csr }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase: "{{ CERT_CONFIG.ca.pwd }}"
|
||||
provider: selfsigned
|
||||
valid_in: "{{ CERT_CONFIG.ca.valid_days }}d"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is not none
|
||||
|
||||
- name: Certificates | Internal | Minimal CA | Generating ca certificate (plain key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
csr_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_csr }}"
|
||||
provider: selfsigned
|
||||
valid_in: "{{ CERT_CONFIG.ca.valid_days }}d"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.ca.pwd | default(none, true) is none
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Internal | Cert | Generate private key (encrypted)
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
cipher: "{{ CERT_CONFIG.cert.cipher }}"
|
||||
size: "{{ CERT_CONFIG.cert.key_size }}"
|
||||
type: "{{ CERT_CONFIG.cert.key_type }}"
|
||||
passphrase: "{{ CERT_CONFIG.cert.pwd }}"
|
||||
regenerate: "{{ CERT_CONFIG.cert.regenerate }}"
|
||||
mode: "{{ CERT_CONFIG.mode_key }}"
|
||||
owner: "{{ CERT_CONFIG.owner_key }}"
|
||||
group: "{{ CERT_CONFIG.group_key }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.cert.pwd | default(none, true) is not none
|
||||
|
||||
- name: Certificates | Internal | Cert | Generate private key (plain)
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
size: "{{ CERT_CONFIG.cert.key_size }}"
|
||||
type: "{{ CERT_CONFIG.cert.key_type }}"
|
||||
regenerate: "{{ CERT_CONFIG.cert.regenerate }}"
|
||||
mode: "{{ CERT_CONFIG.mode_key }}"
|
||||
owner: "{{ CERT_CONFIG.owner_key }}"
|
||||
group: "{{ CERT_CONFIG.group_key }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.cert.pwd | default(none, true) is none
|
||||
|
||||
- name: Certificates | Internal | Cert | Setting SAN
|
||||
ansible.builtin.set_fact:
|
||||
cert_san: "{% for domain in CERT_CONFIG.cert.domains %}
|
||||
{% if domain | valid_domain %}DNS:{{ domain }}{% if not loop.last %},{% endif %}{% endif %}
|
||||
{% endfor %}
|
||||
{% for ip in CERT_CONFIG.cert.ips %}
|
||||
{% if ip | valid_ip %},IP:{{ ip }}{% endif %}
|
||||
{% endfor %}"
|
||||
|
||||
- name: Certificates | Internal | Cert | Generating signing-request (encrypted key)
|
||||
community.crypto.openssl_csr:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase : "{{ CERT_CONFIG.cert.pwd }}"
|
||||
digest: "{{ CERT_CONFIG.cert.digest }}"
|
||||
common_name: "{{ CERT_CONFIG.cert.cn }}"
|
||||
organization_name: "{{ CERT_CONFIG.cert.org }}"
|
||||
country_name: "{{ CERT_CONFIG.cert.country }}"
|
||||
state_or_province_name: "{{ CERT_CONFIG.cert.state }}"
|
||||
locality_name: "{{ CERT_CONFIG.cert.locality }}"
|
||||
email_address: "{{ CERT_CONFIG.cert.email }}"
|
||||
extended_key_usage: "{{ CERT_CONFIG.cert.key_usage }}"
|
||||
ocsp_must_staple: "{{ CERT_CONFIG.cert.ocsp_staple }}"
|
||||
crl_distribution_points: "{{ CERT_CONFIG.cert.crl_distribution }}"
|
||||
subject_alt_name: "{{ cert_san | replace(' ', '') | default('DNS:localhost', true) }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.cert.pwd | default(none, true) is not none
|
||||
|
||||
- name: Certificates | Internal | Cert | Generating signing-request (plain key)
|
||||
community.crypto.openssl_csr:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
digest: "{{ CERT_CONFIG.cert.digest }}"
|
||||
common_name: "{{ CERT_CONFIG.cert.cn }}"
|
||||
organization_name: "{{ CERT_CONFIG.cert.org }}"
|
||||
country_name: "{{ CERT_CONFIG.cert.country }}"
|
||||
state_or_province_name: "{{ CERT_CONFIG.cert.state }}"
|
||||
locality_name: "{{ CERT_CONFIG.cert.locality }}"
|
||||
email_address: "{{ CERT_CONFIG.cert.email }}"
|
||||
extended_key_usage: "{{ CERT_CONFIG.cert.key_usage }}"
|
||||
ocsp_must_staple: "{{ CERT_CONFIG.cert.ocsp_staple }}"
|
||||
crl_distribution_points: "{{ CERT_CONFIG.cert.crl_distribution }}"
|
||||
subject_alt_name: "{{ cert_san | replace(' ', '') | default('DNS:localhost', true) }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when: CERT_CONFIG.cert.pwd | default(none, true) is none
|
||||
|
||||
- name: Certificates | Internal | Cert | Self-Signed | Generating certificate (encrypted key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase: "{{ CERT_CONFIG.cert.pwd }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
provider: selfsigned
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is not none
|
||||
- CERT_CONFIG.mode == 'selfsigned'
|
||||
|
||||
- name: Certificates | Internal | Cert | Self-Signed | Generating certificate (plain key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
provider: selfsigned
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is none
|
||||
- CERT_CONFIG.mode == 'selfsigned'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Generating certificate (encrypted key; encrypted ca-key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase: "{{ CERT_CONFIG.cert.pwd }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
provider: ownca
|
||||
ownca_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
ownca_privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
ownca_privatekey_passphrase: "{{ CERT_CONFIG.ca.pwd }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.ca.pwd | default(none, true) is not none
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is not none
|
||||
- CERT_CONFIG.mode == 'ca'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Generating certificate (plain key; encrypted ca-key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
provider: ownca
|
||||
ownca_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
ownca_privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
ownca_privatekey_passphrase: "{{ CERT_CONFIG.ca.pwd }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.ca.pwd | default(none, true) is not none
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is none
|
||||
- CERT_CONFIG.mode == 'ca'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Generating certificate (encrypted key; plain ca-key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
privatekey_passphrase: "{{ CERT_CONFIG.cert.pwd }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
provider: ownca
|
||||
ownca_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
ownca_privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.ca.pwd | default(none, true) is none
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is not none
|
||||
- CERT_CONFIG.mode == 'ca'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Generating certificate (plain key; plain ca-key)
|
||||
community.crypto.x509_certificate:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}"
|
||||
privatekey_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_key }}"
|
||||
csr_path: "{{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_csr }}"
|
||||
valid_in: "{{ CERT_CONFIG.cert.valid_days }}d"
|
||||
provider: ownca
|
||||
ownca_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }}"
|
||||
ownca_privatekey_path: "{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_key }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
no_log: true
|
||||
when:
|
||||
- CERT_CONFIG.ca.pwd | default(none, true) is none
|
||||
- CERT_CONFIG.cert.pwd | default(none, true) is none
|
||||
- CERT_CONFIG.mode == 'ca'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Creating chained certificate
|
||||
ansible.builtin.shell: "cat {{ CERT_CONFIG.path }}/{{ name }}.{{ CERT_CONFIG.extension_cert }}
|
||||
{{ CERT_CONFIG.ca.path }}/ca.{{ CERT_CONFIG.extension_cert }} >
|
||||
{{ CERT_CONFIG.path }}/{{ name }}.chain.{{ CERT_CONFIG.extension_cert }}"
|
||||
args:
|
||||
creates: "{{ CERT_CONFIG.path }}/{{ name }}.chain.{{ CERT_CONFIG.extension_cert }}"
|
||||
when: CERT_CONFIG.mode == 'ca'
|
||||
|
||||
- name: Certificates | Internal | Cert | CA-Signed | Setting privileges on chained certificate
|
||||
ansible.builtin.file:
|
||||
path: "{{ CERT_CONFIG.path }}/{{ name }}.chain.{{ CERT_CONFIG.extension_cert }}"
|
||||
mode: "{{ CERT_CONFIG.mode_cert }}"
|
||||
owner: "{{ CERT_CONFIG.owner_cert }}"
|
||||
group: "{{ CERT_CONFIG.group_cert }}"
|
||||
when: CERT_CONFIG.mode == 'ca'
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
|
||||
- name: Certificates | Internal | Installing dependencies
|
||||
ansible.builtin.package:
|
||||
pkg: ['python3-cryptography']
|
||||
tags: [certs, ca]
|
||||
|
||||
- name: Certificates | Internal | Creating cert directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ CERT_CONFIG.path }}"
|
||||
state: directory
|
||||
tags: [certs, ca]
|
||||
|
||||
- name: Certificates | Internal | Minimal CA
|
||||
ansible.builtin.import_tasks: ca_minimal.yml
|
||||
when: CERT_CONFIG.mode == 'ca'
|
||||
tags: [ca]
|
||||
|
||||
- name: Certificates | Internal | Cert
|
||||
ansible.builtin.import_tasks: cert.yml
|
||||
when: "CERT_CONFIG.mode in ['ca', 'selfsigned']"
|
||||
tags: [certs]
|
||||
|
|
@ -1,5 +1,25 @@
|
|||
---
|
||||
|
||||
- name: ROLE | Processing debian config
|
||||
ansible.builtin.import_tasks: debian/main.yml
|
||||
when: "ansible_distribution|lower in ['debian', 'ubuntu']"
|
||||
- name: Certificates | Checking config
|
||||
ansible.builtin.fail:
|
||||
msg: "The required configuration was not provided!
|
||||
Needed: 'certs'"
|
||||
when: certs is undefined
|
||||
|
||||
- name: Certificates | Setting name
|
||||
ansible.builtin.set_fact:
|
||||
name: "{% if CERT_CONFIG.cert.name is not none %}{{ CERT_CONFIG.cert.name | safe_key }}{% else %}{{ CERT_CONFIG.cert.cn | safe_key }}{% endif %}"
|
||||
|
||||
- name: Certificates | Internal signed
|
||||
ansible.builtin.include_tasks: internal/main.yml
|
||||
when: "CERT_CONFIG.mode in ['ca_full', 'ca', 'selfsigned']"
|
||||
|
||||
- name: Certificates | Internal | CA
|
||||
ansible.builtin.include_tasks: debian/ca_full.yml
|
||||
when: CERT_CONFIG.mode == 'ca_full'
|
||||
|
||||
- name: Certificates | Debian | Letsencrypt
|
||||
ansible.builtin.include_tasks: debian/letsencrypt/main.yml
|
||||
when:
|
||||
- CERT_CONFIG.mode == 'le_certbot'
|
||||
- "ansible_distribution|lower in ['debian', 'ubuntu']"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# {{ ansible_managed }}
|
||||
# ansibleguy.infra_certs - dummy site used for letsencrypt certbot
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName dummy.letsencrypt.localhost
|
||||
ServerAdmin webmaster@localhost
|
||||
ErrorLog {{ APACHE_CONFIG.log.path }}/error.log
|
||||
CustomLog {{ APACHE_CONFIG.log.path }}/access.log combined
|
||||
</VirtualHost>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# {{ ansible_managed }}
|
||||
# ansibleguy.infra_certs - dummy site used for letsencrypt certbot
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name dummy.letsencrypt.localhost;
|
||||
error_log {{ NGINX_CONFIG.log.path }}/error.log;
|
||||
access_log {{ NGINX_CONFIG.log.path }}/access.log;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# {{ ansible_managed }}
|
||||
# ansibleguy.infra_certs
|
||||
|
||||
[Unit]
|
||||
Description=Service to renew LetsEncrypt Certificates using certbot
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=certbot renew -{{ CERT_CONFIG.letsencrypt.verbosity }} --non-interactive --agree-tos --renew-with-new-domains
|
||||
SuccessExitStatus=0
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# {{ ansible_managed }}
|
||||
# ansibleguy.infra_certs
|
||||
|
||||
[Unit]
|
||||
Description=Timer to renew LetsEncrypt Certificates using certbot
|
||||
|
||||
[Timer]
|
||||
OnCalendar={{ CERT_CONFIG.letsencrypt.renew_timer }}
|
||||
Persistent=false
|
||||
WakeSystem=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Loading…
Reference in New Issue