Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
Dave S. | bdbca4a90e | 2 years ago |
Dave S. | ac4de942ba | 2 years ago |
Dave S. | 5ca943312c | 2 years ago |
@ -0,0 +1,3 @@ |
||||
- name: restart systemd daemons |
||||
systemd: |
||||
daemon_reload: yes |
@ -0,0 +1,18 @@ |
||||
- name: set role information |
||||
set_fact: |
||||
role_dependency_index: 0 |
||||
|
||||
role_hardware: |
||||
cores: 2 |
||||
memory: 128 |
||||
swap: 64 |
||||
disk: 0.6 |
||||
|
||||
role_use_reverse_proxy: yes |
||||
role_use_database: yes |
||||
|
||||
role_firewall_config: |
||||
filter: |
||||
input: |
||||
- { protocol: tcp, dst_port: [53], action: accept } |
||||
- { protocol: udp, dst_port: [53], action: accept } |
@ -1,8 +1,31 @@ |
||||
- name: add to backup plan |
||||
include_tasks: add.yml |
||||
when: function is defined and function == 'add' |
||||
- 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: setup backups |
||||
include_tasks: setup.yml |
||||
when: function is defined and function == 'setup' |
||||
- 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 |
@ -0,0 +1,46 @@ |
||||
caddy_user: caddy |
||||
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_conf_file: "{{ (caddy_conf_dir, 'caddy.json') | path_join }}" |
||||
|
||||
caddy_ecc384_cert: "{{ (caddy_cert_dir, 'ecc384.crt') | path_join }}" |
||||
caddy_ecc384_key: "{{ (caddy_cert_dir, 'ecc384.key') | path_join }}" |
||||
caddy_rsa2048_cert: "{{ (caddy_cert_dir, 'rsa2048.crt') | path_join }}" |
||||
caddy_rsa2048_key: "{{ (caddy_cert_dir, 'rsa2048.key') | path_join }}" |
||||
|
||||
caddy_default_plugins: [] |
||||
caddy_domains: |
||||
- "{{ host_fqdn }}" |
||||
|
||||
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,4 @@ |
||||
- name: restart caddy |
||||
service: |
||||
name: caddy |
||||
state: restarted |
@ -0,0 +1,133 @@ |
||||
- 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 |
||||
- golang |
||||
|
||||
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" |
||||
|
||||
|
||||
- name: install golang |
||||
package: |
||||
name: go |
||||
|
||||
when: ansible_distribution == 'Alpine' |
||||
|
||||
|
||||
- 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,144 @@ |
||||
- 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) }}" |
||||
|
||||
|
||||
- name: import vars for unmanaged tls |
||||
include_vars: |
||||
file: tls.yml |
||||
when: host_tls |
||||
|
||||
|
||||
- name: import reverse proxy vars |
||||
include_vars: |
||||
file: reverse_proxy.yml |
||||
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, list_merge='replace') | |
||||
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 }}" |
||||
- "{{ caddy_cert_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: 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 |
||||
|
||||
|
||||
- block: |
||||
- name: deploy certificates through lego |
||||
include_role: |
||||
name: lego |
||||
vars: |
||||
acme: |
||||
domains: "{{ caddy_domains }}" |
||||
cert: "{{ caddy_ecc384_cert }}" |
||||
key: "{{ caddy_ecc384_key }}" |
||||
owner: "{{ caddy_user }}" |
||||
group: "{{ caddy_group }}" |
||||
run_after_renew: service caddy restart |
||||
notify: restart caddy |
||||
acme2: "{{ caddy_acme_config | d({}) }}" |
||||
|
||||
when: host_tls |
||||
|
||||
|
||||
- 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: 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 }}" |
||||
- "{{ caddy_cert_dir }}" |
||||
|
||||
|
||||
- name: enable and start caddy |
||||
service: |
||||
name: caddy |
||||
enabled: yes |
||||
state: started |
@ -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="{{ (caddy_bin_dir, 'caddy') | path_join }}" |
||||
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,21 @@ |
||||
caddy_reverse_proxy_default_handler: |
||||
- handler: static_response |
||||
status_code: 404 |
||||
|
||||
caddy_reverse_proxy_config: |
||||
apps: |
||||
http: |
||||
servers: |
||||
rproxy: |
||||
listen: "{{ ['tcp4/:443', 'tcp6/:443'] if host_tls else ['tcp4/:80', 'tcp6/:80'] }}" |
||||
listener_wrappers: "{{ [{'wrapper': 'http_redirect'}, {'wrapper': 'tls'}] if host_tls else [] }}" |
||||
automatic_https: |
||||
disable: yes |
||||
tls_connection_policies: |
||||
- match: |
||||
sni: |
||||
- "{{ host_fqdn }}" |
||||
default_sni: "{{ host_fqdn }}" |
||||
routes: |
||||
- handle: "{{ (caddy_reverse_proxy_handlers | d([])) + caddy_reverse_proxy_default_handler }}" |
||||
terminal: true |
@ -0,0 +1,8 @@ |
||||
caddy_tls_config: |
||||
apps: |
||||
tls: |
||||
certificates: |
||||
load_files: |
||||
- certificate: "{{ caddy_ecc384_cert }}" |
||||
key: "{{ caddy_ecc384_key }}" |
||||
tags: "{{ caddy_domains }}" |
@ -1 +1,2 @@ |
||||
dropbear_dir: /etc/dropbear |
||||
dropbear_dir: /etc/dropbear |
||||
alpine_version: "3.17" |
@ -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 |
@ -0,0 +1,3 @@ |
||||
lego_dir: /opt/lego |
||||
lego_cert_dir: /etc/lego |
||||
lego_accounts_file: "{{ (lego_cert_dir, 'accounts.conf') | path_join }}" |
@ -0,0 +1,214 @@ |
||||
- name: fail if acme is not defined |
||||
fail: |
||||
msg: acme must be a mapping |
||||
when: acme is not mapping |
||||
|
||||
|
||||
- name: set acme_cfg |
||||
set_fact: |
||||
acme_cfg: "{{ acme_default_config | d({}) | |
||||
combine(acme_config | d({}), recursive=true) | |
||||
combine(acme2 | d({}), recursive=true) | |
||||
combine(acme, recursive=true) }}" |
||||
|
||||
|
||||
- name: determine host architecture |
||||
include_tasks: tasks/get_host_arch.yml |
||||
|
||||
|
||||
- name: create lego dirs |
||||
file: |
||||
path: "{{ item }}" |
||||
state: directory |
||||
mode: 0700 |
||||
loop: |
||||
- "{{ lego_dir }}" |
||||
- "{{ lego_cert_dir }}" |
||||
|
||||
|
||||
- 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') | path_join }}" |
||||
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 job name |
||||
set_fact: |
||||
lego_job_name: "{{ acme_cfg.domains[0] ~ '-' ~ acme_cfg.type }}" |
||||
|
||||
|
||||
- name: set initial lego facts |
||||
set_fact: |
||||
lego_must_reissue: yes |
||||
lego_renew_script: "{{ (lego_cert_dir, 'cron-' ~ lego_job_name ~ '.sh') | path_join }}" |
||||
lego_lastrun_file: "{{ (lego_cert_dir, 'lastrun-' ~ lego_job_name) | path_join }}" |
||||
|
||||
|
||||
- name: create custom renewal script file |
||||
template: |
||||
src: renewal.j2 |
||||
dest: "{{ lego_renew_script }}" |
||||
force: yes |
||||
mode: 0500 |
||||
lstrip_blocks: yes |
||||
|
||||
|
||||
- name: set lego parameters |
||||
set_fact: |
||||
lego_params: "{{ |
||||
[ |
||||
([] | zip_longest(acme_cfg.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', |
||||
'--filename ' ~ (lego_job_name | quote), |
||||
'--email ' ~ (acme_cfg.email | d(maintainer_email) | quote), |
||||
'--key-type ' ~ (acme_cfg.type | quote), |
||||
'--path ' ~ (lego_cert_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 ''), |
||||
('--renew-hook ' ~ (lego_renew_script | quote)) |
||||
] | 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: set lego command facts |
||||
set_fact: |
||||
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 }}" |
||||
|
||||
|
||||
- name: check if lastrun file exists |
||||
stat: |
||||
path: "{{ lego_lastrun_file }}" |
||||
get_checksum: no |
||||
get_mime: no |
||||
register: result |
||||
|
||||
|
||||
- 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 }}" |
||||
register: result |
||||
|
||||
when: lego_must_reissue |
||||
rescue: |
||||
- pause: |
||||
when: interactive | d(true) == 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 }}" |
||||
register: result |
||||
|
||||
|
||||
- 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: "{{ acme_cfg.notify }}" |
||||
when: acme_cfg.notify is defined |
||||
|
||||
- name: copy certificates to their intended locations |
||||
copy: |
||||
src: "{{ (lego_cert_dir, 'certificates', lego_job_name ~ '.' ~ item.src_ext) | path_join }}" |
||||
dest: "{{ item.dest }}" |
||||
remote_src: yes |
||||
mode: 0600 |
||||
owner: "{{ acme_cfg.owner | d(omit) }}" |
||||
group: "{{ acme_cfg.group | d(omit) }}" |
||||
when: item.dest != None |
||||
loop: |
||||
- { src_ext: 'crt', dest: "{{ acme_cfg.cert | d(None) }}" } |
||||
- { src_ext: 'key', dest: "{{ acme_cfg.key | d(None) }}" } |
||||
notify: "{{ acme_cfg.notify | d(omit) }}" |
||||
|
||||
when: lego_must_reissue |
||||
|
||||
|
||||
- name: configure systemd service and timer |
||||
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' |
||||
|
||||
|
||||
- name: configure crontab entry |
||||
cron: |
||||
name: "certificate renewal ({{ lego_job_name ~ ' on ' ~ acme_cfg.server }})" |
||||
job: "ACME_DNS_API_BASE={{ acme_cfg.server | quote }} ; \ |
||||
ACME_DNS_STORAGE_PATH={{ lego_accounts_file | quote }} ; \ |
||||
cd {{ lego_dir | quote }} ; \ |
||||
{{ lego_renew_command }}" |
||||
hour: "{{ 4 | random(start=1, seed=(host_name ~ lego_job_name)) }}" |
||||
minute: "{{ 59 | random(seed=(host_name ~ lego_job_name)) }}" |
||||
when: ansible_distribution == 'Alpine' |
@ -0,0 +1,22 @@ |
||||
{%- set cert_base = (lego_cert_dir, 'certificates', lego_job_name ~ '.') | path_join -%} |
||||
|
||||
|
||||
#!/bin/sh |
||||
|
||||
{{ (acme_cfg.run_before_renew ~ ' &>/dev/null') if acme_cfg.run_before_renew is defined else '' }} |
||||
|
||||
{%- if acme_cfg.cert is defined %} |
||||
cp -fpT {{ (cert_base ~ 'crt') | quote }} {{ acme_cfg.cert | quote }} |
||||
{% if acme_cfg.owner is defined -%} |
||||
chown -f {{ acme_cfg.owner ~ ((':' ~ acme_cfg.group) if acme_cfg.group is defined else '') }} {{ acme_cfg.cert | quote }} |
||||
{% endif -%} |
||||
{% endif -%} |
||||
|
||||
{% if acme_cfg.key is defined -%} |
||||
cp -fpT {{ (cert_base ~ 'key') | quote }} {{ acme_cfg.key | quote }} |
||||
{% if acme_cfg.owner is defined -%} |
||||
chown -f {{ acme_cfg.owner ~ ((':' ~ acme_cfg.group) if acme_cfg.group is defined else '') }} {{ acme_cfg.key | quote }} |
||||
{% endif -%} |
||||
{% endif -%} |
||||
|
||||
{{ (acme_cfg.run_after_renew ~ ' &>/dev/null &') if acme_cfg.run_after_renew is defined else '' }} |
@ -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,42 @@ |
||||
- 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_rproxy |
||||
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_rproxy | d([]) }}" |
||||
caddy_acme_config: "{{ rproxy_collected_configs[0].acme | 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] if host_tls else [80] }}", action: accept } |
||||
- { protocol: udp, dst_port: "{{ [80, 443] if host_tls else [80] }}", 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 |
@ -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…
Reference in new issue