parent
5ca943312c
commit
ac4de942ba
@ -0,0 +1,3 @@ |
||||
- name: restart systemd daemons |
||||
systemd: |
||||
daemon_reload: yes |
@ -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,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 |
@ -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 |
@ -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 }}" |
@ -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,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,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 |
Loading…
Reference in new issue