Compare commits
64 Commits
527e776d62
...
main
Author | SHA1 | Date | |
---|---|---|---|
da79c9264a
|
|||
34c7601cf7
|
|||
fb1b19bcfd
|
|||
37ccc19e04
|
|||
41c9135dfe
|
|||
d320cc0a44
|
|||
0d560218e2
|
|||
f56276b15b
|
|||
cf37b94440
|
|||
9169d8e6c6
|
|||
9eb88e6417
|
|||
7cfd15a08f
|
|||
414950f4b5
|
|||
7f4f846408
|
|||
de76ae0085
|
|||
a686970b0f
|
|||
4fe3babc83
|
|||
a1683dbf19
|
|||
88ac609897
|
|||
2a5f6621b6
|
|||
f7de61b6e2
|
|||
f57b1f1b3e
|
|||
f1ac6f269b
|
|||
50cb4cfc75
|
|||
aef3070586
|
|||
89bbc6c070
|
|||
361125e4a5
|
|||
b592afcd38
|
|||
145dccac2d
|
|||
8c4684a450
|
|||
f9491c6553
|
|||
c0a466db6a
|
|||
3fedc63db3
|
|||
0a85cd22ff
|
|||
a8c4bf141b
|
|||
2232e7c213
|
|||
6a3010816a
|
|||
e8661bbddb
|
|||
571f694ed1
|
|||
1115f7d0a8
|
|||
7f39ea724a
|
|||
475fe06fb7
|
|||
1d1b31c461
|
|||
8d649970ee
|
|||
3ab93fd509
|
|||
680b09ca2c
|
|||
4814d7d6ae
|
|||
7388125008
|
|||
564db32244
|
|||
bfbb228d12
|
|||
f84085a142
|
|||
7d5c4c9d2d
|
|||
a3ffc713c1
|
|||
2afba2cda4
|
|||
faa42d0789
|
|||
b742395cd4
|
|||
57b83cb58e
|
|||
b0d8cdaf72
|
|||
7d401e9f00
|
|||
9b0be73500
|
|||
be6bc01114
|
|||
988f701433
|
|||
7203cc43ee
|
|||
7af58a6dc7
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -0,0 +1,2 @@
|
||||
__pycache__
|
||||
debug.yml
|
||||
|
41
ansible.cfg
41
ansible.cfg
@ -1,41 +1,20 @@
|
||||
# Ansible configuration
|
||||
|
||||
[defaults]
|
||||
# Explicitely redefined some defaults to make play execution work
|
||||
roles_path = ./roles
|
||||
lookup_plugins = ./lookup_plugins
|
||||
vars_plugins = ./vars_plugins
|
||||
|
||||
# Use true Python version
|
||||
interpreter_python = /usr/bin/python3
|
||||
|
||||
# Do not create .retry files
|
||||
retry_files_enabled = False
|
||||
|
||||
# Use inventory
|
||||
inventory = ./hosts
|
||||
|
||||
# Custom header in templates
|
||||
ansible_managed = Ansible managed, modified on %Y-%m-%d %H:%M:%S by {uid}
|
||||
|
||||
# Do not use cows (with cowsay)
|
||||
nocows = 1
|
||||
|
||||
# Do more parallelism
|
||||
forks = 15
|
||||
|
||||
# Some SSH connection will take time
|
||||
timeout = 60
|
||||
|
||||
[privilege_escalation]
|
||||
|
||||
# Use sudo to get priviledge access
|
||||
become = True
|
||||
|
||||
# Ask for password
|
||||
become_ask_pass = True
|
||||
|
||||
[diff]
|
||||
|
||||
# TO know what changed
|
||||
always = yes
|
||||
|
||||
# Use a separate module to read passwords from pass
|
||||
become_ask_pass = False
|
||||
|
||||
[ssh_connection]
|
||||
pipelining = True
|
||||
retries = 3
|
||||
|
||||
[diff]
|
||||
always = yes
|
||||
|
7
base.yml
7
base.yml
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
# Put a common configuration on all servers
|
||||
- hosts: all
|
||||
roles:
|
||||
- baseconfig
|
||||
- docker
|
45
group_vars/all/all.yml
Normal file
45
group_vars/all/all.yml
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
# Custom header
|
||||
dirty: "{% if template_fullpath is defined %}{{ lookup('pipe', 'git diff --quiet -- ' + template_fullpath | quote + ' || echo dirty') }}{% else %}{{ lookup('pipe', 'git diff --quiet || echo dirty') }}{% endif %}"
|
||||
ansible_header: |
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Ansible managed, don't modify the file locally.
|
||||
See https://git.ynerant.fr/ynerant/templier-ansible.
|
||||
{% if template_fullpath is defined %}{% set _, rpath = template_fullpath.split('roles/', 1) %}Commit: {% if dirty %}({{dirty}}) {% endif %}{{ lookup('pipe', 'git log -n 1 --pretty=format:%H -- ' + template_fullpath | quote) }}
|
||||
{% if dirty %}Run by: {{ ansible_env.SUDO_USER }}
|
||||
{% else %}Author: {{ lookup('pipe', 'git log -n 1 --pretty=format:%an -- ' + template_fullpath | quote) }}
|
||||
{% endif %}Template: roles/{{ rpath }}
|
||||
{% else %}
|
||||
Run by: {{ ansible_env.SUDO_USER }}
|
||||
Latest commit: {% if dirty %}({{dirty}}) {% endif %}{{ lookup('pipe', 'git rev-parse HEAD') }}
|
||||
{% endif %}
|
||||
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
glob_ldap:
|
||||
servers:
|
||||
- 172.16.42.1
|
||||
base: 'dc=ynerant,dc=fr'
|
||||
|
||||
|
||||
bind:
|
||||
domains:
|
||||
- name: ynerant.fr
|
||||
administrator: ynerant.crans.org
|
||||
ipv4: 185.230.78.178
|
||||
ipv6: 2a0c:700:12:0:f21f:afff:fee5:34ca
|
||||
slave: "" # 51.15.199.212
|
||||
aliases:
|
||||
- cloud
|
||||
- element
|
||||
- git
|
||||
- hydrogen
|
||||
- mailu
|
||||
- notls
|
||||
- synapse
|
||||
- thelounge
|
||||
- traefik
|
||||
- translate
|
||||
- whoami
|
||||
- www
|
4
group_vars/all/home.yml
Normal file
4
group_vars/all/home.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
glob_home:
|
||||
ip: 172.16.42.1
|
||||
mountpoint: /vm/home
|
20
group_vars/all/network_interfaces.yml
Normal file
20
group_vars/all/network_interfaces.yml
Normal file
@ -0,0 +1,20 @@
|
||||
glob_network_interfaces:
|
||||
vlan:
|
||||
- name: adh
|
||||
id: 12
|
||||
gateway: "185.230.78.99"
|
||||
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'adh') | ipv4 | first }}"
|
||||
gateway_v6: "2a0c:700:12::ff:fe00:9912"
|
||||
- name: adm
|
||||
id: 42
|
||||
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'adm') | ipv4 | first }}"
|
||||
- name: srv_nat
|
||||
id: 43
|
||||
gateway: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv4 | first }}"
|
||||
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv4 | first }}"
|
||||
gateway_v6: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv6 | first }}"
|
||||
|
||||
|
||||
# Deploy only adm by default
|
||||
interfaces:
|
||||
adm: eth0
|
3
group_vars/all/ntp.yml
Normal file
3
group_vars/all/ntp.yml
Normal file
@ -0,0 +1,3 @@
|
||||
glob_ntp_client:
|
||||
servers:
|
||||
- ntp.adm.ynerant.fr
|
6
group_vars/all/nullmailer.yml
Normal file
6
group_vars/all/nullmailer.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
glob_nullmailer:
|
||||
root: root@ynerant.fr
|
||||
smtp_server: smtp.adm.ynerant.fr
|
||||
defaulthost: ynerant.fr
|
||||
allmailfrom: root@ynerant.fr
|
3
group_vars/all/prometheus_node_exporter.yaml
Normal file
3
group_vars/all/prometheus_node_exporter.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
glob_prometheus_node_exporter:
|
||||
listen_addr: "{{ query('ldap', 'ip', ansible_hostname, 'adm') | ipv4 | first }}"
|
8
group_vars/certbot.yml
Normal file
8
group_vars/certbot.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
glob_certbot:
|
||||
- dns_rfc2136_server: '172.16.42.103'
|
||||
dns_rfc2136_name: certbot_challenge.
|
||||
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
|
||||
mail: ynerant@crans.org
|
||||
certname: ynerant.fr
|
||||
domains: "*.ynerant.fr"
|
10
group_vars/debian.yml
Normal file
10
group_vars/debian.yml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
glob_apt:
|
||||
mirror: "http://mirror.adm.ynerant.fr/"
|
||||
backports: false
|
||||
monitoring_mail: "ynerant+apt@emy.lu"
|
||||
extra_repositories: []
|
||||
pin: {}
|
||||
|
||||
glob_root:
|
||||
passwd_hash: '{{ vault.root_passwd_hash }}'
|
7
group_vars/grafana.yml
Normal file
7
group_vars/grafana.yml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
glob_grafana:
|
||||
root_url: https://grafana.ynerant.fr
|
||||
icon: crans_icon_white.svg
|
||||
ldap_base: "{{ glob_ldap.base }}"
|
||||
ldap_master_ipv4: "{{ glob_ldap.servers[0] }}"
|
||||
ldap_user_tree: "ou=passwd,{{ glob_ldap.base }}"
|
35
group_vars/nginx.yml
Normal file
35
group_vars/nginx.yml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
glob_nginx:
|
||||
contact: ynerant@crans.org
|
||||
who: "Ÿnérant"
|
||||
service_name: service
|
||||
ssl:
|
||||
# Add adm.ynerant.fr if necessary
|
||||
- name: ynerant.fr
|
||||
cert: /etc/letsencrypt/live/ynerant.fr/fullchain.pem
|
||||
cert_key: /etc/letsencrypt/live/ynerant.fr/privkey.pem
|
||||
trusted_cert: /etc/letsencrypt/live/ynerant.fr/chain.pem
|
||||
servers:
|
||||
- ssl: false # Replace by crans.org or adm.crans.org
|
||||
default: true
|
||||
server_name:
|
||||
- "default"
|
||||
- "_"
|
||||
root: "/var/www/html"
|
||||
locations:
|
||||
- filter: "/"
|
||||
params: []
|
||||
additional_params: []
|
||||
upstreams: []
|
||||
|
||||
auth_passwd: []
|
||||
default_server:
|
||||
default_ssl_server:
|
||||
default_ssl_domain: ynerant.fr
|
||||
real_ip_from:
|
||||
- "172.16.0.0/16"
|
||||
- "fd00:0:0:42::/64"
|
||||
deploy_robots_file: false
|
||||
|
||||
glob_prometheus_nginx_exporter:
|
||||
listen_addr: "{{ query('ldap', 'ip', ansible_hostname, 'adm') | ipv4 | first }}"
|
9
group_vars/prometheus.yml
Normal file
9
group_vars/prometheus.yml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
glob_prometheus: {}
|
||||
|
||||
glob_ninjabot:
|
||||
config:
|
||||
nick: templier
|
||||
server: irc.crans.org
|
||||
port: 6667
|
||||
channel: "#/dev/null"
|
46
group_vars/reverseproxy.yml
Normal file
46
group_vars/reverseproxy.yml
Normal file
@ -0,0 +1,46 @@
|
||||
loc_certbot:
|
||||
- dns_rfc2136_server: '172.16.42.103'
|
||||
dns_rfc2136_name: certbot_challenge.
|
||||
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
|
||||
mail: ynerant@crans.org
|
||||
certname: ynerant.fr
|
||||
domains: "ynerant.fr, *.ynerant.fr, ens.kitchen, *.ens.kitchen, ananas.paris, *.ananas.paris, saperlistpopette.fr, *.saperlistpopette.fr"
|
||||
|
||||
loc_nginx:
|
||||
servers: []
|
||||
ssl:
|
||||
- name: ynerant.fr
|
||||
cert: /etc/letsencrypt/live/ynerant.fr/fullchain.pem
|
||||
cert_key: /etc/letsencrypt/live/ynerant.fr/privkey.pem
|
||||
trusted_cert: /etc/letsencrypt/live/ynerant.fr/chain.pem
|
||||
|
||||
|
||||
glob_reverseproxy:
|
||||
redirect_dnames: []
|
||||
|
||||
reverseproxy_sites:
|
||||
- {from: mailu.ynerant.fr, to: 172.16.42.104}
|
||||
# - {from: mirror.adm.ynerant.fr, to: "https://ftps.crans.org"}
|
||||
|
||||
- {from: element.ynerant.fr, to: "172.16.42.199:8002"}
|
||||
- {from: hydrogen.ynerant.fr, to: "172.16.42.199:8003"}
|
||||
- {from: git.ynerant.fr, to: "172.16.42.199:8007"}
|
||||
- {from: cloud.ynerant.fr, to: "172.16.42.199:8007"}
|
||||
# - {from: notls.adh.crans.org, to: "172.16.42.199:8011"}
|
||||
- {from: thelounge.ynerant.fr, to: "172.16.42.199:8012"}
|
||||
- {from: bibliogram.ynerant.fr, to: "172.16.42.199:8014"}
|
||||
- {from: reddit.ynerant.fr, to: "172.16.42.199:8015"}
|
||||
- {from: teddit.ynerant.fr, to: "172.16.42.199:8015"}
|
||||
- {from: whoami.ynerant.fr, to: "172.16.42.199:8016"}
|
||||
|
||||
- {from: saperlistpopette.fr, to: "172.16.42.199:8010"}
|
||||
- {from: kfet.saperlistpopette.fr, to: "172.16.42.199:8010"}
|
||||
|
||||
- {from: ens.kitchen, to: "https://perso.crans.org/club-kitchens/"}
|
||||
|
||||
redirect_sites: []
|
||||
# - {from: machin.ynerant.fr, to: truc.ynerant.fr}
|
||||
|
||||
static_sites:
|
||||
- ynerant.fr
|
||||
- thelounge.ynerant.fr
|
10
group_vars/slapd.yml
Normal file
10
group_vars/slapd.yml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
glob_slapd:
|
||||
master_ip: "172.16.42.1"
|
||||
ip: "172.16.42.1"
|
||||
replica: false
|
||||
# master_ip: "{{ query('ldap', 'ip', 'templier', 'adm') | ipv6 | first }}"
|
||||
regex: "^(role:(dhcp|dns|dns-primary|dns-secondary|ftp|gitlab|miroir|ntp|pve|radius|backup)|ecdsa-sha2-nistp256:.*|ssh-(ed25519|dss|rsa):.*)$"
|
||||
replication_credentials: "{{ vault.ldap_replication_credentials }}"
|
||||
private_key: "{{ vault.ldap_private_key }}"
|
||||
certificate: "{{ vault.ldap_certificate }}"
|
8
group_vars/virtu.yml
Normal file
8
group_vars/virtu.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
service_apt:
|
||||
extra_repositories:
|
||||
- name: pve-entreprise
|
||||
repositories:
|
||||
- url: "{{ glob_apt.mirror }}proxmox/debian/pve"
|
||||
version: "{{ ansible_distribution_release }}"
|
||||
tags: "pve-no-subscription"
|
4
host_vars/belenios.adm.ynerant.fr.yml
Normal file
4
host_vars/belenios.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
3
host_vars/borg.adm.ynerant.fr.yml
Normal file
3
host_vars/borg.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
4
host_vars/dendrite.adm.ynerant.fr.yml
Normal file
4
host_vars/dendrite.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/dns.adm.ynerant.fr.yml
Normal file
4
host_vars/dns.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
4
host_vars/docker.adm.ynerant.fr.yml
Normal file
4
host_vars/docker.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
4
host_vars/fosscord.adm.ynerant.fr.yml
Normal file
4
host_vars/fosscord.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
7
host_vars/galene.adm.ynerant.fr.yml
Normal file
7
host_vars/galene.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
||||
|
||||
loc_apt:
|
||||
backports: true
|
4
host_vars/gitea.adm.ynerant.fr.yml
Normal file
4
host_vars/gitea.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
4
host_vars/mailu.adm.ynerant.fr.yml
Normal file
4
host_vars/mailu.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
4
host_vars/mastodon.adm.ynerant.fr.yml
Normal file
4
host_vars/mastodon.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/minecraft.adm.ynerant.fr.yml
Normal file
4
host_vars/minecraft.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
70
host_vars/monitoring.adm.ynerant.fr.yml
Normal file
70
host_vars/monitoring.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
||||
|
||||
loc_prometheus:
|
||||
node:
|
||||
file: targets_node.json
|
||||
targets: "{{ groups['server'] | select('match', '^.*\\.adm\\.ynerant\\.fr$') | list | sort }}"
|
||||
config:
|
||||
- job_name: servers
|
||||
file_sd_configs:
|
||||
- files:
|
||||
- '/etc/prometheus/targets_node.json'
|
||||
relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
- source_labels: [__param_target]
|
||||
target_label: instance
|
||||
- source_labels: [__param_target]
|
||||
target_label: __address__
|
||||
replacement: '$1:9100'
|
||||
|
||||
nginx:
|
||||
file: targets_nginx.json
|
||||
targets:
|
||||
- proxy.adm.ynerant.fr
|
||||
config:
|
||||
- job_name: nginx
|
||||
file_sd_configs:
|
||||
- files:
|
||||
- '/etc/prometheus/targets_nginx.json'
|
||||
relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: instance
|
||||
- source_labels: [instance]
|
||||
target_label: __address__
|
||||
replacement: '$1:9117'
|
||||
|
||||
blackbox:
|
||||
file: targets_blackbox.json
|
||||
targets:
|
||||
- https://ynerant.fr/
|
||||
- https://bibliogram.ynerant.fr/
|
||||
- https://element.ynerant.fr/
|
||||
- https://gitea.ynerant.fr/
|
||||
- https://grafana.ynerant.fr/
|
||||
- https://hydrogen.ynerant.fr/
|
||||
- https://nextcloud.ynerant.fr/
|
||||
- https://mailu.ynerant.fr/
|
||||
- http://notls.ynerant.fr/
|
||||
- https://reddit.ynerant.fr/
|
||||
- https://thelounge.ynerant.fr/
|
||||
- https://translate.ynerant.fr/
|
||||
- https://kfet.saperlistpopette.fr/
|
||||
config:
|
||||
- job_name: blackbox
|
||||
file_sd_configs:
|
||||
- files:
|
||||
- '/etc/prometheus/targets_blackbox.json'
|
||||
metrics_path: /probe
|
||||
params:
|
||||
module: [http_2xx] # Look for a HTTP 200 response.
|
||||
relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
- source_labels: [__param_target]
|
||||
target_label: instance
|
||||
- target_label: __address__
|
||||
replacement: 127.0.0.1:9115
|
4
host_vars/nextcloud.adm.ynerant.fr.yml
Normal file
4
host_vars/nextcloud.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
4
host_vars/nupes.adm.ynerant.fr.yml
Normal file
4
host_vars/nupes.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/pad.adm.ynerant.fr.yml
Normal file
4
host_vars/pad.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/peertube.adm.ynerant.fr.yml
Normal file
4
host_vars/peertube.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/proxy.adm.ynerant.fr.yml
Normal file
4
host_vars/proxy.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
||||
srv_nat: eth1
|
3
host_vars/psql.adm.ynerant.fr.yml
Normal file
3
host_vars/psql.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: eth0
|
5
host_vars/routeur-templier.adm.ynerant.fr.yml
Normal file
5
host_vars/routeur-templier.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
adh: ens19
|
||||
srv_nat: ens20
|
8
host_vars/templier.adm.ynerant.fr.yml
Normal file
8
host_vars/templier.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
loc_certbot:
|
||||
- dns_rfc2136_server: '172.16.42.103'
|
||||
dns_rfc2136_name: certbot_challenge.
|
||||
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
|
||||
mail: ynerant@crans.org
|
||||
certname: adm.ynerant.fr
|
||||
domains: "*.adm.ynerant.fr"
|
4
host_vars/tgvmax.adm.ynerant.fr.yml
Normal file
4
host_vars/tgvmax.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
4
host_vars/wireguard.adm.ynerant.fr.yml
Normal file
4
host_vars/wireguard.adm.ynerant.fr.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
interfaces:
|
||||
adm: ens18
|
||||
srv_nat: ens19
|
70
hosts
70
hosts
@ -1,3 +1,67 @@
|
||||
[perso]
|
||||
templier.adh.crans.org
|
||||
dt.adh.crans.org
|
||||
[blackbox]
|
||||
monitoring.adm.ynerant.fr
|
||||
|
||||
[certbot]
|
||||
proxy.adm.ynerant.fr
|
||||
templier.adm.ynerant.fr
|
||||
|
||||
[debian:children]
|
||||
server
|
||||
|
||||
[grafana]
|
||||
monitoring.adm.ynerant.fr
|
||||
|
||||
[nginx]
|
||||
nupes.adm.ynerant.fr
|
||||
tgvmax.adm.ynerant.fr
|
||||
|
||||
[nginx:children]
|
||||
reverseproxy
|
||||
|
||||
[ntp_server]
|
||||
routeur-templier.adm.ynerant.fr
|
||||
|
||||
[postfix]
|
||||
mailu.adm.ynerant.fr
|
||||
|
||||
[prometheus]
|
||||
monitoring.adm.ynerant.fr
|
||||
|
||||
[reverseproxy]
|
||||
proxy.adm.ynerant.fr
|
||||
|
||||
[routeur]
|
||||
routeur-templier.adm.ynerant.fr
|
||||
|
||||
[server:children]
|
||||
virtu
|
||||
vm
|
||||
|
||||
[slapd]
|
||||
templier.adm.ynerant.fr
|
||||
|
||||
[virtu]
|
||||
templier.adm.ynerant.fr
|
||||
|
||||
[vm]
|
||||
belenios.adm.ynerant.fr
|
||||
borg.adm.ynerant.fr
|
||||
dendrite.adm.ynerant.fr
|
||||
docker.adm.ynerant.fr
|
||||
dns.adm.ynerant.fr
|
||||
fosscord.adm.ynerant.fr
|
||||
galene.adm.ynerant.fr
|
||||
gitea.adm.ynerant.fr
|
||||
mailu.adm.ynerant.fr
|
||||
mastodon.adm.ynerant.fr
|
||||
#minecraft.adm.ynerant.fr
|
||||
monitoring.adm.ynerant.fr
|
||||
nextcloud.adm.ynerant.fr
|
||||
nupes.adm.ynerant.fr
|
||||
pad.adm.ynerant.fr
|
||||
peertube.adm.ynerant.fr
|
||||
psql.adm.ynerant.fr
|
||||
proxy.adm.ynerant.fr
|
||||
routeur-templier.adm.ynerant.fr
|
||||
tgvmax.adm.ynerant.fr
|
||||
wireguard.adm.ynerant.fr
|
||||
|
BIN
lookup_plugins/__pycache__/ldap.cpython-39.pyc
Normal file
BIN
lookup_plugins/__pycache__/ldap.cpython-39.pyc
Normal file
Binary file not shown.
206
lookup_plugins/ldap.py
Normal file
206
lookup_plugins/ldap.py
Normal file
@ -0,0 +1,206 @@
|
||||
"""
|
||||
To use this lookup plugin, you need to pass ldap:
|
||||
ssh -L 1636:172.16.10.1:636 172.16.10.1
|
||||
"""
|
||||
|
||||
import ipaddress
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
try:
|
||||
import ldap
|
||||
except ImportError:
|
||||
raise AnsibleError("You need to install python3-ldap")
|
||||
|
||||
display = Display()
|
||||
|
||||
def decode_object(object):
|
||||
return {attribute: [value.decode('utf-8') for value in object[attribute]] for attribute in object}
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.base = ldap.initialize('ldaps://localhost:1636/')
|
||||
self.base.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
|
||||
self.base.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
|
||||
self.base_dn = 'dc=ynerant,dc=fr'
|
||||
|
||||
def query(self, base, scope, filter='(objectClass=*)', attr=None):
|
||||
"""
|
||||
Make a LDAP query
|
||||
query('ldap', 'query', BASE, SCOPE[, FILTER[, ATTR]])
|
||||
BASE: base dn
|
||||
SCOPE: 'base', 'one' or 'sub'
|
||||
FILTER: ldap filter (optional)
|
||||
ATTR: list of attributes (optional)
|
||||
"""
|
||||
scope = { 'base': ldap.SCOPE_BASE, 'one': ldap.SCOPE_ONELEVEL, 'sub': ldap.SCOPE_SUBTREE }[scope]
|
||||
query_id = self.base.search(f"{base}", scope, filter, attr)
|
||||
result = self.base.result(query_id)[1]
|
||||
result = { dn: decode_object(entry) for dn, entry in result }
|
||||
return result
|
||||
|
||||
def ip(self, host, vlan):
|
||||
"""
|
||||
Retrieve IP addresses of an interface of a device
|
||||
query('ldap', 'ip', HOST, VLAN)
|
||||
"""
|
||||
if isinstance(vlan, int):
|
||||
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
|
||||
network_result = self.base.result(network_query_id)
|
||||
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
|
||||
if vlan == 'adh':
|
||||
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
else:
|
||||
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
result = self.base.result(query_id)
|
||||
result = result[1][0][1]
|
||||
result = [res.decode('utf-8') for res in result['ipHostNumber']]
|
||||
return result
|
||||
|
||||
def all_ip(self, host):
|
||||
"""
|
||||
Retrieve all IP addresses of a device
|
||||
query('ldap', 'all_ip', HOST)
|
||||
"""
|
||||
interfaces_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL)
|
||||
interfaces_result = self.base.result(interfaces_query_id)
|
||||
result = []
|
||||
for dn, interface in interfaces_result[1]:
|
||||
for ip in interface['ipHostNumber']:
|
||||
result.append(ip.decode('utf-8'))
|
||||
return result
|
||||
|
||||
def cn(self, host, vlan):
|
||||
"""
|
||||
Retrieve aliases of an interface of a device
|
||||
query('ldap', 'cn', HOST, VLAN)
|
||||
"""
|
||||
if isinstance(vlan, int):
|
||||
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
|
||||
network_result = self.base.result(network_query_id)
|
||||
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
|
||||
if vlan == 'adh':
|
||||
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
else:
|
||||
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
result = self.base.result(query_id)
|
||||
result = result[1][0][1]
|
||||
result = [res.decode('utf-8') for res in result['cn']]
|
||||
return result
|
||||
|
||||
def all_cn(self, host):
|
||||
"""
|
||||
Retrieve all aliases addresses of a device
|
||||
query('ldap', 'all_cn', HOST)
|
||||
"""
|
||||
interfaces_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL)
|
||||
interfaces_result = self.base.result(interfaces_query_id)
|
||||
result = []
|
||||
for dn, interface in interfaces_result[1]:
|
||||
for cn in interface['cn']:
|
||||
result.append(cn.decode('utf-8'))
|
||||
return result
|
||||
|
||||
def ssh_keys(self, host):
|
||||
"""
|
||||
Retrieve SSH keys of a host
|
||||
query('ldap', 'ssh_keys', HOST)
|
||||
"""
|
||||
host_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
host_result = self.base.result(host_query_id)[1][0][1]
|
||||
result = []
|
||||
if 'description' not in host_result:
|
||||
return result
|
||||
for description in host_result['description']:
|
||||
description = description.decode('utf-8')
|
||||
key, value = description.split(':', 1)
|
||||
if key in {'ecdsa-sha2-nistp256', 'ssh-ed25519', 'ssh-dss', 'ssh-rsa'}:
|
||||
result.append(f'{key} {value}')
|
||||
return result
|
||||
|
||||
def subnet_ipv4(self, subnet):
|
||||
"""
|
||||
Retrieve used IP addresses on a subnet
|
||||
query('ldap', 'subnet_ipv4', SUBNET)
|
||||
"""
|
||||
network_query_id = self.base.search(f"cn={subnet},ou=networks,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
network_result = self.base.result(network_query_id)
|
||||
network = network_result[1][0][1]
|
||||
network, hostmask = network['ipNetworkNumber'][0].decode('utf-8'), network['ipNetmaskNumber'][0].decode('utf-8')
|
||||
subnet = ipaddress.IPv4Network(f"{network}/{hostmask}")
|
||||
query_id = self.base.search(f"ou=hosts,{self.base_dn}", ldap.SCOPE_SUBTREE, "objectClass=ipHost")
|
||||
result = self.base.result(query_id)
|
||||
result = [ip.decode('utf-8') for dn, entry in result[1] for ip in entry['ipHostNumber'] if ipaddress.ip_address(ip.decode('utf-8')) in subnet]
|
||||
return result
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
if terms[0] == 'query':
|
||||
result = self.query(*terms[1:])
|
||||
elif terms[0] == 'ip':
|
||||
result = self.ip(*terms[1:])
|
||||
elif terms[0] == 'all_ip':
|
||||
result = self.all_ip(*terms[1:])
|
||||
elif terms[0] == 'cn':
|
||||
result = self.cn(*terms[1:])
|
||||
elif terms[0] == 'all_cn':
|
||||
result = self.all_cn(*terms[1:])
|
||||
elif terms[0] == 'subnet_ipv4':
|
||||
result = self.subnet_ipv4(*terms[1:])
|
||||
elif terms[0] == 'ssh_keys':
|
||||
result = self.ssh_keys(*terms[1:])
|
||||
elif terms[0] == 'group':
|
||||
query_id = self.base.search(f"ou=group,{self.base_dn}", ldap.SCOPE_SUBTREE, "objectClass=posixGroup")
|
||||
result = self.base.result(query_id)
|
||||
result = result[1]
|
||||
# query interface attribute
|
||||
# query('ldap', 'hosts', HOST, VLAN, ATTR)
|
||||
# HOST: device name
|
||||
# VLAN: vlan name
|
||||
# ATTR: attribute
|
||||
elif terms[0] == 'hosts':
|
||||
host = terms[1]
|
||||
vlan = terms[2]
|
||||
attr = terms[3]
|
||||
if isinstance(vlan, int):
|
||||
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
|
||||
network_result = self.base.result(network_query_id)
|
||||
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
|
||||
if vlan == 'adh':
|
||||
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
else:
|
||||
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
|
||||
result = self.base.result(query_id)
|
||||
result = result[1][0][1]
|
||||
result = [res.decode('utf-8') for res in result[attr]]
|
||||
elif terms[0] == 'network':
|
||||
network = terms[1]
|
||||
query_id = self.base.search(f"cn={network},ou=networks,{self.base_dn}", ldap.SCOPE_BASE, "objectClass=ipNetwork")
|
||||
result = self.base.result(query_id)
|
||||
result = result[1][0][1]
|
||||
return str(ipaddress.ip_network('{}/{}'.format(result['ipNetworkNumber'][0].decode('utf-8'), result['ipNetmaskNumber'][0].decode('utf-8'))))
|
||||
elif terms[0] == 'zones':
|
||||
query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, "objectClass=ipNetwork")
|
||||
result = self.base.result(query_id)
|
||||
res = []
|
||||
for _, network in result[1]:
|
||||
network = network['cn'][0].decode('utf-8')
|
||||
if network == 'adh':
|
||||
res.append('ynerant.fr')
|
||||
else:
|
||||
res.append(f"{network}.ynerant.fr")
|
||||
result = res
|
||||
elif terms[0] == 'vlanid':
|
||||
network = terms[1]
|
||||
query_id = self.base.search(f"cn={network},ou=networks,{self.base_dn}", ldap.SCOPE_BASE, "objectClass=ipNetwork")
|
||||
result = self.base.result(query_id)
|
||||
result = result[1][0][1]
|
||||
return int(result['description'][0])
|
||||
elif terms[0] == 'role':
|
||||
role = terms[1]
|
||||
query_id = self.base.search(f"ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description=role:{role}")
|
||||
result = self.base.result(query_id)
|
||||
result = [cn.decode('utf-8') for res in result[1] for cn in res[1]['cn']]
|
||||
return result
|
7
plays/apt.yml
Executable file
7
plays/apt.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: debian
|
||||
vars:
|
||||
apt: "{{ glob_apt | default({}) | combine(service_apt | default({})) | combine(loc_apt | default({})) }}"
|
||||
roles:
|
||||
- apt
|
23
plays/base.yml
Executable file
23
plays/base.yml
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
|
||||
- import_playbook: root.yml
|
||||
- import_playbook: apt.yml
|
||||
- import_playbook: network_interfaces.yml
|
||||
- import_playbook: ntp.yml
|
||||
- import_playbook: ldap-client.yml
|
||||
- import_playbook: home.yml
|
||||
- import_playbook: nullmailer.yml
|
||||
- import_playbook: monitoring.yml
|
||||
|
||||
- hosts: debian
|
||||
roles:
|
||||
- sudo
|
||||
- qemu-guest-agent
|
||||
- cli-utils
|
||||
|
||||
#- hosts: templier.adh.crans.org
|
||||
# roles:
|
||||
# - bind
|
||||
# - docker
|
||||
# become: yes
|
7
plays/certbot.yml
Executable file
7
plays/certbot.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: certbot
|
||||
vars:
|
||||
certbot: "{{ glob_certbot | default(service_certbot | default(loc_certbot | default([]))) }}"
|
||||
roles:
|
||||
- certbot
|
7
plays/home.yml
Executable file
7
plays/home.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: debian
|
||||
vars:
|
||||
home: '{{ glob_home | combine(loc_home | default({})) }}'
|
||||
roles:
|
||||
- home
|
7
plays/ldap-client.yml
Executable file
7
plays/ldap-client.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: debian
|
||||
vars:
|
||||
ldap: '{{ glob_ldap | combine(loc_ldap | default({})) }}'
|
||||
roles:
|
||||
- ldap-client
|
38
plays/monitoring.yml
Executable file
38
plays/monitoring.yml
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
|
||||
# Deploy Prometheus on monitoring server
|
||||
- hosts: prometheus
|
||||
vars:
|
||||
prometheus: "{{ glob_prometheus | default({}) | combine(loc_prometheus | default({})) }}"
|
||||
alertmanager: "{{ glob_alertmanager | default({}) | combine(loc_alertmanager | default({})) }}"
|
||||
ninjabot: "{{ glob_ninjabot | default({}) | combine(loc_ninjabot | default({})) }}"
|
||||
roles:
|
||||
- prometheus
|
||||
- prometheus-alertmanager
|
||||
- ninjabot
|
||||
|
||||
# Deploy Grafana on monitoring server
|
||||
- hosts: grafana
|
||||
vars:
|
||||
grafana: "{{ glob_grafana | default({}) | combine(loc_grafana | default({})) }}"
|
||||
roles:
|
||||
- grafana
|
||||
|
||||
- hosts: blackbox
|
||||
roles:
|
||||
- prometheus-blackbox-exporter
|
||||
|
||||
# Monitor all hosts
|
||||
- hosts: server
|
||||
vars:
|
||||
prometheus_node_exporter: "{{ glob_prometheus_node_exporter | default({}) | combine(loc_prometheus_node_exporter | default({})) }}"
|
||||
roles:
|
||||
- prometheus-node-exporter
|
||||
|
||||
# Export nginx metrics
|
||||
- hosts: nginx
|
||||
vars:
|
||||
prometheus_nginx_exporter: "{{ glob_prometheus_nginx_exporter | default({}) | combine(loc_prometheus_nginx_exporter | default({})) }}"
|
||||
roles:
|
||||
- prometheus-nginx-exporter
|
7
plays/network_interfaces.yml
Executable file
7
plays/network_interfaces.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: vm
|
||||
vars:
|
||||
network_interfaces: "{{ glob_network_interfaces | default({}) | combine(loc_network_interfaces | default({})) }}"
|
||||
roles:
|
||||
- network-interfaces
|
14
plays/nginx.yml
Executable file
14
plays/nginx.yml
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: nginx,!reverseproxy
|
||||
vars:
|
||||
nginx: "{{ glob_nginx | default({}) | combine(service_nginx | default({})) | combine(loc_nginx | default({})) }}"
|
||||
roles:
|
||||
- nginx
|
||||
|
||||
- hosts: reverseproxy
|
||||
vars:
|
||||
nginx: "{{ glob_nginx | default({}) | combine(service_nginx | default({})) | combine(loc_nginx | default({})) }}"
|
||||
reverseproxy: "{{ glob_reverseproxy | default({}) | combine(service_reverseproxy | default({})) | combine(loc_reverseproxy | default({})) }}"
|
||||
roles:
|
||||
- nginx
|
13
plays/ntp.yml
Executable file
13
plays/ntp.yml
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: ntp_server
|
||||
vars:
|
||||
ntp_server: '{{ glob_ntp_server | combine(loc_ntp_server | default({})) }}'
|
||||
roles:
|
||||
- ntp-server
|
||||
|
||||
- hosts: debian
|
||||
vars:
|
||||
ntp_client: '{{ glob_ntp_client | combine(loc_ntp_client | default({})) }}'
|
||||
roles:
|
||||
- ntp-client
|
7
plays/nullmailer.yml
Executable file
7
plays/nullmailer.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: debian,!postfix
|
||||
vars:
|
||||
nullmailer: "{{ glob_nullmailer | default({}) | combine(loc_nullmailer | default({})) }}"
|
||||
roles:
|
||||
- nullmailer
|
7
plays/root.yml
Executable file
7
plays/root.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: debian
|
||||
vars:
|
||||
root: "{{ glob_root | default({}) | combine(loc_root | default({})) }}"
|
||||
roles:
|
||||
- root
|
7
plays/slapd.yml
Executable file
7
plays/slapd.yml
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env ansible-playbook
|
||||
---
|
||||
- hosts: slapd
|
||||
vars:
|
||||
slapd: "{{ glob_slapd | default({}) | combine(service_slapd | default({})) | combine(loc_slapd | default({})) }}"
|
||||
roles:
|
||||
- slapd
|
32
roles/apt/tasks/apt-listchanges.yml
Normal file
32
roles/apt/tasks/apt-listchanges.yml
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
# Install apt-listchanges
|
||||
- name: Install apt-listchanges
|
||||
when: ansible_os_family == "Debian"
|
||||
apt:
|
||||
name: apt-listchanges
|
||||
state: present
|
||||
update_cache: true
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
# Send email when there is something new
|
||||
- name: Configure apt-listchanges
|
||||
ini_file:
|
||||
path: /etc/apt/listchanges.conf
|
||||
no_extra_spaces: true
|
||||
section: apt
|
||||
option: "{{ item.option }}"
|
||||
value: "{{ item.value }}"
|
||||
state: present
|
||||
mode: 0644
|
||||
loop:
|
||||
- option: confirm
|
||||
value: "true"
|
||||
|
||||
- option: email_address
|
||||
value: "{{ apt.monitoring_mail }}"
|
||||
|
||||
- option: which
|
||||
value: both
|
||||
...
|
20
roles/apt/tasks/apt-unattended.yml
Normal file
20
roles/apt/tasks/apt-unattended.yml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Install unattended-upgrades
|
||||
when: ansible_os_family == "Debian"
|
||||
apt:
|
||||
name: unattended-upgrades
|
||||
state: present
|
||||
update_cache: true
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Configure unattended-upgrades
|
||||
template:
|
||||
src: "apt/apt.conf.d/{{ item }}.j2"
|
||||
dest: "/etc/apt/apt.conf.d/{{ item }}"
|
||||
owner: root
|
||||
mode: u=rw,g=r,o=r
|
||||
loop:
|
||||
- 50unattended-upgrades
|
||||
- 20auto-upgrades
|
58
roles/apt/tasks/main.yml
Normal file
58
roles/apt/tasks/main.yml
Normal file
@ -0,0 +1,58 @@
|
||||
---
|
||||
- name: Add mirror.adm.ynerant.fr in /etc/hosts
|
||||
lineinfile:
|
||||
state: present
|
||||
path: /etc/hosts
|
||||
regex: "^{{ item }}"
|
||||
line: "{{ item }} mirror.adm.ynerant.fr"
|
||||
loop:
|
||||
- "172.16.42.102"
|
||||
- "fd00::42:4000:ff:fe01:242"
|
||||
|
||||
- name: Configure Debian repositories
|
||||
template:
|
||||
src: apt/sources.list.j2
|
||||
dest: /etc/apt/sources.list
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Configure extra repositories
|
||||
template:
|
||||
src: apt/sources.list.d/sources.list.j2
|
||||
dest: "/etc/apt/sources.list.d/{{ item.name }}.list"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
loop: "{{ apt.extra_repositories }}"
|
||||
|
||||
- name: Configure pin from future distributions
|
||||
when: item[2].key != ansible_distribution_release
|
||||
template:
|
||||
src: "apt/{{ item[0] }}.d/pin{{ item[1] }}.j2"
|
||||
dest: "/etc/apt/{{ item[0] }}.d/{{ item[2].key }}{{ item[1] }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
with_nested:
|
||||
- [["sources.list", ".list"], ["preferences", ""]]
|
||||
- "{{ apt.pin|dict2items }}"
|
||||
|
||||
- name: Clear useless pinned configuration
|
||||
when: item[2].key == ansible_distribution_release
|
||||
file:
|
||||
path: "/etc/apt/{{ item[0] }}.d/{{ item[2].key }}{{ item[1] }}"
|
||||
state: absent
|
||||
with_nested:
|
||||
- [["sources.list", ".list"], ["preferences", ""]]
|
||||
- "{{ apt.pin|dict2items }}"
|
||||
|
||||
- name: Update APT cache
|
||||
apt:
|
||||
update_cache: true
|
||||
|
||||
# APT-List Changes : send email with changelog
|
||||
- include_tasks: apt-listchanges.yml
|
||||
|
||||
# APT Unattended upgrades
|
||||
- include_tasks: apt-unattended.yml
|
4
roles/apt/templates/apt/apt.conf.d/20auto-upgrades.j2
Normal file
4
roles/apt/templates/apt/apt.conf.d/20auto-upgrades.j2
Normal file
@ -0,0 +1,4 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
APT::Periodic::Update-Package-Lists "1";
|
||||
APT::Periodic::Unattended-Upgrade "1";
|
175
roles/apt/templates/apt/apt.conf.d/50unattended-upgrades.j2
Normal file
175
roles/apt/templates/apt/apt.conf.d/50unattended-upgrades.j2
Normal file
@ -0,0 +1,175 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
// Unattended-Upgrade::Origins-Pattern controls which packages are
|
||||
// upgraded.
|
||||
//
|
||||
// Lines below have the format "keyword=value,...". A
|
||||
// package will be upgraded only if the values in its metadata match
|
||||
// all the supplied keywords in a line. (In other words, omitted
|
||||
// keywords are wild cards.) The keywords originate from the Release
|
||||
// file, but several aliases are accepted. The accepted keywords are:
|
||||
// a,archive,suite (eg, "stable")
|
||||
// c,component (eg, "main", "contrib", "non-free")
|
||||
// l,label (eg, "Debian", "Debian-Security")
|
||||
// o,origin (eg, "Debian", "Unofficial Multimedia Packages")
|
||||
// n,codename (eg, "jessie", "jessie-updates")
|
||||
// site (eg, "http.debian.net")
|
||||
// The available values on the system are printed by the command
|
||||
// "apt-cache policy", and can be debugged by running
|
||||
// "unattended-upgrades -d" and looking at the log file.
|
||||
//
|
||||
// Within lines unattended-upgrades allows 2 macros whose values are
|
||||
// derived from /etc/debian_version:
|
||||
// ${distro_id} Installed origin.
|
||||
// ${distro_codename} Installed codename (eg, "buster")
|
||||
Unattended-Upgrade::Origins-Pattern {
|
||||
// Codename based matching:
|
||||
// This will follow the migration of a release through different
|
||||
// archives (e.g. from testing to stable and later oldstable).
|
||||
// Software will be the latest available for the named release,
|
||||
// but the Debian release itself will not be automatically upgraded.
|
||||
"origin=Debian,codename=${distro_codename},label=Debian";
|
||||
"origin=Debian,codename=${distro_codename}-updates";
|
||||
"origin=Debian,codename=${distro_codename}-proposed-updates";
|
||||
"origin=Debian,codename=${distro_codename},label=Debian-Security";
|
||||
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
|
||||
"origin=Debian Backports,codename=${distro_codename}-backports,label=Debian Backports"
|
||||
|
||||
// Archive or Suite based matching:
|
||||
// Note that this will silently match a different release after
|
||||
// migration to the specified archive (e.g. testing becomes the
|
||||
// new stable).
|
||||
// "o=Debian,a=stable";
|
||||
// "o=Debian,a=stable-updates";
|
||||
// "o=Debian,a=proposed-updates";
|
||||
// "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports";
|
||||
};
|
||||
|
||||
// Python regular expressions, matching packages to exclude from upgrading
|
||||
Unattended-Upgrade::Package-Blacklist {
|
||||
// The following matches all packages starting with linux-
|
||||
// "linux-";
|
||||
|
||||
// Use $ to explicitely define the end of a package name. Without
|
||||
// the $, "libc6" would match all of them.
|
||||
// "libc6$";
|
||||
// "libc6-dev$";
|
||||
// "libc6-i686$";
|
||||
|
||||
// Special characters need escaping
|
||||
// "libstdc\+\+6$";
|
||||
|
||||
// The following matches packages like xen-system-amd64, xen-utils-4.1,
|
||||
// xenstore-utils and libxenstore3.0
|
||||
// "(lib)?xen(store)?";
|
||||
|
||||
// For more information about Python regular expressions, see
|
||||
// https://docs.python.org/3/howto/regex.html
|
||||
};
|
||||
|
||||
// This option allows you to control if on a unclean dpkg exit
|
||||
// unattended-upgrades will automatically run
|
||||
// dpkg --force-confold --configure -a
|
||||
// The default is true, to ensure updates keep getting installed
|
||||
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||||
|
||||
// Split the upgrade into the smallest possible chunks so that
|
||||
// they can be interrupted with SIGTERM. This makes the upgrade
|
||||
// a bit slower but it has the benefit that shutdown while a upgrade
|
||||
// is running is possible (with a small delay)
|
||||
//Unattended-Upgrade::MinimalSteps "true";
|
||||
Unattended-Upgrade::MinimalSteps "true";
|
||||
|
||||
// Install all updates when the machine is shutting down
|
||||
// instead of doing it in the background while the machine is running.
|
||||
// This will (obviously) make shutdown slower.
|
||||
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
|
||||
// This allows more time for unattended-upgrades to shut down gracefully
|
||||
// or even install a few packages in InstallOnShutdown mode, but is still a
|
||||
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
|
||||
// Users enabling InstallOnShutdown mode are advised to increase
|
||||
// InhibitDelayMaxSec even further, possibly to 30 minutes.
|
||||
//Unattended-Upgrade::InstallOnShutdown "false";
|
||||
|
||||
// Send email to this address for problems or packages upgrades
|
||||
// If empty or unset then no email is sent, make sure that you
|
||||
// have a working mail setup on your system. A package that provides
|
||||
// 'mailx' must be installed. E.g. "user@example.com"
|
||||
//Unattended-Upgrade::Mail "";
|
||||
Unattended-Upgrade::Mail "{{ apt.monitoring_mail }}";
|
||||
|
||||
// Set this value to one of:
|
||||
// "always", "only-on-error" or "on-change"
|
||||
// If this is not set, then any legacy MailOnlyOnError (boolean) value
|
||||
// is used to chose between "only-on-error" and "on-change"
|
||||
//Unattended-Upgrade::MailReport "on-change";
|
||||
|
||||
// Remove unused automatically installed kernel-related packages
|
||||
// (kernel images, kernel headers and kernel version locked tools).
|
||||
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||
|
||||
// Do automatic removal of newly unused dependencies after the upgrade
|
||||
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
|
||||
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
|
||||
|
||||
// Do automatic removal of unused packages after the upgrade
|
||||
// (equivalent to apt-get autoremove)
|
||||
//Unattended-Upgrade::Remove-Unused-Dependencies "false";
|
||||
Unattended-Upgrade::Remove-Unused-Dependencies "false";
|
||||
|
||||
// Automatically reboot *WITHOUT CONFIRMATION* if
|
||||
// the file /var/run/reboot-required is found after the upgrade
|
||||
//Unattended-Upgrade::Automatic-Reboot "false";
|
||||
Unattended-Upgrade::Automatic-Reboot "true";
|
||||
|
||||
// Automatically reboot even if there are users currently logged in
|
||||
// when Unattended-Upgrade::Automatic-Reboot is set to true
|
||||
//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
|
||||
|
||||
// If automatic reboot is enabled and needed, reboot at the specific
|
||||
// time instead of immediately
|
||||
// Default: "now"
|
||||
//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
|
||||
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
|
||||
|
||||
// Use apt bandwidth limit feature, this example limits the download
|
||||
// speed to 70kb/sec
|
||||
//Acquire::http::Dl-Limit "70";
|
||||
|
||||
// Enable logging to syslog. Default is False
|
||||
// Unattended-Upgrade::SyslogEnable "false";
|
||||
Unattended-Upgrade::SyslogEnable "true";
|
||||
|
||||
// Specify syslog facility. Default is daemon
|
||||
// Unattended-Upgrade::SyslogFacility "daemon";
|
||||
|
||||
// Download and install upgrades only on AC power
|
||||
// (i.e. skip or gracefully stop updates on battery)
|
||||
// Unattended-Upgrade::OnlyOnACPower "true";
|
||||
|
||||
// Download and install upgrades only on non-metered connection
|
||||
// (i.e. skip or gracefully stop updates on a metered connection)
|
||||
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
|
||||
|
||||
// Verbose logging
|
||||
// Unattended-Upgrade::Verbose "false";
|
||||
|
||||
// Print debugging information both in unattended-upgrades and
|
||||
// in unattended-upgrade-shutdown
|
||||
// Unattended-Upgrade::Debug "false";
|
||||
|
||||
// Allow package downgrade if Pin-Priority exceeds 1000
|
||||
// Unattended-Upgrade::Allow-downgrade "false";
|
||||
|
||||
// When APT fails to mark a package to be upgraded or installed try adjusting
|
||||
// candidates of related packages to help APT's resolver in finding a solution
|
||||
// where the package can be upgraded or installed.
|
||||
// This is a workaround until APT's resolver is fixed to always find a
|
||||
// solution if it exists. (See Debian bug #711128.)
|
||||
// The fallback is enabled by default, except on Debian's sid release because
|
||||
// uninstallable packages are frequent there.
|
||||
// Disabling the fallback speeds up unattended-upgrades when there are
|
||||
// uninstallable packages at the expense of rarely keeping back packages which
|
||||
// could be upgraded or installed.
|
||||
// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
|
12
roles/apt/templates/apt/preferences.d/pin.j2
Normal file
12
roles/apt/templates/apt/preferences.d/pin.j2
Normal file
@ -0,0 +1,12 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
|
||||
Package: *
|
||||
Pin: release n={{ item[2].key }}
|
||||
Pin-Priority: 1
|
||||
{% for package in item[2].value -%}
|
||||
|
||||
Package: {{ package }}
|
||||
Pin: release n={{ item[2].key }}
|
||||
Pin-Priority: 900
|
||||
{% endfor -%}
|
3
roles/apt/templates/apt/sources.list.d/pin.list.j2
Normal file
3
roles/apt/templates/apt/sources.list.d/pin.list.j2
Normal file
@ -0,0 +1,3 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
deb {{ apt.mirror }}debian {{ item[2].key }} main contrib non-free
|
8
roles/apt/templates/apt/sources.list.d/sources.list.j2
Normal file
8
roles/apt/templates/apt/sources.list.d/sources.list.j2
Normal file
@ -0,0 +1,8 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
{% for repo in item.repositories -%}
|
||||
deb {{ repo.url }} {{ repo.version }} {{ repo.tags }}
|
||||
{% if repo.src is defined and repo.src -%}
|
||||
deb-src {{ repo.url }} {{ repo.version }} {{ repo.tags }}
|
||||
{% endif -%}
|
||||
{% endfor -%}
|
15
roles/apt/templates/apt/sources.list.j2
Normal file
15
roles/apt/templates/apt/sources.list.j2
Normal file
@ -0,0 +1,15 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
# Mises à jour de sécurité
|
||||
deb {{ apt.mirror }}debian-security {{ ansible_distribution_release }}-security main contrib non-free
|
||||
|
||||
# Dépôt classique
|
||||
deb {{ apt.mirror }}debian {{ ansible_distribution_release }} main contrib non-free
|
||||
|
||||
# Dépôt pour mises à jour fréquentes (volatile)
|
||||
deb {{ apt.mirror }}debian {{ ansible_distribution_release }}-updates main contrib non-free
|
||||
|
||||
{% if apt.backports | default(false) %}
|
||||
# Backports
|
||||
deb {{ apt.mirror }}debian {{ ansible_distribution_release }}-backports main contrib non-free
|
||||
{% endif %}
|
File diff suppressed because it is too large
Load Diff
@ -1,326 +0,0 @@
|
||||
# Filename: /etc/skel/.zshrc
|
||||
# Purpose: config file for zsh (z shell)
|
||||
# Authors: (c) grml-team (grml.org)
|
||||
# Bug-Reports: see http://grml.org/bugs/
|
||||
# License: This file is licensed under the GPL v2 or any later version.
|
||||
################################################################################
|
||||
# Nowadays, grml's zsh setup lives in only *one* zshrc file.
|
||||
# That is the global one: /etc/zsh/zshrc (from grml-etc-core).
|
||||
# It is best to leave *this* file untouched and do personal changes to
|
||||
# your zsh setup via ${HOME}/.zshrc.local which is loaded at the end of
|
||||
# the global zshrc.
|
||||
#
|
||||
# That way, we enable people on other operating systems to use our
|
||||
# setup, too, just by copying our global zshrc to their ${HOME}/.zshrc.
|
||||
# Adjustments would still go to the .zshrc.local file.
|
||||
################################################################################
|
||||
|
||||
## Aurore host color and white user
|
||||
zstyle ':prompt:grml:left:items:host' pre '%B%F{red}'
|
||||
zstyle ':prompt:grml:left:items:host' post '%f%b'
|
||||
zstyle ':prompt:grml:left:items:user' pre '%B'
|
||||
zstyle ':prompt:grml:left:items:user' post '%b'
|
||||
|
||||
## Settings for umask
|
||||
#if (( EUID == 0 )); then
|
||||
# umask 002
|
||||
#else
|
||||
# umask 022
|
||||
#fi
|
||||
|
||||
## Now, we'll give a few examples of what you might want to use in your
|
||||
## .zshrc.local file (just copy'n'paste and uncomment it there):
|
||||
|
||||
## Prompt theme extension ##
|
||||
|
||||
# Virtualenv support
|
||||
|
||||
#function virtual_env_prompt () {
|
||||
# REPLY=${VIRTUAL_ENV+(${VIRTUAL_ENV:t}) }
|
||||
#}
|
||||
#grml_theme_add_token virtual-env -f virtual_env_prompt '%F{magenta}' '%f'
|
||||
#zstyle ':prompt:grml:left:setup' items rc virtual-env change-root user at host path vcs percent
|
||||
|
||||
## ZLE tweaks ##
|
||||
|
||||
## use the vi navigation keys (hjkl) besides cursor keys in menu completion
|
||||
#bindkey -M menuselect 'h' vi-backward-char # left
|
||||
#bindkey -M menuselect 'k' vi-up-line-or-history # up
|
||||
#bindkey -M menuselect 'l' vi-forward-char # right
|
||||
#bindkey -M menuselect 'j' vi-down-line-or-history # bottom
|
||||
|
||||
## set command prediction from history, see 'man 1 zshcontrib'
|
||||
#is4 && zrcautoload predict-on && \
|
||||
#zle -N predict-on && \
|
||||
#zle -N predict-off && \
|
||||
#bindkey "^X^Z" predict-on && \
|
||||
#bindkey "^Z" predict-off
|
||||
|
||||
## press ctrl-q to quote line:
|
||||
#mquote () {
|
||||
# zle beginning-of-line
|
||||
# zle forward-word
|
||||
# # RBUFFER="'$RBUFFER'"
|
||||
# RBUFFER=${(q)RBUFFER}
|
||||
# zle end-of-line
|
||||
#}
|
||||
#zle -N mquote && bindkey '^q' mquote
|
||||
|
||||
## define word separators (for stuff like backward-word, forward-word, backward-kill-word,..)
|
||||
#WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' # the default
|
||||
#WORDCHARS=.
|
||||
#WORDCHARS='*?_[]~=&;!#$%^(){}'
|
||||
#WORDCHARS='${WORDCHARS:s@/@}'
|
||||
|
||||
# just type '...' to get '../..'
|
||||
#rationalise-dot() {
|
||||
#local MATCH
|
||||
#if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' ]]; then
|
||||
# LBUFFER+=/
|
||||
# zle self-insert
|
||||
# zle self-insert
|
||||
#else
|
||||
# zle self-insert
|
||||
#fi
|
||||
#}
|
||||
#zle -N rationalise-dot
|
||||
#bindkey . rationalise-dot
|
||||
## without this, typing a . aborts incremental history search
|
||||
#bindkey -M isearch . self-insert
|
||||
|
||||
#bindkey '\eq' push-line-or-edit
|
||||
|
||||
## some popular options ##
|
||||
|
||||
## add `|' to output redirections in the history
|
||||
#setopt histallowclobber
|
||||
|
||||
## try to avoid the 'zsh: no matches found...'
|
||||
#setopt nonomatch
|
||||
|
||||
## warning if file exists ('cat /dev/null > ~/.zshrc')
|
||||
#setopt NO_clobber
|
||||
|
||||
## don't warn me about bg processes when exiting
|
||||
#setopt nocheckjobs
|
||||
|
||||
## alert me if something failed
|
||||
#setopt printexitvalue
|
||||
|
||||
## with spelling correction, assume dvorak kb
|
||||
#setopt dvorak
|
||||
|
||||
## Allow comments even in interactive shells
|
||||
#setopt interactivecomments
|
||||
|
||||
|
||||
## compsys related snippets ##
|
||||
|
||||
## changed completer settings
|
||||
#zstyle ':completion:*' completer _complete _correct _approximate
|
||||
#zstyle ':completion:*' expand prefix suffix
|
||||
|
||||
## another different completer setting: expand shell aliases
|
||||
#zstyle ':completion:*' completer _expand_alias _complete _approximate
|
||||
|
||||
## to have more convenient account completion, specify your logins:
|
||||
#my_accounts=(
|
||||
# {grml,grml1}@foo.invalid
|
||||
# grml-devel@bar.invalid
|
||||
#)
|
||||
#other_accounts=(
|
||||
# {fred,root}@foo.invalid
|
||||
# vera@bar.invalid
|
||||
#)
|
||||
#zstyle ':completion:*:my-accounts' users-hosts $my_accounts
|
||||
#zstyle ':completion:*:other-accounts' users-hosts $other_accounts
|
||||
|
||||
## add grml.org to your list of hosts
|
||||
#hosts+=(grml.org)
|
||||
#zstyle ':completion:*:hosts' hosts $hosts
|
||||
|
||||
## telnet on non-default ports? ...well:
|
||||
## specify specific port/service settings:
|
||||
#telnet_users_hosts_ports=(
|
||||
# user1@host1:
|
||||
# user2@host2:
|
||||
# @mail-server:{smtp,pop3}
|
||||
# @news-server:nntp
|
||||
# @proxy-server:8000
|
||||
#)
|
||||
#zstyle ':completion:*:*:telnet:*' users-hosts-ports $telnet_users_hosts_ports
|
||||
|
||||
## the default grml setup provides '..' as a completion. it does not provide
|
||||
## '.' though. If you want that too, use the following line:
|
||||
#zstyle ':completion:*' special-dirs true
|
||||
|
||||
## aliases ##
|
||||
|
||||
## translate
|
||||
#alias u='translate -i'
|
||||
|
||||
## ignore ~/.ssh/known_hosts entries
|
||||
#alias insecssh='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null" -o "PreferredAuthentications=keyboard-interactive"'
|
||||
|
||||
|
||||
## global aliases (for those who like them) ##
|
||||
|
||||
#alias -g '...'='../..'
|
||||
#alias -g '....'='../../..'
|
||||
#alias -g BG='& exit'
|
||||
#alias -g C='|wc -l'
|
||||
#alias -g G='|grep'
|
||||
#alias -g H='|head'
|
||||
#alias -g Hl=' --help |& less -r'
|
||||
#alias -g K='|keep'
|
||||
#alias -g L='|less'
|
||||
#alias -g LL='|& less -r'
|
||||
#alias -g M='|most'
|
||||
#alias -g N='&>/dev/null'
|
||||
#alias -g R='| tr A-z N-za-m'
|
||||
#alias -g SL='| sort | less'
|
||||
#alias -g S='| sort'
|
||||
#alias -g T='|tail'
|
||||
#alias -g V='| vim -'
|
||||
|
||||
## instead of global aliase it might be better to use grmls $abk assoc array, whose contents are expanded after pressing ,.
|
||||
#$abk[SnL]="| sort -n | less"
|
||||
|
||||
## get top 10 shell commands:
|
||||
#alias top10='print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
|
||||
|
||||
## Execute \kbd{./configure}
|
||||
#alias CO="./configure"
|
||||
|
||||
## Execute \kbd{./configure --help}
|
||||
#alias CH="./configure --help"
|
||||
|
||||
## miscellaneous code ##
|
||||
|
||||
## Use a default width of 80 for manpages for more convenient reading
|
||||
#export MANWIDTH=${MANWIDTH:-80}
|
||||
|
||||
## Set a search path for the cd builtin
|
||||
#cdpath=(.. ~)
|
||||
|
||||
## variation of our manzsh() function; pick you poison:
|
||||
#manzsh() { /usr/bin/man zshall | most +/"$1" ; }
|
||||
|
||||
## Switching shell safely and efficiently? http://www.zsh.org/mla/workers/2001/msg02410.html
|
||||
#bash() {
|
||||
# NO_SWITCH="yes" command bash "$@"
|
||||
#}
|
||||
#restart () {
|
||||
# exec $SHELL $SHELL_ARGS "$@"
|
||||
#}
|
||||
|
||||
## Handy functions for use with the (e::) globbing qualifier (like nt)
|
||||
#contains() { grep -q "$*" $REPLY }
|
||||
#sameas() { diff -q "$*" $REPLY &>/dev/null }
|
||||
#ot () { [[ $REPLY -ot ${~1} ]] }
|
||||
|
||||
## get_ic() - queries imap servers for capabilities; real simple. no imaps
|
||||
#ic_get() {
|
||||
# emulate -L zsh
|
||||
# local port
|
||||
# if [[ ! -z $1 ]] ; then
|
||||
# port=${2:-143}
|
||||
# print "querying imap server on $1:${port}...\n";
|
||||
# print "a1 capability\na2 logout\n" | nc $1 ${port}
|
||||
# else
|
||||
# print "usage:\n $0 <imap-server> [port]"
|
||||
# fi
|
||||
#}
|
||||
|
||||
## List all occurrences of programm in current PATH
|
||||
#plap() {
|
||||
# emulate -L zsh
|
||||
# if [[ $# = 0 ]] ; then
|
||||
# echo "Usage: $0 program"
|
||||
# echo "Example: $0 zsh"
|
||||
# echo "Lists all occurrences of program in the current PATH."
|
||||
# else
|
||||
# ls -l ${^path}/*$1*(*N)
|
||||
# fi
|
||||
#}
|
||||
|
||||
## Find out which libs define a symbol
|
||||
#lcheck() {
|
||||
# if [[ -n "$1" ]] ; then
|
||||
# nm -go /usr/lib/lib*.a 2>/dev/null | grep ":[[:xdigit:]]\{8\} . .*$1"
|
||||
# else
|
||||
# echo "Usage: lcheck <function>" >&2
|
||||
# fi
|
||||
#}
|
||||
|
||||
## Download a file and display it locally
|
||||
#uopen() {
|
||||
# emulate -L zsh
|
||||
# if ! [[ -n "$1" ]] ; then
|
||||
# print "Usage: uopen \$URL/\$file">&2
|
||||
# return 1
|
||||
# else
|
||||
# FILE=$1
|
||||
# MIME=$(curl --head $FILE | \
|
||||
# grep Content-Type | \
|
||||
# cut -d ' ' -f 2 | \
|
||||
# cut -d\; -f 1)
|
||||
# MIME=${MIME%$'\r'}
|
||||
# curl $FILE | see ${MIME}:-
|
||||
# fi
|
||||
#}
|
||||
|
||||
## Memory overview
|
||||
#memusage() {
|
||||
# ps aux | awk '{if (NR > 1) print $5;
|
||||
# if (NR > 2) print "+"}
|
||||
# END { print "p" }' | dc
|
||||
#}
|
||||
|
||||
## print hex value of a number
|
||||
#hex() {
|
||||
# emulate -L zsh
|
||||
# if [[ -n "$1" ]]; then
|
||||
# printf "%x\n" $1
|
||||
# else
|
||||
# print 'Usage: hex <number-to-convert>'
|
||||
# return 1
|
||||
# fi
|
||||
#}
|
||||
|
||||
## log out? set timeout in seconds...
|
||||
## ...and do not log out in some specific terminals:
|
||||
#if [[ "${TERM}" == ([Exa]term*|rxvt|dtterm|screen*) ]] ; then
|
||||
# unset TMOUT
|
||||
#else
|
||||
# TMOUT=1800
|
||||
#fi
|
||||
|
||||
## associate types and extensions (be aware with perl scripts and anwanted behaviour!)
|
||||
#check_com zsh-mime-setup || { autoload zsh-mime-setup && zsh-mime-setup }
|
||||
#alias -s pl='perl -S'
|
||||
|
||||
## ctrl-s will no longer freeze the terminal.
|
||||
#stty erase "^?"
|
||||
|
||||
## you want to automatically use a bigger font on big terminals?
|
||||
#if [[ "$TERM" == "xterm" ]] && [[ "$LINES" -ge 50 ]] && [[ "$COLUMNS" -ge 100 ]] && [[ -z "$SSH_CONNECTION" ]] ; then
|
||||
# large
|
||||
#fi
|
||||
|
||||
## Some quick Perl-hacks aka /useful/ oneliner
|
||||
#bew() { perl -le 'print unpack "B*","'$1'"' }
|
||||
#web() { perl -le 'print pack "B*","'$1'"' }
|
||||
#hew() { perl -le 'print unpack "H*","'$1'"' }
|
||||
#weh() { perl -le 'print pack "H*","'$1'"' }
|
||||
#pversion() { perl -M$1 -le "print $1->VERSION" } # i. e."pversion LWP -> 5.79"
|
||||
#getlinks () { perl -ne 'while ( m/"((www|ftp|http):\/\/.*?)"/gc ) { print $1, "\n"; }' $* }
|
||||
#gethrefs () { perl -ne 'while ( m/href="([^"]*)"/gc ) { print $1, "\n"; }' $* }
|
||||
#getanames () { perl -ne 'while ( m/a name="([^"]*)"/gc ) { print $1, "\n"; }' $* }
|
||||
#getforms () { perl -ne 'while ( m:(\</?(input|form|select|option).*?\>):gic ) { print $1, "\n"; }' $* }
|
||||
#getstrings () { perl -ne 'while ( m/"(.*?)"/gc ) { print $1, "\n"; }' $*}
|
||||
#showINC () { perl -e 'for (@INC) { printf "%d %s\n", $i++, $_ }' }
|
||||
#vimpm () { vim `perldoc -l $1 | sed -e 's/pod$/pm/'` }
|
||||
#vimhelp () { vim -c "help $1" -c on -c "au! VimEnter *" }
|
||||
|
||||
## END OF FILE #################################################################
|
@ -1,39 +0,0 @@
|
||||
#!/bin/sh
|
||||
# {{ ansible_managed }}
|
||||
|
||||
# Pretty uptime
|
||||
upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
|
||||
mins=$((${upSeconds}/60%60))
|
||||
hours=$((${upSeconds}/3600%24))
|
||||
days=$((${upSeconds}/86400))
|
||||
UPTIME=`printf "%d jours, %02dh%02dm" "$days" "$hours" "$mins"`
|
||||
|
||||
# RAM
|
||||
RAM=`free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'`
|
||||
DISK=`df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}'`
|
||||
|
||||
# Text font
|
||||
bold=$(tput bold)
|
||||
normal=$(tput sgr0)
|
||||
|
||||
# Logo
|
||||
cat << EOF
|
||||
[49m[K[0m
|
||||
[0m [48;5;160m[38;5;160m [48;5;124m[38;5;124m [48;5;160m[38;5;160m [0m [49m ${bold}Uptime${normal} : ${UPTIME}
|
||||
[0m [48;5;160m[38;5;160m [0m [49m ${bold}Mémoire${normal} : ${RAM}
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m ${bold}Disque racine${normal} : ${DISK}
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [48;5;124m[38;5;124m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [48;5;52m[38;5;196m [0m [49m
|
||||
[0m [48;5;124m[38;5;124m [0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [48;5;124m[38;5;124m [0m[49m
|
||||
[0m [48;5;124m[38;5;124m [48;5;160m[38;5;160m [0m [48;5;188m[38;5;188m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m[49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;160m[38;5;160m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m[49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;160m[38;5;160m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m[49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;124m[38;5;124m [0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [0m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [0m [48;5;231m[38;5;232m [0m [48;5;231m[38;5;232m [48;5;160m[38;5;160m [0m [49m
|
||||
[0m [48;5;160m[38;5;160m [0m ${bold}Aurore${normal} [48;5;231m[38;5;232m [48;5;160m[38;5;160m [0m [49m
|
||||
|
||||
EOF
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
# {{ ansible_managed }}
|
||||
uname -snrvm
|
@ -1,4 +0,0 @@
|
||||
---
|
||||
# Reconfigure locales when conf changes
|
||||
- name: Reconfigure locales
|
||||
command: dpkg-reconfigure locales -f noninteractive
|
@ -1,52 +0,0 @@
|
||||
---
|
||||
- name: Install basic tools
|
||||
apt:
|
||||
name:
|
||||
- apt # better than apt-get
|
||||
- aptitude # nice to have for Ansible
|
||||
- bash-completion # because bash
|
||||
- curl # better than wget
|
||||
- git # code versioning
|
||||
- htop # better than top
|
||||
- less # i like cats
|
||||
- sudo # i am god
|
||||
- tmux # better than screen
|
||||
- tree # create a graphical tree of files
|
||||
- vim # better than nano
|
||||
- molly-guard # prevent reboot
|
||||
- ntp # network time sync
|
||||
- emacs-nox # for maman
|
||||
update_cache: true
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
# Pimp my server
|
||||
- name: Customize motd
|
||||
copy:
|
||||
src: "update-motd.d/{{ item }}"
|
||||
dest: "/etc/update-motd.d/{{ item }}"
|
||||
mode: 0755
|
||||
loop:
|
||||
- 00-logo
|
||||
- 10-uname
|
||||
|
||||
- name: Remove Debian warranty motd
|
||||
file:
|
||||
path: /etc/motd
|
||||
state: absent
|
||||
|
||||
# Patriotisme
|
||||
- name: Ensure French UTF-8 locale exists
|
||||
locale_gen:
|
||||
name: fr_FR.UTF-8
|
||||
state: present
|
||||
|
||||
# Fix LC_CTYPE="C"
|
||||
- name: Select default locale
|
||||
debconf:
|
||||
name: locales
|
||||
question: locales/default_environment_locale
|
||||
value: fr_FR.UTF-8
|
||||
vtype: select
|
||||
notify: Reconfigure locales
|
6
roles/bind/handlers/main.yml
Normal file
6
roles/bind/handlers/main.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Restart bind
|
||||
service:
|
||||
name: bind9
|
||||
state: restarted
|
23
roles/bind/tasks/main.yml
Normal file
23
roles/bind/tasks/main.yml
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
|
||||
- name: Queries apt to install bind9
|
||||
apt:
|
||||
name:
|
||||
- bind9
|
||||
register: pkg_result
|
||||
retries: 3
|
||||
until: pkg_result is succeeded
|
||||
notify: Restart bind
|
||||
|
||||
- name: Deploy named local configuration
|
||||
template:
|
||||
src: 'named.conf.local.j2'
|
||||
dest: '/etc/bind/named.conf.local'
|
||||
notify: Restart bind
|
||||
|
||||
- name: Deploy per-site configuration
|
||||
template:
|
||||
src: 'db.j2'
|
||||
dest: '/var/lib/bind/{{ item.name }}/db'
|
||||
with_items: '{{ bind.domains }}'
|
||||
notify: Restart bind
|
21
roles/bind/templates/db.j2
Normal file
21
roles/bind/templates/db.j2
Normal file
@ -0,0 +1,21 @@
|
||||
$TTL 3600
|
||||
@ IN SOA dns {{ item.administrator }}. (
|
||||
{{ '%Y%m%d%H' | strftime }} ;Serial
|
||||
3600 ;Refresh
|
||||
1800 ;Retry
|
||||
3600000 ;Expire
|
||||
172800 ;Minimum
|
||||
)
|
||||
|
||||
{{ item.name }}. IN NS dns
|
||||
{{ item.name }}. IN NS slave
|
||||
{{ item.name }}. IN A {{ item.ipv4 }}
|
||||
{{ item.name }}. IN AAAA {{ item.ipv6 }}
|
||||
|
||||
dns IN A {{ item.ipv4 }}
|
||||
dns IN AAAA {{ item.ipv6 }}
|
||||
slave IN A {{ item.slave }}
|
||||
|
||||
{% for alias in item.aliases %}
|
||||
{{ alias }} IN CNAME @
|
||||
{% endfor %}
|
18
roles/bind/templates/named.conf.local.j2
Normal file
18
roles/bind/templates/named.conf.local.j2
Normal file
@ -0,0 +1,18 @@
|
||||
{{ ansible_header | comment(decoration='//') }}
|
||||
|
||||
//
|
||||
// Do any local configuration here
|
||||
//
|
||||
|
||||
// Consider adding the 1918 zones here, if they are not used in your
|
||||
// organization
|
||||
//include "/etc/bind/zones.rfc1918";
|
||||
|
||||
{% for domain in bind.domains %}
|
||||
zone "{{ domain.name }}" {
|
||||
type master;
|
||||
file "/var/lib/bind/{{ domain.name }}/db";
|
||||
notify yes;
|
||||
allow-transfer { {{ domain.slave }}; };
|
||||
};
|
||||
{% endfor %}
|
52
roles/certbot/tasks/main.yml
Normal file
52
roles/certbot/tasks/main.yml
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Install certbot and RFC2136 plugin
|
||||
apt:
|
||||
update_cache: true
|
||||
name:
|
||||
- certbot
|
||||
- python3-certbot-dns-rfc2136
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Add DNS credentials
|
||||
template:
|
||||
src: letsencrypt/rfc2136.ini.j2
|
||||
dest: "/etc/letsencrypt/rfc2136.{{ item.certname }}.ini"
|
||||
mode: 0600
|
||||
owner: root
|
||||
loop: "{{ certbot }}"
|
||||
|
||||
- name: Add dhparam
|
||||
template:
|
||||
src: "letsencrypt/dhparam.j2"
|
||||
dest: "/etc/letsencrypt/dhparam"
|
||||
mode: 0600
|
||||
|
||||
- name: Create /etc/letsencrypt/conf.d
|
||||
file:
|
||||
path: /etc/letsencrypt/conf.d
|
||||
state: directory
|
||||
|
||||
- name: Add Certbot configuration
|
||||
template:
|
||||
src: "letsencrypt/conf.d/certname.ini.j2"
|
||||
dest: "/etc/letsencrypt/conf.d/{{ item.certname }}.ini"
|
||||
mode: 0644
|
||||
loop: "{{ certbot }}"
|
||||
|
||||
- name: Run certbot
|
||||
command: certbot --non-interactive --config /etc/letsencrypt/conf.d/{{ item.certname }}.ini certonly
|
||||
register: certbot_output
|
||||
changed_when: not "Certificate not yet due for renewal" in certbot_output.stdout
|
||||
loop: "{{ certbot }}"
|
||||
|
||||
- name: Clean old files
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/etc/letsencrypt/options-ssl-nginx.conf"
|
||||
- "/etc/letsencrypt/ssl-dhparams.pem"
|
||||
- "/etc/letsencrypt/rfc2136.ini"
|
28
roles/certbot/templates/letsencrypt/conf.d/certname.ini.j2
Normal file
28
roles/certbot/templates/letsencrypt/conf.d/certname.ini.j2
Normal file
@ -0,0 +1,28 @@
|
||||
{{ ansible_header | comment(decoration='# ') }}
|
||||
|
||||
# To generate the certificate, please use the following command
|
||||
# certbot --config /etc/letsencrypt/conf.d/{{ item.certname }}.ini certonly
|
||||
|
||||
# Use a 4096 bit RSA key instead of 2048
|
||||
rsa-key-size = 4096
|
||||
|
||||
# Always use the staging/testing server
|
||||
# server = https://acme-staging.api.letsencrypt.org/directory
|
||||
|
||||
# Uncomment and update to register with the specified e-mail address
|
||||
email = {{ item.mail }}
|
||||
|
||||
# Uncomment to use a text interface instead of ncurses
|
||||
text = True
|
||||
|
||||
# Yes I want to sell my soul and my guinea pig.
|
||||
agree-tos = True
|
||||
|
||||
# Use DNS-01 challenge
|
||||
authenticator = dns-rfc2136
|
||||
dns-rfc2136-credentials = /etc/letsencrypt/rfc2136.{{ item.certname }}.ini
|
||||
dns-rfc2136-propagation-seconds = 30
|
||||
|
||||
# Wildcard the domain
|
||||
cert-name = {{ item.certname }}
|
||||
domains = {{ item.domains }}
|
8
roles/certbot/templates/letsencrypt/dhparam.j2
Normal file
8
roles/certbot/templates/letsencrypt/dhparam.j2
Normal file
@ -0,0 +1,8 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||
-----END DH PARAMETERS-----
|
7
roles/certbot/templates/letsencrypt/rfc2136.ini.j2
Normal file
7
roles/certbot/templates/letsencrypt/rfc2136.ini.j2
Normal file
@ -0,0 +1,7 @@
|
||||
{{ ansible_header | comment(decoration='# ') }}
|
||||
|
||||
dns_rfc2136_server = {{ item.dns_rfc2136_server }}
|
||||
dns_rfc2136_port = 53
|
||||
dns_rfc2136_name = {{ item.dns_rfc2136_name }}
|
||||
dns_rfc2136_secret = {{ item.dns_rfc2136_secret }}
|
||||
dns_rfc2136_algorithm = HMAC-SHA512
|
26
roles/cli-utils/tasks/main.yml
Normal file
26
roles/cli-utils/tasks/main.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
- name: Install useful utilities
|
||||
package:
|
||||
name:
|
||||
- bash
|
||||
- bash-completion
|
||||
- bat
|
||||
- curl
|
||||
- dnsutils
|
||||
- git
|
||||
- htop
|
||||
- man
|
||||
- molly-guard
|
||||
- mtr-tiny
|
||||
- needrestart
|
||||
- patch
|
||||
- rsync
|
||||
- sl
|
||||
- sudo
|
||||
- tmux
|
||||
- traceroute
|
||||
- tree
|
||||
- vim
|
||||
register: pkg_result
|
||||
retries: 3
|
||||
until: pkg_result is succeeded
|
@ -15,4 +15,6 @@
|
||||
template:
|
||||
src: update-motd.d/05-service.j2
|
||||
dest: /etc/update-motd.d/05-docker
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0755
|
||||
|
@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
# {{ ansible_managed }}
|
||||
{{ ansible_header | comment }}
|
||||
echo "> Les recettes Docker-compose se trouvent dans /var/local/ansible-docker"
|
||||
|
5
roles/grafana/handlers/main.yml
Normal file
5
roles/grafana/handlers/main.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Restart grafana
|
||||
service:
|
||||
name: grafana-server
|
||||
state: restarted
|
100
roles/grafana/tasks/main.yml
Normal file
100
roles/grafana/tasks/main.yml
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
- name: Install GPG
|
||||
apt:
|
||||
name: gnupg
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Import Grafana GPG signing key
|
||||
apt_key:
|
||||
url: https://packages.grafana.com/gpg.key
|
||||
state: present
|
||||
validate_certs: false
|
||||
register: apt_key_result
|
||||
retries: 3
|
||||
until: apt_key_result is succeeded
|
||||
|
||||
- name: Add Grafana repository
|
||||
apt_repository:
|
||||
repo: deb http://mirror.adm.ynerant.fr/grafana/oss/deb stable main
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install Grafana
|
||||
apt:
|
||||
name: grafana
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Configure Grafana
|
||||
ini_file:
|
||||
path: /etc/grafana/grafana.ini
|
||||
section: "{{ item.section }}"
|
||||
option: "{{ item.option }}"
|
||||
value: "{{ item.value }}"
|
||||
mode: 0640
|
||||
loop:
|
||||
- section: server
|
||||
option: root_url
|
||||
value: "{{ grafana.root_url }}"
|
||||
- section: analytics
|
||||
option: reporting_enabled
|
||||
value: "false"
|
||||
- section: analytics
|
||||
option: check_for_updates
|
||||
value: "false"
|
||||
- section: security
|
||||
option: disable_initial_admin_creation
|
||||
value: "true"
|
||||
- section: security
|
||||
option: cookie_secure
|
||||
value: "true"
|
||||
- section: snapshots
|
||||
option: external_enabled
|
||||
value: "false"
|
||||
- section: users
|
||||
option: allow_sign_up
|
||||
value: "false"
|
||||
- section: users
|
||||
option: allow_org_create
|
||||
value: "false"
|
||||
- section: auth.anonymous
|
||||
option: enabled
|
||||
value: "true"
|
||||
- section: auth.anonymous
|
||||
option: hide_version
|
||||
value: "true"
|
||||
- section: auth.basic # Only LDAP auth
|
||||
option: enabled
|
||||
value: "false"
|
||||
- section: auth.ldap
|
||||
option: enabled
|
||||
value: "true"
|
||||
- section: alerting
|
||||
option: enabled
|
||||
value: "false"
|
||||
notify: Restart grafana
|
||||
|
||||
- name: Configure Grafana LDAP
|
||||
template:
|
||||
src: ldap.toml.j2
|
||||
dest: /etc/grafana/ldap.toml
|
||||
mode: 0640
|
||||
notify: Restart grafana
|
||||
|
||||
- name: Enable and start Grafana
|
||||
systemd:
|
||||
name: grafana-server
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
- name: Indicate role in motd
|
||||
template:
|
||||
src: update-motd.d/05-service.j2
|
||||
dest: /etc/update-motd.d/05-grafana
|
||||
mode: 0755
|
47
roles/grafana/templates/ldap.toml.j2
Normal file
47
roles/grafana/templates/ldap.toml.j2
Normal file
@ -0,0 +1,47 @@
|
||||
{{ ansible_header | comment }}
|
||||
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
|
||||
# [log]
|
||||
# filters = ldap:debug
|
||||
|
||||
[[servers]]
|
||||
# Ldap server host (specify multiple hosts space separated)
|
||||
host = "{{ grafana.ldap_master_ipv4 }}"
|
||||
# Default port is 389 or 636 if use_ssl = true
|
||||
port = 636
|
||||
# Set to true if ldap server supports TLS
|
||||
use_ssl = true
|
||||
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
|
||||
start_tls = false
|
||||
# set to true if you want to skip ssl cert validation
|
||||
ssl_skip_verify = true
|
||||
# set to the path to your root CA certificate or leave unset to use system defaults
|
||||
# root_ca_cert = "/path/to/certificate.crt"
|
||||
# Authentication against LDAP servers requiring client certificates
|
||||
# client_cert = "/path/to/client.crt"
|
||||
# client_key = "/path/to/client.key"
|
||||
|
||||
# Use direct bind
|
||||
bind_dn = "uid=%s,{{ grafana.ldap_user_tree }}"
|
||||
|
||||
# Useless as we are doing direct bind,
|
||||
# but without LDAP auth hang
|
||||
search_filter = "(uid=%s)"
|
||||
search_base_dns = ["ou=passwd,dc=ynerant,dc=fr"]
|
||||
|
||||
## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
|
||||
## Please check grafana LDAP docs for examples
|
||||
group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
|
||||
group_search_base_dns = ["ou=group,{{ grafana.ldap_base }}"]
|
||||
group_search_filter_user_attribute = "cn"
|
||||
|
||||
# Specify names of the ldap attributes your ldap uses
|
||||
[servers.attributes]
|
||||
name = "givenName"
|
||||
surname = "sn"
|
||||
username = "uid"
|
||||
email = "mail"
|
||||
|
||||
# All LDAP members can edit
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "*"
|
||||
org_role = "Admin"
|
3
roles/grafana/templates/update-motd.d/05-service.j2
Executable file
3
roles/grafana/templates/update-motd.d/05-service.j2
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/tail +14
|
||||
{{ ansible_header | comment }}
|
||||
[0m> [38;5;82mgrafana[0m a été déployé sur cette machine. Voir [38;5;6m/etc/grafana/[0m.
|
8
roles/home/README.md
Normal file
8
roles/home/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# HOME-NOUNOUS
|
||||
|
||||
Ce rôle permet d'exporter les homes vers les différents serveurs.
|
||||
|
||||
## VARS
|
||||
|
||||
home_nounous:
|
||||
ip: l'ip du serveur nfs
|
31
roles/home/tasks/main.yml
Normal file
31
roles/home/tasks/main.yml
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
- name: Install NFS client
|
||||
apt:
|
||||
update_cache: true
|
||||
name:
|
||||
- nfs-common
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Create directory home
|
||||
file:
|
||||
path: /home
|
||||
state: directory
|
||||
owner: root
|
||||
group: user
|
||||
mode: 0750
|
||||
|
||||
- name: Deploy nfs systemd mount
|
||||
template:
|
||||
src: systemd/system/home.mount.j2
|
||||
dest: /etc/systemd/system/home.mount
|
||||
mode: 0644
|
||||
|
||||
- name: Load and activate nfs systemd mount
|
||||
systemd:
|
||||
name: home.mount
|
||||
daemon_reload: true
|
||||
enabled: true
|
||||
state: started
|
14
roles/home/templates/systemd/system/home.mount.j2
Normal file
14
roles/home/templates/systemd/system/home.mount.j2
Normal file
@ -0,0 +1,14 @@
|
||||
{{ ansible_header | comment }}
|
||||
[Unit]
|
||||
Description=Mount home
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Mount]
|
||||
What={{ home.ip }}:{{ home.mountpoint }}
|
||||
Where=/home
|
||||
Type=nfs
|
||||
Options=rw,nosuid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
10
roles/ldap-client/README.md
Normal file
10
roles/ldap-client/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# LDAP-CLIENT
|
||||
|
||||
Configure un client ldap pour les utilisateurs
|
||||
|
||||
## VARS
|
||||
|
||||
ldap:
|
||||
- local: si le serveur est installé en local
|
||||
- servers: la liste des servers ldap a contacté
|
||||
- base: le search term du ldap
|
16
roles/ldap-client/handlers/main.yml
Normal file
16
roles/ldap-client/handlers/main.yml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Reconfigure libnss-ldapd package
|
||||
command: dpkg-reconfigure libnss-ldapd -f noninteractive
|
||||
|
||||
- name: Restart nslcd service
|
||||
service:
|
||||
name: nslcd
|
||||
state: restarted
|
||||
|
||||
# Empty cache when nslcd is restarted
|
||||
- name: Restart nscd service
|
||||
service:
|
||||
name: nscd
|
||||
state: restarted
|
||||
ignore_errors: true # Sometimes service do not exist
|
||||
listen: Restart nslcd service
|
50
roles/ldap-client/tasks/main.yml
Normal file
50
roles/ldap-client/tasks/main.yml
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
# Install LDAP client packages
|
||||
- name: Install LDAP client packages
|
||||
apt:
|
||||
update_cache: true
|
||||
name:
|
||||
- libnss-ldapd
|
||||
- libpam-ldapd
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
# Configure /etc/nslcd.conf
|
||||
- name: Configure nslcd
|
||||
template:
|
||||
src: nslcd.conf.j2
|
||||
dest: /etc/nslcd.conf
|
||||
mode: 0600
|
||||
notify: Restart nslcd service
|
||||
|
||||
# Configure /etc/nsswitch.conf
|
||||
- name: Configure NSS to use LDAP
|
||||
lineinfile:
|
||||
dest: /etc/nsswitch.conf
|
||||
regexp: "^{{ item }}"
|
||||
line: "{{ item }} files systemd ldap"
|
||||
loop:
|
||||
- "passwd:"
|
||||
- "group: "
|
||||
notify: Restart nslcd service
|
||||
|
||||
- name: Configure NSS to use LDAP
|
||||
lineinfile:
|
||||
dest: /etc/nsswitch.conf
|
||||
regexp: "^{{ item }}"
|
||||
line: "{{ item }} files ldap"
|
||||
loop:
|
||||
- "shadow: "
|
||||
- "networks:"
|
||||
notify: Restart nslcd service
|
||||
|
||||
- name: Configure NSS to use LDAP
|
||||
lineinfile:
|
||||
dest: /etc/nsswitch.conf
|
||||
regexp: "^{{ item }}"
|
||||
line: "{{ item }} files ldap dns"
|
||||
loop:
|
||||
- "hosts:"
|
||||
notify: Restart nslcd service
|
38
roles/ldap-client/templates/nslcd.conf.j2
Normal file
38
roles/ldap-client/templates/nslcd.conf.j2
Normal file
@ -0,0 +1,38 @@
|
||||
{{ ansible_header | comment }}
|
||||
# /etc/nslcd.conf
|
||||
# nslcd configuration file. See nslcd.conf(5)
|
||||
# for details.
|
||||
|
||||
# The user and group nslcd should run as.
|
||||
uid nslcd
|
||||
gid nslcd
|
||||
|
||||
# The location at which the LDAP server(s) should be reachable.
|
||||
{% if 'slapd' in group_names %}
|
||||
uri ldapi:///
|
||||
{% else %}
|
||||
{% for server in ldap.servers %}
|
||||
uri ldaps://{{ server }}/
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
# The search base that will be used for all queries.
|
||||
base {{ ldap.base }}
|
||||
|
||||
# The LDAP protocol version to use.
|
||||
#ldap_version 3
|
||||
|
||||
# The DN to bind with for normal lookups.
|
||||
#binddn cn=annonymous,dc=example,dc=net
|
||||
#bindpw secret
|
||||
|
||||
# The DN used for password modifications by root.
|
||||
#rootpwmoddn cn=admin,dc=example,dc=com
|
||||
|
||||
# SSL options
|
||||
#ssl off
|
||||
tls_reqcert allow
|
||||
tls_cacertfile /etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
# The search scope.
|
||||
#scope sub
|
28
roles/network-interfaces/tasks/main.yml
Normal file
28
roles/network-interfaces/tasks/main.yml
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Install vlan support
|
||||
apt:
|
||||
update_cache: true
|
||||
name: vlan
|
||||
state: present
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Deploy default interfaces config
|
||||
template:
|
||||
src: network/interfaces.j2
|
||||
dest: /etc/network/interfaces
|
||||
mode: 0644
|
||||
|
||||
- name: Remove cloud-init interface configuration
|
||||
file:
|
||||
path: /etc/network/interfaces.d/50-cloud-init
|
||||
state: absent
|
||||
|
||||
- name: Deploy interfaces config
|
||||
template:
|
||||
src: "network/interfaces.d/ifalias.j2"
|
||||
dest: "/etc/network/interfaces.d/{{ '%02d' | format(item.id) }}-{{ item.name | replace('_', '-') }}"
|
||||
mode: 0644
|
||||
when: item.name in interfaces
|
||||
loop: "{{ network_interfaces.vlan }}"
|
@ -0,0 +1,55 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
{% set vlan_name = (item.name | replace('_', '-')) %}
|
||||
{% set subnet_network = (query('ldap', 'network', vlan_name) | ipaddr('network')) %}
|
||||
{% set subnet_netmask = (query('ldap', 'network', vlan_name) | ipaddr('netmask')) %}
|
||||
{% set ips = query('ldap', 'ip', ansible_hostname, vlan_name) %}
|
||||
{% if (ips | ipv4 | length) > 0 %}
|
||||
auto {{ interfaces[item.name] }}
|
||||
iface {{ interfaces[item.name] }} inet static
|
||||
{% for ip in (ips | ipv4) %}
|
||||
address {{ ip }}
|
||||
{% endfor %}
|
||||
network {{ subnet_network }}
|
||||
netmask {{ subnet_netmask }}
|
||||
{% if item.gateway is defined and item.gateway not in (ips | ipv4) %}
|
||||
gateway {{ item.gateway }}
|
||||
{% endif %}
|
||||
{% if item.metric is defined %}
|
||||
metric {{ item.metric }}
|
||||
{% endif %}
|
||||
{% if item.dns is defined %}
|
||||
dns-nameservers {{ item.dns }}
|
||||
{% endif %}
|
||||
{% if vlan_name == 'srv' %}
|
||||
dns-search ynerant.fr
|
||||
{% else %}
|
||||
dns-search {{ vlan_name }}.ynerant.fr
|
||||
{% endif %}
|
||||
up /sbin/ip link set $IFACE alias {{ vlan_name }}
|
||||
{% if ansible_local.interfaces.sup_if_4 is defined %}
|
||||
{% if interfaces[item.name] in ansible_local.interfaces.sup_if_4 %}
|
||||
{% for line in ansible_local.interfaces.sup_if_4[interfaces[item.name]] %}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if (ips | ipv6 | length) > 0 %}
|
||||
iface {{ interfaces[item.name] }} inet6 static
|
||||
{% for ip in (ips | ipv6) %}
|
||||
address {{ ip }}/64
|
||||
{% endfor %}
|
||||
{% if item.gateway_v6 is defined and item.gateway_v6 not in (ips | ipv6) %}
|
||||
gateway {{ item.gateway_v6 }}
|
||||
{% endif %}
|
||||
accept_ra 0
|
||||
{% if ansible_local.interfaces.sup_if_6 is defined %}
|
||||
{% if interfaces[item.name] in ansible_local.interfaces.sup_if_6 %}
|
||||
{% for line in ansible_local.interfaces.sup_if_6[interfaces[item.name]] %}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
10
roles/network-interfaces/templates/network/interfaces.j2
Normal file
10
roles/network-interfaces/templates/network/interfaces.j2
Normal file
@ -0,0 +1,10 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
# This file describes the network interfaces available on your system
|
||||
# and how to activate them. For more information, see interfaces(5).
|
||||
|
||||
source /etc/network/interfaces.d/*
|
||||
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
5
roles/nginx/handlers/main.yml
Normal file
5
roles/nginx/handlers/main.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Reload nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
128
roles/nginx/tasks/main.yml
Normal file
128
roles/nginx/tasks/main.yml
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
- name: Install NGINX
|
||||
apt:
|
||||
update_cache: true
|
||||
name: nginx
|
||||
register: apt_result
|
||||
retries: 3
|
||||
until: apt_result is succeeded
|
||||
|
||||
- name: Copy proxypass snippets
|
||||
template:
|
||||
src: "nginx/snippets/options-proxypass.conf.j2"
|
||||
dest: "/etc/nginx/snippets/options-proxypass.conf"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Copy SSL snippets
|
||||
template:
|
||||
src: "nginx/snippets/options-ssl.conf.j2"
|
||||
dest: "/etc/nginx/snippets/options-ssl.{{ item.name }}.conf"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
loop: "{{ nginx.ssl }}"
|
||||
|
||||
- name: Disable default site
|
||||
file:
|
||||
dest: "/etc/nginx/sites-enabled/default"
|
||||
state: absent
|
||||
|
||||
- name: Copy reverse proxy sites
|
||||
when: reverseproxy is defined
|
||||
template:
|
||||
src: "nginx/sites-available/{{ item }}.j2"
|
||||
dest: "/etc/nginx/sites-available/{{ item }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
loop:
|
||||
- reverseproxy
|
||||
- reverseproxy_redirect_dname
|
||||
- redirect
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Activate reverse proxy sites
|
||||
when: reverseproxy is defined
|
||||
file:
|
||||
src: "/etc/nginx/sites-available/{{ item }}"
|
||||
dest: "/etc/nginx/sites-enabled/{{ item }}"
|
||||
owner: root
|
||||
group: root
|
||||
state: link
|
||||
loop:
|
||||
- reverseproxy
|
||||
- reverseproxy_redirect_dname
|
||||
- redirect
|
||||
notify: Reload nginx
|
||||
ignore_errors: "{{ ansible_check_mode }}"
|
||||
|
||||
- name: Copy service nginx configuration
|
||||
when: nginx.servers is defined and nginx.servers|length > 0
|
||||
template:
|
||||
src: "nginx/sites-available/service.j2"
|
||||
dest: "/etc/nginx/sites-available/{{ nginx.service_name }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Activate local nginx service site
|
||||
when: nginx.servers is defined and nginx.servers|length > 0
|
||||
file:
|
||||
src: "/etc/nginx/sites-available/{{ nginx.service_name }}"
|
||||
dest: "/etc/nginx/sites-enabled/{{ nginx.service_name }}"
|
||||
owner: root
|
||||
group: root
|
||||
state: link
|
||||
notify: Reload nginx
|
||||
ignore_errors: "{{ ansible_check_mode }}"
|
||||
|
||||
- name: Copy 50x error page
|
||||
template:
|
||||
src: www/html/50x.html.j2
|
||||
dest: /var/www/html/50x.html
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: 0644
|
||||
|
||||
- name: Copy robots.txt file
|
||||
when: nginx.deploy_robots_file
|
||||
template:
|
||||
src: www/html/robots.txt.j2
|
||||
dest: /var/www/html/robots.txt
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: 0644
|
||||
|
||||
- name: Install passwords
|
||||
when: nginx.auth_passwd|length > 0
|
||||
template:
|
||||
src: nginx/passwd.j2
|
||||
dest: /etc/nginx/passwd
|
||||
mode: 0644
|
||||
|
||||
- name: Copy 401 error page
|
||||
when: nginx.auth_passwd|length > 0
|
||||
template:
|
||||
src: www/html/401.html.j2
|
||||
dest: /var/www/html/401.html
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: 0644
|
||||
|
||||
- name: Indicate role in motd
|
||||
template:
|
||||
src: update-motd.d/05-service.j2
|
||||
dest: /etc/update-motd.d/05-nginx
|
||||
mode: 0755
|
||||
|
||||
- name: Clean old files
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "/etc/nginx/snippets/options-ssl.conf"
|
||||
- "/var/www/custom_401.html"
|
||||
- "/var/www/robots.txt"
|
8
roles/nginx/templates/letsencrypt/dhparam.j2
Normal file
8
roles/nginx/templates/letsencrypt/dhparam.j2
Normal file
@ -0,0 +1,8 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||
-----END DH PARAMETERS-----
|
4
roles/nginx/templates/nginx/passwd.j2
Normal file
4
roles/nginx/templates/nginx/passwd.j2
Normal file
@ -0,0 +1,4 @@
|
||||
{{ ansible_header | comment }}
|
||||
{% for user, hash in nginx.auth_passwd.items() -%}
|
||||
{{ user }}:{{ hash }}
|
||||
{% endfor -%}
|
87
roles/nginx/templates/nginx/sites-available/redirect.j2
Normal file
87
roles/nginx/templates/nginx/sites-available/redirect.j2
Normal file
@ -0,0 +1,87 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
{% for site in reverseproxy.redirect_sites %}
|
||||
# Redirect http://{{ site.from }} to http://{{ site.to }}
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name {{ site.from }};
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
return 302 http://{{ site.to }}$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# Redirect https://{{ site.from }} to https://{{ site.to }}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name {{ site.from }};
|
||||
|
||||
# SSL common conf
|
||||
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
return 302 https://{{ site.to }}$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{# Also redirect for DNAMEs #}
|
||||
{% for dname in reverseproxy.redirect_dnames %}
|
||||
{% for site in reverseproxy.redirect_sites %}
|
||||
{% set from = site.from | regex_replace('crans.org', dname) %}
|
||||
{% if from != site.from %}
|
||||
# Redirect http://{{ from }} to http://{{ site.to }}
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name {{ from }};
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
return 302 http://{{ site.to }}$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# Redirect https://{{ from }} to https://{{ site.to }}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name {{ from }};
|
||||
|
||||
# SSL common conf
|
||||
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
return 302 https://{{ site.to }}$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
62
roles/nginx/templates/nginx/sites-available/reverseproxy.j2
Normal file
62
roles/nginx/templates/nginx/sites-available/reverseproxy.j2
Normal file
@ -0,0 +1,62 @@
|
||||
{{ ansible_header | comment }}
|
||||
|
||||
# Automatic Connection header for WebSocket support
|
||||
# See http://nginx.org/en/docs/http/websocket.html
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
{% for site in reverseproxy.reverseproxy_sites %}
|
||||
# Redirect http://{{ site.from }} to https://{{ site.from }}
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name {{ site.from }};
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
return 302 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# Reverse proxify https://{{ site.from }} to {% if not site.to.startswith("http") %}http://{% endif %}{{ site.to }}
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name {{ site.from }};
|
||||
|
||||
# SSL common conf
|
||||
include "/etc/nginx/snippets/options-ssl.{{ site.ssl|default(nginx.default_ssl_domain) }}.conf";
|
||||
|
||||
# Log into separate log files
|
||||
access_log /var/log/nginx/{{ site.from }}.log;
|
||||
error_log /var/log/nginx/{{ site.from }}_error.log;
|
||||
|
||||
# Keep the TCP connection open a bit for faster browsing
|
||||
keepalive_timeout 70;
|
||||
|
||||
# Custom error page
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /var/www/html;
|
||||
}
|
||||
|
||||
{% for realip in nginx.real_ip_from %}
|
||||
set_real_ip_from {{ realip }};
|
||||
{% endfor %}
|
||||
real_ip_header X-Real-Ip;
|
||||
|
||||
location / {
|
||||
proxy_pass {% if not site.to.startswith("http") %}http://{% endif %}{{ site.to }};
|
||||
include "/etc/nginx/snippets/options-proxypass.conf";
|
||||
}
|
||||
}
|
||||
|
||||
{% endfor %}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user