Commit 2f5cea2e authored by HgO's avatar HgO
Browse files

create letsencrypt role

parent 57cd031e
letsencrypt_dns_gandi_api_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
37623065386338343831383566336134303861396663666631656563633730613434633231343336
3132646565373162613537646538353933363161363036650a343634633932373362336134636139
34313539353938393164353034653366303664613332333038663266656466323265303130333035
3430613234383662640a313864386230646137383637343263356236633434356335383335353935
64623839396433346235383264613534383130386433363931306662663063306665
letsencrypt_dns_gandi_sharing_id: !vault |
$ANSIBLE_VAULT;1.1;AES256
38396332333438316166356332636166623231653165396138373938613734663766366231396564
6238353638383965393837356339353864323333376532610a643738376136626335653835323638
66363537646637373130376630326365336433393161303861383163383766656166396566366530
3139626262313437640a623462346133303264393234366665663838663931653062616130643639
31303535323864323031353032346664643562626563633864366237373935386438353138643337
6632383964373738663761343065306137313163303838633763
letsencrypt_staging: true
letsencrypt_hook_scripts:
- haproxy.py
letsencrypt_domains:
- name: neutrinet.be
hooks:
deploy:
- /etc/letsencrypt/hooks.d/haproxy.py
post:
- systemctl reload haproxy
#!/usr/bin/env python3
import os
import pwd
import grp
import re
import sys
def chown(path: str, owner: str, group: str, **kwargs) -> None:
"""Change ownership of a file or directory given an username and a group name."""
uid = pwd.getpwnam(owner).pw_uid
gid = grp.getgrnam(group).gr_gid
os.chown(path, uid, gid, **kwargs)
# Certbot sets an environment variable RENEWED_LINEAGE, which points to the
# path of the renewed certificate. We use that path to determine and find
# the files for the currently renewed certificated
lineage=os.environ.get('RENEWED_LINEAGE')
# If nothing renewed, exit
if not lineage:
sys.exit()
# From the linage, we strip the 'domain name', which is the last part
# of the path.
result = re.match(r'.*/live/(.+)$', lineage)
# If we can not recognize the path, we exit with 1
if not result:
sys.exit(1)
# Extract the domain name
domain = result.group(1)
# Define a path for HAproxy where you want to write the .pem file.
deploy_path="/etc/haproxy/ssl/" + domain.replace('.', '-') + ".pem"
# The source files can be found in below paths, constructed with the lineage
# path
source_key = lineage + "/privkey.pem"
source_chain = lineage + "/fullchain.pem"
# HAproxy requires to combine the key and chain in one .pem file
# Open a file descriptor to handle permissions. See https://stackoverflow.com/a/45368120
deploy_fd = os.open(deploy_path, os.O_CREAT | os.O_WRONLY, 0o640)
with os.fdopen(deploy_fd, "w") as deploy, \
open(source_key, "r") as key, \
open(source_chain, "r") as chain:
deploy.write(key.read())
deploy.write(chain.read())
chown(deploy_path, "haproxy", "haproxy")
# Here you can add your service reload command. Which will be executed after
# every renewal, which is fine if you only have a few domains.
# Alternative is to add the reload to the --post-hook. In that case it is only
# run once after all renewals. That would be the use-case if you have a large
# number of different certificates served by HAproxy.
*********************************
Vagrant driver installation guide
*********************************
Requirements
============
* Vagrant
* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ pip install 'molecule_vagrant'
---
- name: Converge
hosts: all
become: true
roles:
- letsencrypt
dependency:
name: galaxy
driver:
name: vagrant
provider:
name: virtualbox
platforms:
- name: buster-letsencrypt-molecule
box: debian/buster64
cpu: 2
memory: 512
interfaces:
- network_name: private_network
type: dhcp
auto_config: true
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: /usr/bin/python3
vault_password_file: "${MOLECULE_PROJECT_DIRECTORY}/../../vault.key"
ssh_connection:
pipelining: true
verifier:
name: ansible
---
- name: Prepare
hosts: all
become: true
pre_tasks:
- name: Mise à jour du cache APT
apt:
update_cache: true
cache_valid_time: 3600
---
- name: Définition du nom du certificat {{ algorithm | upper }} {{ domain.name }}
set_fact:
cert_name: "{{ domain.name | replace('.', '-') }}-{{ algorithm }}"
- name: Test si le certificat {{ algorithm | upper }} {{ domain.name }} existe
stat:
path: /etc/letsencrypt/live/{{ cert_name }}/cert.pem
register: letsencrypt_domain
- name: Création du certificat {{ algorithm | upper }} {{ domain.name }}
command: >
/opt/letsencrypt/bin/certbot certonly
--non-interactive
{% if letsencrypt_staging %}
--staging
{% endif %}
--authenticator dns-gandi
--dns-gandi-credentials /etc/letsencrypt/gandi/gandi.ini
--key-type {{ algorithm }}
{% if algorithm == 'rsa' %}
--rsa-key-size 4096
{% endif %}
--cert-name {{ cert_name }}
--domain {{ domain.name }}
--domain *\.{{ domain.name }}
{% for hook in domain.hooks.deploy | default([]) %}
--deploy-hook {{ hook | quote }}
{% endfor %}
{% for hook in domain.hooks.post | default([]) %}
--post-hook {{ hook | quote }}
{% endfor %}
when: not letsencrypt_domain.stat.exists
- include_tasks: create.yml
loop:
- rsa
- ecdsa
loop_control:
loop_var: algorithm
---
- name: Installation des dépendances python
ansible.builtin.package:
name:
- python3-dev
- python3-virtualenv
- virtualenv
state: present
- name: Création des dossiers Let's Encrypt
file:
path: "{{ item }}"
owner: root
group: root
mode: "u=rw,go=r"
state: directory
with_items:
- /etc/letsencrypt
- /etc/letsencrypt/gandi
- /etc/letsencrypt/hooks.d
- /opt/letsencrypt
- name: Installation de pip et certbot # noqa package-latest
ansible.builtin.pip:
name:
- pip
- certbot
- certbot-plugin-gandi
virtualenv: /opt/letsencrypt
virtualenv_python: python3
state: latest
chdir: /opt/letsencrypt
- name: Création d'un cron job pour renouveler les certificats
cron:
name: "letsencrypt-update"
cron_file: letsencrypt-update
special_time: daily
user: "root"
job: "/opt/letsencrypt/bin/certbot renew"
- name: Test si le compte Let's Encrypt existe
stat:
path: /etc/letsencrypt/accounts
register: letsencrypt_accounts
- name: Enregistrement du compte Let's Encrypt
command: >
/opt/letsencrypt/bin/certbot register
--non-interactive
{% if letsencrypt_staging %}
--staging
--register-unsafely-without-email
{% else %}
--email {{ mail_notification }}
{% endif %}
--no-eff-email
--agree-tos
when: not letsencrypt_accounts.stat.exists
- name: Installation des hooks
copy:
src: "{{ hook_script }}"
dest: /etc/letsencrypt/hooks.d/{{ hook_script }}
mode: "u=rwx,go=rx"
owner: root
group: root
loop: "{{ letsencrypt_hook_scripts }}"
loop_control:
loop_var: hook_script
- name: Config de Gandi pour Let's Encrypt
template:
src: gandi.ini.j2
dest: /etc/letsencrypt/gandi/gandi.ini
owner: root
group: root
mode: "u=rw,go="
- name: Création des certificats challenge gandi
include_tasks: gandi/main.yml
loop: "{{ letsencrypt_domains }}"
loop_control:
loop_var: domain
label: "{{ domain.name }}"
{{ ansible_managed | comment }}
# live dns v5 api key
dns_gandi_api_key={{ letsencrypt_dns_gandi_api_key }}
# optional organization id, remove it if not used
dns_gandi_sharing_id={{ letsencrypt_dns_gandi_sharing_id }}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment