feat: caddy

fix: various fixes
master
Dave S. 2 years ago
parent eb5feb1fb8
commit 5ca943312c
  1. 2
      ansible.cfg
  2. 1
      group_vars/all.yml
  3. 53
      roles/caddy/defaults/main.yml
  4. 9
      roles/caddy/handlers/main.yml
  5. 131
      roles/caddy/tasks/build_caddy.yml
  6. 41
      roles/caddy/tasks/install_prebuilt_caddy.yml
  7. 141
      roles/caddy/tasks/main.yml
  8. 19
      roles/caddy/tasks/register_acme_domain.yml
  9. 88
      roles/caddy/tasks/setup_acme_client.yml
  10. 158
      roles/caddy/tasks/setup_lego.yml
  11. 1
      roles/caddy/templates/caddy.j2
  12. 23
      roles/caddy/templates/init.j2
  13. 27
      roles/caddy/vars/reverse_proxy.yml
  14. 33
      roles/caddy/vars/tls_caddy.yml
  15. 8
      roles/caddy/vars/tls_lego.yml
  16. 6
      roles/coredns/tasks/info.yml
  17. 23
      roles/iptables/defaults/main.yml
  18. 7
      roles/iptables/tasks/main.yml
  19. 4
      roles/iptables/templates/iptables.j2
  20. 4
      roles/vault/defaults/main.yml
  21. 22
      roles/vault/tasks/main.yml
  22. 4
      roles/vault/templates/init.j2
  23. 7
      tasks/get_host_arch.yml

@ -5,6 +5,8 @@ use_persistent_connections = true
forks = 6
internal_poll_interval = 0.01
jinja2_native = true
no_target_syslog = true
verbosity = 1
[ssh_connection]
pipelining = true

@ -41,3 +41,4 @@ role_dependency_common:
- {stage: 5, role: 'mail-user'}
- {stage: 8, role: 'iptables'}
- {stage: 9, role: 'backup', function: 'setup'}

@ -0,0 +1,53 @@
caddy_user: caddy
caddy_group: caddy
caddy_conf_dir: /etc/caddy
caddy_asset_dir: /opt/caddy-assets
caddy_bin_dir: /usr/sbin
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_domains:
- "{{ host_fqdn }}"
caddy_acme_endpoint: https://acme-staging-v02.api.letsencrypt.org/directory
caddy_default_config:
admin:
disabled: yes
logging:
sink:
writer:
output: stdout
logs:
default:
writer:
output: stdout
encoder:
format: console
level: INFO
storage:
module: file_system
root: "{{ caddy_asset_dir }}"
apps:
tls:
session_tickets:
rotation_interval: 4h
max_keys: 8
cache:
capacity: 512
http:
grace_period: 20s

@ -0,0 +1,9 @@
- name: restart caddy
service:
name: caddy
state: restarted
- name: reload systemd daemons
systemd:
daemon_reload: yes

@ -0,0 +1,131 @@
- name: install xcaddy from debian/ubuntu repository
block:
- name: install dependencies
package:
name:
- debian-keyring
- debian-archive-keyring
- apt-transport-https
- name: get xcaddy signing key location
set_fact:
caddy_xcaddy_signing_key_file: "{{ (gpg_keyrings_dir, 'xcaddy.asc') | path_join }}"
- name: add xcaddy signing key
get_url:
url: "{{ caddy_xcaddy_gpg_key_url }}"
dest: "{{ caddy_xcaddy_signing_key_file }}"
mode: a+r
- name: add apt repo
apt_repository:
repo: "deb [signed-by={{ caddy_xcaddy_signing_key_file | quote }}] {{ caddy_xcaddy_repo_url }} any-version main"
register: result
- name: update repository index
apt:
force_apt_get: yes
update_cache: yes
changed_when: no
when: result.changed
- name: install xcaddy
package:
name: xcaddy
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
- name: install xcaddy from github
block:
- name: determine host architecture
include_tasks: tasks/get_host_arch.yml
- name: create xcaddy dir
file:
path: "{{ caddy_xcaddy_dir }}"
state: directory
- name: get latest xcaddy version
include_tasks: tasks/get_lastversion.yml
vars:
package:
name: caddyserver/xcaddy
location: github
file: "{{ (caddy_conf_dir, 'last_xcaddy_version') | path_join }}"
assets: yes
asset_filter: "{{ 'linux_' ~ host_architecture ~ '.tar.gz$' }}"
extract: "{{ caddy_xcaddy_dir }}"
- name: ensure xcaddy binary has executable flag set
file:
path: "{{ (caddy_xcaddy_dir, 'xcaddy') | path_join }}"
mode: "+x"
- name: copy xcaddy to bin dir
copy:
src: "{{ (caddy_xcaddy_dir, 'xcaddy') | path_join }}"
dest: "{{ (caddy_bin_dir, 'xcaddy') | path_join }}"
remote_src: yes
mode: "+x"
when: ansible_distribution == 'Alpine'
- name: install golang
package:
name: golang
- name: get latest caddy version
include_tasks: tasks/get_lastversion.yml
vars:
package:
name: caddyserver/caddy
location: github
file: "{{ (caddy_conf_dir, 'last_caddy_version') | path_join }}"
- name: generate build command
set_fact:
caddy_build_command: >-
{{
'xcaddy build ' ~ (
[] | zip_longest((caddy_default_plugins | d([])) +
(caddy_custom_plugins | d([])) | select() | map('quote'), fillvalue='--with ')
| map('join') | list | join(' ')
) ~ ' --output ' ~ ((caddy_bin_dir, 'caddy') | path_join | quote) }}
- name: save build command to a file
copy:
content: "{{ caddy_build_command }}"
dest: "{{ (caddy_conf_dir, 'build_info') | path_join }}"
mode: 0400
register: result
- name: build caddy binary if a new version is found or build command was changed
shell:
cmd: "{{ caddy_build_command }}"
chdir: "{{ caddy_bin_dir }}"
register: result
when: package_changed or result.changed
notify: restart caddy
- name: check if caddy version and last version are identical
shell:
cmd: "caddy version | cut -d ' ' -f1 | cut -b2- | diff -wq {{ (caddy_conf_dir, 'last_caddy_version') | path_join | quote }} -"
register: result
failed_when: result.rc != 0
changed_when: no

@ -0,0 +1,41 @@
- name: install caddy from debian/ubuntu repository
block:
- name: install dependencies
package:
name:
- debian-keyring
- debian-archive-keyring
- apt-transport-https
- name: get caddy signing key location
set_fact:
caddy_signing_key_file: "{{ (gpg_keyrings_dir, 'caddy.asc') | path_join }}"
- name: add caddy signing key
get_url:
url: "{{ caddy_gpg_key_url }}"
dest: "{{ caddy_signing_key_file }}"
mode: a+r
- name: add apt repo
apt_repository:
repo: "deb [signed-by={{ caddy_signing_key_file | quote }}] {{ caddy_repo_url }} any-version main"
register: result
- name: update repository index
apt:
force_apt_get: yes
update_cache: yes
changed_when: no
when: result.changed
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
- name: install caddy
package:
name: caddy

@ -0,0 +1,141 @@
- 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
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
- name: import reverse proxy vars
include_vars:
file: reverse_proxy.yml
when: caddy_has_reverse_proxy
- 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_config | d({}), recursive=true) }}"
- name: create user and group
include_tasks: tasks/create_user.yml
vars:
user:
name: "{{ caddy_user }}"
group: "{{ caddy_group }}"
dir: "{{ caddy_conf_dir }}"
create_home: no
- name: create caddy directories
file:
path: "{{ item }}"
state: directory
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
loop:
- "{{ caddy_conf_dir }}"
- "{{ caddy_asset_dir }}"
- name: create caddy bin dir
file:
path: "{{ caddy_bin_dir }}"
state: directory
- name: build caddy
include_tasks: build_caddy.yml
when: caddy_custom_build
- name: install prebuilt caddy
include_tasks: install_prebuilt_caddy.yml
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
dest: "{{ caddy_conf_file }}"
force: yes
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
mode: 0400
validate: "{{ (caddy_bin_dir, 'caddy') | path_join }} validate --config %s"
notify: restart caddy
- name: template systemd file
template:
src: systemd.j2
dest: /etc/systemd/system/caddy.service
force: yes
lstrip_blocks: yes
notify:
- reload systemd daemons
- restart caddy
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
- name: template init script
template:
src: init.j2
dest: /etc/init.d/caddy
force: yes
mode: 0755
notify: restart caddy
when: ansible_distribution == 'Alpine'
- name: change permissions on asset dir contents
file:
path: "{{ caddy_asset_dir }}"
recurse: yes
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
notify: restart caddy
- name: flush handlers
meta: flush_handlers
- name: add directories to backup plan
include_role:
name: backup
tasks_from: add.yml
vars:
backup_items:
- "{{ caddy_asset_dir }}"
- "{{ caddy_conf_dir }}"
- name: enable and start caddy
service:
name: caddy
enabled: yes
state: started

@ -0,0 +1,19 @@
- name: call acme-dns-client
expect:
command: "./acme-dns-client register -d {{ domain | quote }} -s {{ acme_dns_server | quote }}"
chdir: "{{ caddy_acmedns_client_bin_dir }}"
echo: yes
responses:
'Do you want acme-dns-client to monitor the CNAME record change?': 'n'
'Do you wish to set up a CAA record now?': 'n'
become: yes
become_method: "{{ 'su' if ansible_distribution == 'Alpine' else 'sudo' }}"
become_user: "{{ caddy_user }}"
register: result
changed_when: yes
failed_when: not ('successfully registered' in result.stdout)
- name: pause if acme-dns-client registered a new record
pause:
when: result.changed

@ -0,0 +1,88 @@
- name: determine host architecture
include_tasks: tasks/get_host_arch.yml
- name: create acme-client directory
file:
path: "{{ item }}"
state: directory
mode: 0700
owner: "{{ caddy_user }}"
group: "{{ caddy_group }}"
loop:
- "{{ caddy_acmedns_client_bin_dir }}"
- "{{ caddy_acmedns_client_dir }}"
- name: get and extract latest acme-dns-client version
include_tasks: tasks/get_lastversion.yml
vars:
package:
name: acme-dns/acme-dns-client
location: github
assets: yes
asset_filter: "{{ 'linux_' ~ host_architecture ~ '.tar.gz$' }}"
file: "{{ (caddy_acmedns_client_bin_dir, 'last_acme_client_version') | path_join }}"
extract: "{{ caddy_acmedns_client_bin_dir }}"
user: "{{ caddy_user }}"
group: "{{ caddy_group }}"
- name: ensure acme-dns-client binary has executable bit set
file:
path: "{{ (caddy_acmedns_client_bin_dir, 'acme-dns-client') | path_join }}"
mode: "+x"
- block:
- name: remove unnecessary files
file:
path: "{{ (caddy_acmedns_client_bin_dir, item) | path_join }}"
state: absent
loop:
- LICENSE
- README.md
rescue:
- meta: noop
- name: clear acme-dns-client domain fact
set_fact:
acmedns_current_domains: "{{ [] }}"
- name: check if acme-dns-client config exists
stat:
path: "{{ caddy_acmedns_client_file }}"
get_checksum: no
get_attributes: no
get_mime: no
register: result
- block:
- name: get acme-dns-client config file
slurp:
path: "{{ caddy_acmedns_client_file }}"
register: file_content
- name: set acme-dns-client domain fact
set_fact:
acmedns_current_domains: "{{ file_content.content | b64decode | from_json | dict2items | map(attribute='key') | list }}"
when: result.stat.exists
no_log: yes
- name: show domain information
debug:
msg: |
acme-dns-client currently manages these FQDNs: {{ '(none)' if acmedns_current_domains | length == 0 else acmedns_current_domains | join(', ') }}
acme-dns-client does not yet manage these FQDNs: {{ caddy_domains | difference(acmedns_current_domains) | join(', ') }}
- name: register a record with acme-dns-client for each unmanaged domain
include_tasks: register_acme_domain.yml
vars:
domain: "{{ item }}"
loop: "{{ caddy_domains | difference(acmedns_current_domains) }}"

@ -0,0 +1,158 @@
- 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

@ -0,0 +1 @@
{{ caddy_cfg | to_nice_json(indent=2) }}

@ -0,0 +1,23 @@
#!/sbin/openrc-run
: ${caddy_opts:="--config {{ caddy_conf_file | quote }}"}
name="$SVCNAME"
directory="{{ caddy_conf_dir }}"
command=/usr/sbin/caddy
command_args="run --environ $caddy_opts"
command_user="{{ caddy_user ~ ':' ~ caddy_group }}"
pidfile="/var/run/$SVCNAME.pid"
command_background=true
extra_started_commands="reload"
depend() {
need net localmount
after firewall
}
reload() {
ebegin "Reloading $SVCNAME"
su ${command_user%:*} -s /bin/sh -c "$command reload $caddy_opts"
eend $?
}

@ -0,0 +1,27 @@
caddy_reverse_proxy_config:
apps:
http:
servers:
rproxy:
listen:
- "tcp4/:443"
- "tcp6/:443"
automatic_https:
disable: "{{ caddy_use_lego }}"
tls_connection_policies:
- match:
sni:
- "{{ host_fqdn }}"
default_sni: "{{ host_fqdn }}"
routes:
- match:
- host:
- "{{ host_fqdn }}"
handle:
- handler: subroute
routes:
- handle:
- handler: reverse_proxy
upstreams:
- dial: "127.0.0.1:{{ reverse_proxy_port }}"
terminal: true

@ -0,0 +1,33 @@
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 }}"

@ -0,0 +1,8 @@
caddy_unmanaged_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 }}"
tags: "{{ caddy_domains }}"

@ -11,3 +11,9 @@
memory: 128
swap: 64
disk: 0.3
role_firewall_config:
filter:
input:
- { protocol: tcp, dst_port: [53, 443, 853], action: accept }
- { protocol: udp, dst_port: [53, 443, 853], action: accept }

@ -1,5 +1,5 @@
iptables_dir: /etc/iptables
iptables_file: "{{ iptables_dir }}/rules-save"
iptables_file: "{{ (iptables_dir, 'rules-save') | path_join }}"
iptables_mappings:
state: { module: 'state', param: 'state', upper: yes, join: ',' }
@ -20,3 +20,24 @@ iptables_mappings:
set_mss: { param: 'set-mss' }
to_source: { param: 'to-source' }
firewall_default_config:
filter:
default_policy:
input: drop
forward: drop
output: accept
input:
- { state: ['established', 'related'], action: accept }
- { state: invalid, action: drop }
- { protocol: icmp, icmp_type: 8, action: accept }
- { in_intf: lo, action: accept }
- { not_in_intf: lo, src_addr: '127.0.0.0/8', action: drop }
firewall_ssh_config:
filter:
input:
- "{{ { 'protocol': 'tcp', 'dst_port': 22, 'src_addr': admin_net | d(int_net | d('0.0.0.0/0')), 'action': 'accept' } }}"
- "{{ { 'protocol': 'tcp', 'dst_port': 22, 'src_addr': hostvars['ansible']['ansible_host'], 'action': 'accept' } if hostvars['ansible'] is defined else None }}"

@ -1,7 +1,10 @@
- block:
- name: set firewall_cfg
set_fact:
firewall_cfg: "{{ firewall_default_config | d({}) | combine(firewall | d({}), recursive=true) }}"
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 | d({}), recursive=true, list_merge='append') }}"
- name: install iptables
@ -44,4 +47,4 @@
enabled: yes
state: started
when: firewall is mapping
when: firewall is mapping or role_firewall_config is mapping or (host_firewall | d(false) == true)

@ -49,7 +49,9 @@
{% if section.key != 'default_policy' -%}
{% if section.value | type_debug == 'list' -%}
{% for rule in section.value -%}
{{ iptables_rule(section.key, rule) }}
{% if rule is mapping and rule != None -%}
{{ iptables_rule(section.key, rule) }}
{% endif -%}
{% endfor -%}
{% elif section.value is mapping -%}
{{ iptables_rule(section.key, section.value) }}

@ -14,8 +14,8 @@ vault_default_config:
rocket_port: "{{ vault_port }}"
websocket_port: "{{ vault_websocket_port }}"
org_attachment_limit: "{{ ((hardware.disk | d(10) | float) * 1024 * 1024 / 30) | int | abs }}"
user_attachment_limit: "{{ ((hardware.disk | d(10) | float) * 1024 * 1024 / 90) | int | abs }}"
org_attachment_limit: "{{ ((host_hardware.disk | d(10) | float) * 1024 * 1024 / 30) | int | abs }}"
user_attachment_limit: "{{ ((host_hardware.disk | d(10) | float) * 1024 * 1024 / 90) | int | abs }}"
database_max_conns: 4
websocket_enabled: yes

@ -7,7 +7,9 @@
- name: set vault_cfg
set_fact:
vault_cfg: "{{ vault_default_config | d({}) | combine(vault_mail_config | d({}), recursive=true) | combine(vault_config | d({}), recursive=true) }}"
vault_cfg: "{{ vault_default_config | d({}) |
combine(vault_mail_config | d({}), recursive=true) |
combine(vault_config | d({}), recursive=true) }}"
- name: install curl
@ -30,7 +32,7 @@
- name: create data directory
file:
path: "{{ vault_dir }}/data"
path: "{{ (vault_dir, 'data') | path_join }}"
state: directory
mode: 0750
owner: "{{ vault_user }}"
@ -53,7 +55,7 @@
- name: run docker-image-extract
command:
cmd: "{{ vault_extract_dir }}/docker-image-extract vaultwarden/server:alpine"
cmd: "{{ (vault_extract_dir, 'docker-image-extract') | path_join }} vaultwarden/server:alpine"
chdir: "{{ vault_extract_dir }}"
register: result
changed_when: no
@ -62,7 +64,7 @@
- name: check if output directory exists
stat:
path: "{{ vault_extract_dir }}/output"
path: "{{ (vault_extract_dir, 'output') | path_join }}"
register: result
@ -74,8 +76,8 @@
- name: move vaultwarden to vault dir
copy:
src: "{{ vault_extract_dir ~ '/output/vaultwarden' }}"
dest: "{{ vault_dir ~ '/vaultwarden' }}"
src: "{{ (vault_extract_dir, 'output', 'valutwarden') | path_join }}"
dest: "{{ (vault_dir, 'valutwarden') | path_join }}"
force: yes
remote_src: yes
owner: "{{ vault_user }}"
@ -85,14 +87,14 @@
- name: remove output directory
file:
path: "{{ vault_extract_dir }}/output"
path: "{{ (vault_extract_dir, 'output') | path_join }}"
state: absent
changed_when: no
- name: ensure vaultwarden has executable bit set
file:
path: "{{ vault_dir }}/vaultwarden"
path: "{{ (vault_dir, 'valutwarden') | path_join }}"
mode: "+x"
@ -114,7 +116,7 @@
- name: template .env file
template:
src: env.j2
dest: "{{ vault_dir }}/.env"
dest: "{{ (vault_dir, '.env') | path_join }}"
force: yes
mode: 0400
owner: "{{ vault_user }}"
@ -160,8 +162,8 @@
- name: add directories to backup plan
include_role:
name: backup
tasks_from: add.yml
vars:
function: add
backup_items:
- "{{ vault_dir }}"

@ -2,7 +2,7 @@
name="$SVCNAME"
directory="{{ vault_dir }}"
command="{{ vault_dir }}/vaultwarden"
command="{{ (vault_dir, 'vaultwarden') | path_join }}"
command_user="{{ vault_user ~ ':' ~ vault_group }}"
pidfile="/var/run/$SVCNAME.pid"
{% if vault_supervised | d(false) == true -%}
@ -14,6 +14,6 @@ command_background=true
depend() {
need net
use dns
before nginx
before nginx caddy
after postgresql mariadb
}

@ -0,0 +1,7 @@
- name: determine host architecture
set_fact:
host_architecture: "{{ [ansible_architecture] | map('extract', {
'aarch64': 'arm64',
'x86_64': 'amd64',
'i386': '386'
}) | first }}"
Loading…
Cancel
Save