fix: various fixes

master
Dave S. 2 years ago
parent 5ca943312c
commit ac4de942ba
  1. 2
      all.yml
  2. 11
      group_vars/all.yml
  3. 3
      handlers/main.yml
  4. 3
      roles/acme-dns/defaults/main.yml
  5. 12
      roles/acme-dns/tasks/info.yml
  6. 43
      roles/acme-dns/tasks/main.yml
  7. 6
      roles/acme-dns/templates/init.j2
  8. 0
      roles/acme-dns/templates/rproxy_nginx.j2
  9. 39
      roles/backup/tasks/main.yml
  10. 31
      roles/backup/tasks/setup.yml
  11. 16
      roles/caddy/defaults/main.yml
  12. 5
      roles/caddy/handlers/main.yml
  13. 12
      roles/caddy/tasks/build_caddy.yml
  14. 41
      roles/caddy/tasks/main.yml
  15. 158
      roles/caddy/tasks/setup_lego.yml
  16. 2
      roles/caddy/templates/init.j2
  17. 14
      roles/caddy/vars/reverse_proxy.yml
  18. 6
      roles/caddy/vars/tls.yml
  19. 33
      roles/caddy/vars/tls_caddy.yml
  20. 1
      roles/certs/tasks/acme_dns.yml
  21. 3
      roles/common/defaults/main.yml
  22. 12
      roles/container/tasks/preconf.yml
  23. 0
      roles/coredns/tasks/install.yml
  24. 5
      roles/iptables/tasks/add.yml
  25. 1
      roles/iptables/tasks/main.yml
  26. 11
      roles/lego/defaults/main.yml
  27. 0
      roles/lego/tasks/acme-client.yml
  28. 174
      roles/lego/tasks/main.yml
  29. 4
      roles/lego/tasks/register_acme_domain.yml
  30. 1
      roles/nginx/tasks/main.yml
  31. 19
      roles/postgres/defaults/main.yml
  32. 2
      roles/postgres/tasks/add_database.yml
  33. 15
      roles/postgres/tasks/install.yml
  34. 11
      roles/postgres/tasks/integrate.yml
  35. 5
      roles/rproxy/tasks/add.yml
  36. 41
      roles/rproxy/tasks/main.yml
  37. 12
      roles/vault/tasks/info.yml
  38. 33
      roles/vault/tasks/main.yml
  39. 0
      roles/vault/templates/rproxy_nginx.j2

@ -35,7 +35,7 @@
role_deps: "{{ (([{ 'stage': 6, 'role': host_primary_role }] if role_dependency is not defined else [role_dependency]) +
([role_dependency_common] if (role_dependency_no_common | d(false) == false) else []) +
([{ 'stage': 1, 'role': 'container' }] if 'containers' in group_names else []) +
([{ 'stage': 3, 'role': 'postgres', 'function': 'integrate' }] if role_dependency_use_db | d(false) == true else [])
([{ 'stage': 3, 'role': 'postgres', 'tasks_from': 'integrate.yml' }] if role_use_database | d(false) == true else [])
) | flatten(levels=1) | sort(attribute='stage') }}"
selected_stages: "{%- if stage is defined and ((stage | string) is search(',')) -%}{{ stage | string | split(',') | list | map('int') | list }}\
{%- elif (stage is not defined) or ((stage | int) == 0) -%}{{ [1,2,3,4,5,6,7,8,9] }}\

@ -1,7 +1,6 @@
ansible_user: root
ansible_dir: /etc/ansible
ansible_key_dir: keys
alpine_version: "3.17"
mac_prefix: 02:FF
@ -39,6 +38,16 @@ role_dependency_common:
- {stage: 2, role: 'common'}
- {stage: 4, role: 'ns'}
- {stage: 5, role: 'mail-user'}
- {stage: 8, role: 'rproxy'}
- {stage: 8, role: 'iptables'}
- {stage: 9, role: 'backup', function: 'setup'}
reverse_proxy_type: caddy
acme_default_config:
endpoint_prod: https://acme-v02.api.letsencrypt.org/directory
endpoint_staging: https://acme-staging-v02.api.letsencrypt.org/directory
staging: no
resolver: 1.1.1.1
renew_at_days: 45
preferred_chain: 'ISRG Root X1'

@ -0,0 +1,3 @@
- name: restart systemd daemons
systemd:
daemon_reload: yes

@ -8,7 +8,6 @@ acme_dns_admin: "{{ maintainer_email | d('admin@' ~ (acme_tld | d(tld))) }}"
acme_dns_api_port: 8080
acme_dns_default_config:
general:
listen: ":53"
@ -34,7 +33,7 @@ acme_dns_default_config:
tls: none
use_header: no
notification_email: "{{ letsencrypt_email | d(maintainer_email) }}"
notification_email: "{{ maintainer_email }}"
corsorigins:
- "*"

@ -0,0 +1,12 @@
- name: set role information
set_fact:
role_dependency_index: 0
role_hardware:
cores: 2
memory: 128
swap: 64
disk: 0.3
role_use_reverse_proxy: yes
role_use_database: yes

@ -1,6 +1,7 @@
- name: set acme_dns_cfg
set_fact:
acme_dns_cfg: "{{ acme_dns_default_config | d({}) | combine(acme_dns_config | d({}), recursive=true) }}"
acme_dns_cfg: "{{ acme_dns_default_config | d({}) |
combine(acme_dns_config | d({}), recursive=true) }}"
- name: install dependencies
@ -27,7 +28,7 @@
location: github
assets: yes
asset_filter: 'Linux_amd64.tar.gz$'
file: "{{ acme_dns_dir }}/last_version"
file: "{{ (acme_dns_dir, 'last_version') | path_join }}"
extract: "{{ acme_dns_dir }}"
user: "{{ acme_dns_user }}"
group: "{{ acme_dns_group }}"
@ -36,7 +37,7 @@
- name: delete unnecessary files
file:
path: "{{ acme_dns_dir }}/{{ item }}"
path: "{{ (acme_dns_dir, item) | path_join }}"
state: absent
loop:
- CHANGELOG.md
@ -47,7 +48,7 @@
- name: template acme-dns config
template:
src: config.j2
dest: "{{ acme_dns_dir }}/config.cfg"
dest: "{{ (acme_dns_dir, 'config.cfg') | path_join }}"
force: yes
mode: 0400
owner: "{{ acme_dns_user }}"
@ -63,45 +64,47 @@
force: yes
mode: "+x"
notify: restart acme-dns
when: ansible_distribution == 'Alpine'
- name: ensure acme-dns binary has executable bit set
file:
path: "{{ acme_dns_dir }}/acme-dns"
path: "{{ (acme_dns_dir, 'acme-dns') | path_join }}"
mode: "+x"
- name: add cap_net_bind_service to acme-dns executable
community.general.capabilities:
path: "{{ acme_dns_dir }}/acme-dns"
path: "{{ (acme_dns_dir, 'acme-dns') | path_join }}"
capability: cap_net_bind_service+ep
changed_when: no
- name: set acme server address
set_fact:
acme_server: "http://127.0.0.1:{{ acme_dns_api_port }}"
- name: flush handlers
meta: flush_handlers
- name: install and configure nginx
- name: add reverse proxy config
include_role:
name: nginx
name: rproxy
tasks_from: add.yml
vars:
nginx:
servers:
- conf: nginx_server
certs: "{{ host_tls }}"
- name: flush handlers
meta: flush_handlers
rproxy_config:
port: "{{ acme_dns_api_port }}"
acme:
server: "http://127.0.0.1:{{ acme_dns_api_port }}"
nginx: rproxy_nginx.j2
caddy_reverse_proxy_handlers:
- handler: reverse_proxy
upstreams:
- dial: "127.0.0.1:{{ acme_dns_api_port }}"
- name: add directories to backup plan
include_role:
name: backup
tasks_from: add.yml
vars:
function: add
backup_items:
- "{{ acme_dns_dir }}"

@ -1,9 +1,9 @@
#!/sbin/openrc-run
name="$SVCNAME"
command="{{ acme_dns_dir }}/$SVCNAME"
command="{{ (acme_dns_dir, '$SVCNAME') | path_join }}"
directory="{{ acme_dns_dir }}"
command_user="{{ acme_dns_user }}:{{ acme_dns_group }}"
command_user="{{ acme_dns_user ~ ':' ~ acme_dns_group }}"
pidfile="/var/run/$SVCNAME.pid"
command_background=true
start_stop_daemon_args="--stdout-logger logger --stderr-logger logger"
@ -14,5 +14,5 @@ depend() {
}
start_pre() {
setcap 'cap_net_bind_service=+ep' {{ acme_dns_dir }}/$SVCNAME
setcap 'cap_net_bind_service=+ep' {{ (acme_dns_dir, '$SVCNAME') | path_join | quote }}
}

@ -1,8 +1,35 @@
- name: add to backup plan
include_tasks: add.yml
when: function is defined and function == 'add'
- fail:
when: function is defined
- name: setup backups
include_tasks: setup.yml
when: function is defined and function == 'setup'
- name: notify that backups are not supported
debug:
msg: backup host is missing, will not set up backups
when: services.backup is not mapping
- name: install restic with custom configuration
block:
- include_role:
name: restic
vars:
backup: "{{ backup_cfg }}"
when: services.backup is mapping and backup_cfg is mapping
- name: install restic with default configuration
block:
- include_role:
name: restic
vars:
backup:
dirs: "{{ collected_backup_dirs }}"
password: "{{ backup_password }}"
tags: automated
filter:
- "*.log"
- "node_modules"
- ".npm"
when: services.backup is mapping and backup_cfg is not defined and backup_password is defined

@ -1,31 +0,0 @@
- name: notify that backups are not supported
debug:
msg: backup host is missing, will not set up backups
when: services.backup is not mapping
- name: install restic with custom configuration
block:
- include_role:
name: restic
vars:
backup: "{{ backup_cfg }}"
when: services.backup is mapping and backup_cfg is mapping
- name: install restic with default configuration
block:
- include_role:
name: restic
vars:
backup:
dirs: "{{ collected_backup_dirs }}"
password: "{{ backup_password }}"
tags: automated
filter:
- "*.log"
- "node_modules"
- ".npm"
when: services.backup is mapping and backup_cfg is not defined and backup_password is defined

@ -4,27 +4,15 @@ caddy_group: caddy
caddy_conf_dir: /etc/caddy
caddy_asset_dir: /opt/caddy-assets
caddy_bin_dir: /usr/sbin
caddy_cert_dir: /etc/caddy/certs
caddy_xcaddy_dir: /opt/xcaddy
caddy_acmedns_client_bin_dir: /opt/acme-client
caddy_conf_file: "{{ (caddy_conf_dir, 'caddy.json') | path_join }}"
caddy_default_plugins:
- github.com/caddy-dns/acmedns
# hardcoded in acmedns_client and cannot be changed
caddy_acmedns_client_dir: /etc/acmedns
caddy_acmedns_client_file: /etc/acmedns/clientstorage.json
caddy_use_lego: no
caddy_lego_dir: /opt/lego
caddy_lego_lastrun_file: "{{ (caddy_lego_dir, 'lastrun') | path_join }}"
caddy_default_plugins: []
caddy_domains:
- "{{ host_fqdn }}"
caddy_acme_endpoint: https://acme-staging-v02.api.letsencrypt.org/directory
caddy_default_config:
admin:
disabled: yes

@ -2,8 +2,3 @@
service:
name: caddy
state: restarted
- name: reload systemd daemons
systemd:
daemon_reload: yes

@ -36,7 +36,9 @@
- name: install xcaddy
package:
name: xcaddy
name:
- xcaddy
- golang
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
@ -78,12 +80,12 @@
remote_src: yes
mode: "+x"
when: ansible_distribution == 'Alpine'
- name: install golang
package:
name: go
- name: install golang
package:
name: golang
when: ansible_distribution == 'Alpine'
- name: get latest caddy version

@ -1,32 +1,24 @@
- name: determine if custom caddy build should be used
set_fact:
caddy_custom_build: "{{ (((caddy_default_plugins | d([])) + (caddy_custom_plugins | d([]))) | length > 0) or (caddy_use_xcaddy | d(false) == true) }}"
caddy_has_reverse_proxy: "{{ reverse_proxy_port is number or reverse_proxy_port is string }}"
- name: import vars for automatic caddy tls
- name: import vars for unmanaged tls
include_vars:
file: tls_caddy.yml
when: not caddy_use_lego
- name: import vars for lego tls
include_vars:
file: tls_lego.yml
when: caddy_use_lego
file: tls.yml
- name: import reverse proxy vars
include_vars:
file: reverse_proxy.yml
when: caddy_has_reverse_proxy
when: caddy_reverse_proxy_handlers is defined
- name: set caddy_cfg
set_fact:
caddy_cfg: "{{ caddy_default_config | d({}) |
combine(caddy_tls_config | d({}), recursive=true) |
combine(caddy_reverse_proxy_config | d({}), recursive=true) |
combine(caddy_reverse_proxy_config | d({}), recursive=true, list_merge='replace') |
combine(caddy_config | d({}), recursive=true) }}"
@ -49,6 +41,7 @@
loop:
- "{{ caddy_conf_dir }}"
- "{{ caddy_asset_dir }}"
- "{{ caddy_cert_dir }}"
- name: create caddy bin dir
@ -67,16 +60,6 @@
when: not caddy_custom_build
- name: setup acme-dns-client for auto-tls
include_tasks: setup_acme_client.yml
when: not caddy_use_lego
- name: setup lego for unmanaged tls
include_tasks: setup_lego.yml
when: caddy_use_lego
- name: template caddy config
template:
src: caddy.j2
@ -120,6 +103,19 @@
notify: restart caddy
- name: deploy certificates
include_role:
name: certs
vars:
certs:
cert: "{{ (caddy_cert_dir, 'ecc384.crt') | path_join }}"
key: "{{ (caddy_cert_dir, 'ecc384.key') | path_join }}"
ecc: yes
post_hook: service caddy restart
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
- name: flush handlers
meta: flush_handlers
@ -132,6 +128,7 @@
backup_items:
- "{{ caddy_asset_dir }}"
- "{{ caddy_conf_dir }}"
- "{{ caddy_cert_dir }}"
- name: enable and start caddy

@ -1,158 +0,0 @@
- name: determine host architecture
include_tasks: tasks/get_host_arch.yml
- name: create lego working dir
file:
path: "{{ caddy_lego_dir }}"
state: directory
mode: 0700
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
- name: get and extract latest lego version
include_tasks: tasks/get_lastversion.yml
vars:
package:
name: go-acme/lego
location: github
assets: yes
asset_filter: "{{ 'linux_' ~ host_architecture ~ '.tar.gz$' }}"
file: "{{ caddy_lego_dir }}/last_version"
extract: "{{ caddy_lego_dir }}"
user: "{{ caddy_user }}"
group: "{{ caddy_group }}"
- block:
- name: remove unnecessary files
file:
path: "{{ (caddy_lego_dir, item) | path_join }}"
state: absent
loop:
- LICENSE
- CHANGELOG.md
rescue:
- meta: noop
- name: set lego parameters
set_fact:
lego_params: "{{
[
([] | zip_longest(caddy_domains | d([]) | select() | map('quote'), fillvalue='--domains ') | map('join') | list),
'--server ' ~ (acme_endpoint | quote),
'--accept-tos',
'--email ' ~ (acme_email | quote),
'--key-type ec384',
'--path ' ~ (caddy_lego_dir | quote),
'--dns acme-dns',
'--dns.resolvers 9.9.9.9',
'--dns.disable-cp'
] | flatten(levels=1) | select() | list | join(' ') }}"
lego_renewal_params: "{{
[
(('--days ' ~ (acme_renewal_days | quote)) if acme_renewal_days is defined else ''),
('--reuse-key' if acme_reuse_key | d(false) == true else ''),
('--no-random-sleep' if acme_no_random_sleep | d(true) == true else '')
] | flatten(levels=1) | select() | list | join(' ') }}"
lego_preferred_chain: "{{ '--preferred-chain ' ~ (acme_preferred_chain | quote) if acme_preferred_chain is defined else '' }}"
- name: check if lastrun file exists
stat:
path: "{{ caddy_lego_lastrun_file }}"
get_checksum: no
get_mime: no
register: result
- name: set initial reissue value
set_fact:
lego_must_reissue: yes
lego_full_command: "{{ (caddy_lego_dir, 'lego') | path_join }} {{ lego_params }} run {{ lego_preferred_chain }}"
lego_renew_command: "{{ (caddy_lego_dir, 'lego') | path_join }} {{ lego_params }} renew {{ lego_preferred_chain }} {{ lego_renewal_params }}"
- block:
- name: get lastrun file contents
slurp:
path: "{{ caddy_lego_lastrun_file }}"
register: file_content
no_log: yes
- name: set acme-dns-client domain fact
set_fact:
lego_must_reissue: "{{ (file_content.content | b64decode) != lego_full_command }}"
when: result.stat.exists
- block:
- name: issue cert with dns mode
shell:
cmd: "{{ lego_full_command }}"
chdir: "{{ caddy_lego_dir }}"
environment:
ACME_DNS_API_BASE: "{{ acme_dns_server }}"
ACME_DNS_STORAGE_PATH: "{{ (caddy_lego_dir, 'accounts.conf') | path_join }}"
register: result
become: yes
become_method: "{{ 'su' if ansible_distribution == 'Alpine' else 'sudo' }}"
become_user: "{{ caddy_user }}"
when: lego_must_reissue
rescue:
- pause:
- name: retry issuing cert with dns mode
shell:
cmd: "{{ lego_full_command }}"
chdir: "{{ caddy_lego_dir }}"
environment:
ACME_DNS_API_BASE: "{{ acme_dns_server }}"
ACME_DNS_STORAGE_PATH: "{{ (caddy_lego_dir, 'accounts.conf') | path_join }}"
register: result
become: yes
become_method: "{{ 'su' if ansible_distribution == 'Alpine' else 'sudo' }}"
become_user: "{{ caddy_user }}"
- block:
- name: save data to lastrun file
copy:
content: "{{ lego_full_command }}"
dest: "{{ caddy_lego_lastrun_file }}"
remote_src: yes
- name: defer caddy restart
debug:
msg: deferring caddy restart
changed_when: yes
notify: restart caddy
when: lego_must_reissue
- name: template systemd files
template:
src: "{{ item.src }}.j2"
dest: "/etc/systemd/system/{{ item.dst }}"
force: yes
lstrip_blocks: yes
loop:
- { src: 'lego_systemd', dst: 'lego.service' }
- { src: 'lego_timer', dst: 'lego.timer' }
notify: reload systemd daemons
- name: enable lego timer
systemd:
name: lego.timer
state: started
enabled: yes
# TODO: restart script

@ -4,7 +4,7 @@
name="$SVCNAME"
directory="{{ caddy_conf_dir }}"
command=/usr/sbin/caddy
command="{{ (caddy_bin_dir, 'caddy') | path_join }}"
command_args="run --environ $caddy_opts"
command_user="{{ caddy_user ~ ':' ~ caddy_group }}"
pidfile="/var/run/$SVCNAME.pid"

@ -1,3 +1,7 @@
caddy_reverse_proxy_default_handler:
- handler: static_response
status_code: 404
caddy_reverse_proxy_config:
apps:
http:
@ -7,7 +11,7 @@ caddy_reverse_proxy_config:
- "tcp4/:443"
- "tcp6/:443"
automatic_https:
disable: "{{ caddy_use_lego }}"
disable: yes
tls_connection_policies:
- match:
sni:
@ -17,11 +21,5 @@ caddy_reverse_proxy_config:
- match:
- host:
- "{{ host_fqdn }}"
handle:
- handler: subroute
routes:
- handle:
- handler: reverse_proxy
upstreams:
- dial: "127.0.0.1:{{ reverse_proxy_port }}"
handle: "{{ (caddy_reverse_proxy_handlers | d([])) + caddy_reverse_proxy_default_handler }}"
terminal: true

@ -1,8 +1,8 @@
caddy_unmanaged_tls_config:
caddy_tls_config:
apps:
tls:
certificates:
load_files:
- certificate: "{{ (caddy_lego_dir, 'certificates', caddy_domains[0] ~ '.crt') | path_join }}"
key: "{{ (caddy_lego_dir, 'certificates', caddy_domains[0] ~ '.key') | path_join }}"
- certificate: "{{ (caddy_cert_dir, 'certificates', caddy_domains[0] ~ '.crt') | path_join }}"
key: "{{ (caddy_cert_dir, 'certificates', caddy_domains[0] ~ '.key') | path_join }}"
tags: "{{ caddy_domains }}"

@ -1,33 +0,0 @@
caddy_auto_tls_config:
apps:
tls:
automation:
policies:
- subjects: "{{ caddy_domains }}"
issuers:
- module: acme
ca: "{{ caddy_acme_endpoint }}"
email: "{{ maintainer_email | d(None) }}"
acme_timeout: 5m
challenges:
http:
disabled: yes
tls-alpn:
disabled: yes
dns:
resolvers:
- 1.1.1.1
- 8.8.8.8
provider:
name: acmedns
config_file_path: "{{ caddy_acmedns_client_file }}"
propagation_delay: 15s
propagation_timeout: -1
preferred_chains:
root_common_name:
- ISRG Root X1
must_staple: yes
key_type: p384
renew_interval: 1h
certificates:
automate: "{{ caddy_domains }}"

@ -22,3 +22,4 @@
acme_tld: "{{ combined.tld | d(None) }}"
acme_fqdn: "{{ combined.fqdn | d(None) }}"
acme_hosts: "{{ combined.hosts | d(None) }}"
acme_server: "{{ combined.acme_server | d(None) }}"

@ -1 +1,2 @@
dropbear_dir: /etc/dropbear
dropbear_dir: /etc/dropbear
alpine_version: "3.17"

@ -13,20 +13,11 @@
- pct_command: rc-update add dropbear
chg_substr: added to runlevel
- name: install dropbear-scp if this is not an ansible controller
include_tasks: tasks/pct_command.yml
vars:
pct_command: apk add dropbear-scp
chg_substr: Installing
when: (inventory_hostname != 'ansible') and ((primary_role is not defined) or (primary_role != 'ansible'))
and alpine_version is version('3.15', '<=')
- name: install openssh-sftp-server due to openssh 9 scp deprecation
- name: install openssh-sftp-server
include_tasks: tasks/pct_command.yml
vars:
pct_command: apk add openssh-sftp-server
chg_substr: Installing
when: alpine_version is version('3.16', '>=')
- name: start dropbear
include_tasks: tasks/pct_command.yml
@ -57,7 +48,6 @@
vars:
pct_command: "sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config"
- name: start sshd
include_tasks: tasks/pct_command.yml
vars:

@ -0,0 +1,5 @@
- name: collect firewall config
set_fact:
firewall_collected_configs: "{{ firewall_collected_configs | d([]) |
combine(firewall_config, recursive=true, list_merge='append') }}"
when: firewall_config is mapping

@ -4,6 +4,7 @@
firewall_cfg: "{{ firewall_default_config | d({}) |
combine(firewall_ssh_config if (firewall_use_ssh | d(true) == true) else {}, recursive=true, list_merge='append') |
combine(role_firewall_config | d({}), recursive=true, list_merge='append') |
combine(firewall_collected_configs | d({}), recursive=true, list_merge='append') |
combine(firewall | d({}), recursive=true, list_merge='append') }}"

@ -0,0 +1,11 @@
lego_dir: /opt/lego
lego_lastrun_file: "{{ (lego_dir, 'lastrun') | path_join }}"
lego_user: root
lego_group: root
# hardcoded in acmedns_client and cannot be changed
lego_acmedns_client_dir: /etc/acmedns
lego_acmedns_client_file: /etc/acmedns/clientstorage.json
lego_acmedns_client_bin_dir: /opt/acme-client

@ -0,0 +1,174 @@
- name: set acme_cfg
set_fact:
acme_cfg: "{{ acme_default_config | d({}) |
combine(acme_config | d({}), recursive=true) }}"
- name: determine host architecture
include_tasks: tasks/get_host_arch.yml
- name: create user and group
include_tasks: tasks/create_user.yml
vars:
user:
name: "{{ lego_user }}"
group: "{{ lego_group }}"
create_home: no
- name: create lego working dir
file:
path: "{{ lego_dir }}"
state: directory
mode: 0700
- name: get and extract latest lego version
include_tasks: tasks/get_lastversion.yml
vars:
package:
name: go-acme/lego
location: github
assets: yes
asset_filter: "{{ 'linux_' ~ host_architecture ~ '.tar.gz$' }}"
file: "{{ lego_dir }}/last_version"
extract: "{{ lego_dir }}"
- block:
- name: remove unnecessary files
file:
path: "{{ (lego_dir, item) | path_join }}"
state: absent
loop:
- LICENSE
- CHANGELOG.md
rescue:
- meta: noop
- name: set lego parameters
set_fact:
lego_params: "{{
[
([] | zip_longest(acme_domains | d([]) | select() | map('quote'), fillvalue='--domains ') | map('join') | list),
'--server ' ~ ((acme_cfg.endpoint_staging if acme_cfg.staging else acme_cfg.endpoint_prod) | quote),
'--accept-tos',
'--email ' ~ (acme_cfg.email | d(maintainer_email) | quote),
'--key-type ec384',
'--path ' ~ (lego_dir | quote),
'--dns acme-dns',
'--dns.resolvers ' ~ (acme_cfg.resolver | d('1.1.1.1') | quote),
'--dns.disable-cp'
] | flatten(levels=1) | select() | list | join(' ') }}"
lego_renewal_params: "{{
[
(('--days ' ~ (acme_cfg.renew_at_days | quote)) if acme_cfg.renew_at_days is defined else ''),
('--reuse-key' if acme_cfg.reuse_key | d(false) == true else ''),
('--no-random-sleep' if acme_cfg.no_random_sleep | d(true) == true else '')
] | flatten(levels=1) | select() | list | join(' ') }}"
lego_preferred_chain: "{{ '--preferred-chain ' ~ (acme_cfg.preferred_chain | quote) if acme_cfg.preferred_chain is defined else '' }}"
- name: check if lastrun file exists
stat:
path: "{{ lego_lastrun_file }}"
get_checksum: no
get_mime: no
register: result
- name: set initial reissue value
set_fact:
lego_must_reissue: yes
lego_full_command: "{{ (lego_dir, 'lego') | path_join }} {{ lego_params }} run {{ lego_preferred_chain }}"
lego_renew_command: "{{ (lego_dir, 'lego') | path_join }} {{ lego_params }} renew {{ lego_preferred_chain }} {{ lego_renewal_params }}"
- block:
- name: get lastrun file contents
slurp:
path: "{{ lego_lastrun_file }}"
register: file_content
no_log: yes
- name: determine if cert should be reissued
set_fact:
lego_must_reissue: "{{ (file_content.content | b64decode) != lego_full_command }}"
when: result.stat.exists
- block:
- name: issue cert with dns mode
shell:
cmd: "{{ lego_full_command }}"
chdir: "{{ lego_dir }}"
environment:
ACME_DNS_API_BASE: "{{ acme_cfg.server }}"
ACME_DNS_STORAGE_PATH: "{{ lego_accounts_file | d((lego_dir, 'accounts.conf') | path_join) }}"
register: result
become: yes
become_method: "{{ 'su' if ansible_distribution == 'Alpine' else 'sudo' }}"
become_user: "{{ lego_user }}"
when: lego_must_reissue
rescue:
- pause:
when: interactive | d(false) == true
- name: retry issuing cert with dns mode
shell:
cmd: "{{ lego_full_command }}"
chdir: "{{ lego_dir }}"
environment:
ACME_DNS_API_BASE: "{{ acme_cfg.server }}"
ACME_DNS_STORAGE_PATH: "{{ lego_accounts_file | d((lego_dir, 'accounts.conf') | path_join) }}"
register: result
become: yes
become_method: "{{ 'su' if ansible_distribution == 'Alpine' else 'sudo' }}"
become_user: "{{ lego_user }}"
- block:
- name: save data to lastrun file
copy:
content: "{{ lego_full_command }}"
dest: "{{ lego_lastrun_file }}"
remote_src: yes
- name: defer service restart
debug:
msg: deferring service restart
changed_when: yes
notify: "{{ lego_notify }}"
when: lego_notify is defined
when: lego_must_reissue
- block:
- name: template systemd files
template:
src: "{{ item.src }}.j2"
dest: "{{ ('/etc/systemd/system', item.dst) | path_join }}"
force: yes
lstrip_blocks: yes
loop:
- { src: 'lego_systemd', dst: 'lego.service' }
- { src: 'lego_timer', dst: 'lego.timer' }
notify: reload systemd daemons
- name: enable lego timer
systemd:
name: lego.timer
state: started
enabled: yes
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
# TODO: restart script

@ -1,6 +1,6 @@
- name: call acme-dns-client
expect:
command: "./acme-dns-client register -d {{ domain | quote }} -s {{ acme_dns_server | quote }}"
command: "./acme-dns-client register -d {{ domain | quote }} -s {{ acme_dns_server_url | quote }}"
chdir: "{{ caddy_acmedns_client_bin_dir }}"
echo: yes
responses:
@ -16,4 +16,4 @@
- name: pause if acme-dns-client registered a new record
pause:
when: result.changed
when: result.changed and (interactive | d(true) == true)

@ -148,6 +148,7 @@
notify: restart nginx
stapling: "{{ nginx_cfg.must_staple | d(nginx_cfg.enable_stapling) | d(false) }}"
hosts: "{{ nginx_cfg.domains | d(None) }}"
acme_server: "{{ nginx_cfg.acme_server | d(None) }}"
certs:
- id: "{{ host_name ~ '-nginx-ecc' }}"
cert: "{{ nginx_cfg.conf_dir }}/tls/{{ nginx_cfg.cert_ecc_name }}.crt"

@ -1,10 +1,9 @@
postgresql_user: postgres
postgresql_group: postgres
postgresql_data_dir: /db
postgresql_data_dir: /opt/postgresql
postgresql_conf_dir: /etc/postgresql
postgresql_tls_dir: "{{ postgresql_conf_dir }}/tls"
postgresql_dhparam_file: dhparam.pem
postgresql_tls_dir: "{{ (postgresql_conf_dir, 'tls') | path_join }}"
postgresql_db: []
@ -50,9 +49,9 @@ postgresql_default_config:
log_timezone: "{{ timezone }}"
timezone: "{{ timezone }}"
shared_buffers: "{{ ((hardware.memory | d(512) | int) * (1024/2)) | int }}kB"
work_mem: "{{ ((hardware.memory | d(512) | int) * (1024/35)) | round(1, 'ceil') | int }}kB"
max_wal_size: "{{ ((hardware.disk | d(2) | float) * (1024 / 2)) | int }}MB"
shared_buffers: "{{ ((host_hardware.memory | d(512) | int) * (1024/2)) | int }}kB"
work_mem: "{{ ((host_hardware.memory | d(512) | int) * (1024/35)) | round(1, 'ceil') | int }}kB"
max_wal_size: "{{ ((host_hardware.disk | d(2) | float) * (1024 / 2)) | int }}MB"
postgresql_tls_config:
@ -61,7 +60,7 @@ postgresql_tls_config:
ssl_prefer_server_ciphers: yes
ssl_min_protocol_version: TLSv1.2
ssl_ecdh_curve: secp384r1
ssl_ca_file: "{{ postgresql_tls_dir }}/root.crt"
ssl_cert_file: "{{ postgresql_tls_dir }}/ecc384.crt"
ssl_key_file: "{{ postgresql_tls_dir }}/ecc384.key"
ssl_dh_params_file: "{{ postgresql_tls_dir ~ '/' ~ postgresql_dhparam_file }}"
ssl_ca_file: "{{ (postgresql_tls_dir, 'root.crt') | path_join }}"
ssl_cert_file: "{{ (postgresql_tls_dir, 'ecc384.crt') | path_join }}"
ssl_key_file: "{{ (postgresql_tls_dir, 'ecc384.key') | path_join }}"
ssl_dh_params_file: "{{ (postgresql_tls_dir, 'dhparam.pem') | path_join }}"

@ -56,7 +56,7 @@
- name: add line to postgres hba
community.postgresql.postgresql_pg_hba:
dest: "{{ postgresql_conf_dir }}/pg_hba.conf"
dest: "{{ (postgresql_conf_dir, 'pg_hba.conf') | path_join }}"
contype: "{{ 'host' if (database.ssl | d(false) == false) else 'hostssl' }}"
databases: "{{ database.name }}"
users: "{{ database.user }}"

@ -1,6 +1,7 @@
- name: set pg_cfg
set_fact:
pg_cfg: "{{ postgresql_default_config | d({}) | combine(postgresql_config | d({}), recursive=true) }}"
pg_cfg: "{{ postgresql_default_config | d({}) |
combine(postgresql_config | d({}), recursive=true) }}"
- name: install dependencies
@ -29,6 +30,18 @@
group: "{{ postgresql_group }}"
- block:
- name: create data directory
file:
path: "{{ postgresql_data_dir }}"
state: directory
mode: 0700
owner: "{{ postgresql_user }}"
group: "{{ postgresql_group }}"
rescue:
- meta: noop
- name: include custom config in default postgres config
lineinfile:
path: "{{ postgresql_conf_dir }}/postgresql.conf"

@ -1,19 +1,16 @@
- name: install postgres for self-hosted deployment
include_role:
name: postgres
vars:
function: install
include_tasks: install.yml
when: database_self_hosted | d(false) == true
- name: add database
include_role:
name: postgres
include_tasks:
file: add_database.yml
apply:
delegate_to: "{{ inventory_hostname if (database_self_hosted | d(false) == true) else services.db.hostname }}"
vars:
function: add_database
database:
name: "{{ database_name }}"
user: "{{ database_user }}"
pass: "{{ database_pass }}"
self_hosted: "{{ database_self_hosted | d(false) }}"

@ -0,0 +1,5 @@
- name: collect rproxy config
set_fact:
rproxy_collected_configs: "{{ (rproxy_collected_configs | d([])) +
([rproxy_config] if rproxy_config is mapping else rproxy_config) }}"
when: rproxy_config is defined and ((rproxy_config | type_debug == 'list') or rproxy_config is mapping)

@ -0,0 +1,41 @@
- block:
- name: fail if more than one reverse proxy config was collected
fail:
msg: more than one reverse proxy config was collected, this is not supported yet
when: rproxy_collected_configs | length > 1
- name: install nginx
include_role:
name: nginx
vars:
nginx:
servers:
- conf: rproxy_collected_configs[0].nginx
certs: "{{ host_tls }}"
acme_server: "{{ (rproxy_collected_configs[0].acme | d({}))['server'] | d(None) }}"
when: reverse_proxy_type == 'nginx'
- name: install caddy
include_role:
name: caddy
vars:
caddy_config: "{{ rproxy_collected_configs[0].caddy | d({}) }}"
caddy_reverse_proxy_handlers: "{{ rproxy_collected_configs[0].caddy_reverse_proxy_handlers | d([]) }}"
when: reverse_proxy_type == 'caddy'
- name: add firewall entries
include_role:
name: iptables
tasks_from: add.yml
vars:
firewall_config:
filter:
input:
- { protocol: tcp, dst_port: [80, 443], action: accept }
- { protocol: udp, dst_port: [80, 443], action: accept }
when: rproxy_collected_configs is defined and rproxy_collected_configs | length > 0
and role_use_reverse_proxy | d(true) == true

@ -0,0 +1,12 @@
- name: set role information
set_fact:
role_dependency_index: 2
role_hardware:
cores: 4
memory: 128
swap: 64
disk: 1.2
role_use_reverse_proxy: yes
role_use_database: yes

@ -76,8 +76,8 @@
- name: move vaultwarden to vault dir
copy:
src: "{{ (vault_extract_dir, 'output', 'valutwarden') | path_join }}"
dest: "{{ (vault_dir, 'valutwarden') | path_join }}"
src: "{{ (vault_extract_dir, 'output', 'vaultwarden') | path_join }}"
dest: "{{ (vault_dir, 'vaultwarden') | path_join }}"
force: yes
remote_src: yes
owner: "{{ vault_user }}"
@ -94,7 +94,7 @@
- name: ensure vaultwarden has executable bit set
file:
path: "{{ (vault_dir, 'valutwarden') | path_join }}"
path: "{{ (vault_dir, 'vaultwarden') | path_join }}"
mode: "+x"
@ -106,7 +106,7 @@
location: github
assets: yes
asset_filter: '.tar.gz$'
file: "{{ vault_dir }}/last_version"
file: "{{ (vault_dir, 'last_version') | path_join }}"
extract: "{{ vault_dir }}"
user: "{{ vault_user }}"
group: "{{ vault_group }}"
@ -132,6 +132,7 @@
force: yes
mode: "+x"
notify: restart vaultwarden
when: ansible_distribution == 'Alpine'
- name: ensure correct ownership in vault dir
@ -145,20 +146,24 @@
notify: restart vaultwarden
- name: install and configure nginx
include_role:
name: nginx
vars:
nginx:
servers:
- conf: nginx_server
certs: "{{ host_tls }}"
- name: flush handlers
meta: flush_handlers
- name: add reverse proxy config
include_role:
name: rproxy
tasks_from: add.yml
vars:
rproxy_config:
port: "{{ vault_port }}"
nginx: rproxy_nginx.j2
caddy_reverse_proxy_handlers:
- handler: reverse_proxy
upstreams:
- dial: "127.0.0.1:{{ vault_port }}"
- name: add directories to backup plan
include_role:
name: backup

Loading…
Cancel
Save