cloudfall 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudfall/__init__.py +19 -0
- cloudfall/__main__.py +5 -0
- cloudfall/_bundled/schemas/v1/alert-rule.schema.json +63 -0
- cloudfall/_bundled/schemas/v1/application.schema.json +60 -0
- cloudfall/_bundled/schemas/v1/artifact.schema.json +71 -0
- cloudfall/_bundled/schemas/v1/backup-receipt.schema.json +58 -0
- cloudfall/_bundled/schemas/v1/common.schema.json +115 -0
- cloudfall/_bundled/schemas/v1/component.schema.json +234 -0
- cloudfall/_bundled/schemas/v1/deployment-receipt.schema.json +53 -0
- cloudfall/_bundled/schemas/v1/domain.schema.json +208 -0
- cloudfall/_bundled/schemas/v1/environment-receipt.schema.json +55 -0
- cloudfall/_bundled/schemas/v1/logging-stack.schema.json +473 -0
- cloudfall/_bundled/schemas/v1/observed-domain.schema.json +158 -0
- cloudfall/_bundled/schemas/v1/observed-server.schema.json +627 -0
- cloudfall/_bundled/schemas/v1/operator-policy.schema.json +97 -0
- cloudfall/_bundled/schemas/v1/operator-proposal.schema.json +253 -0
- cloudfall/_bundled/schemas/v1/release-receipt.schema.json +66 -0
- cloudfall/_bundled/schemas/v1/server-type.schema.json +289 -0
- cloudfall/_bundled/schemas/v1/server.schema.json +146 -0
- cloudfall/_bundled/schemas/v1/service.schema.json +222 -0
- cloudfall/_bundled/schemas/v1/ssh-public-key.schema.json +55 -0
- cloudfall/agent_tools.py +868 -0
- cloudfall/arguments.py +92 -0
- cloudfall/audit.py +905 -0
- cloudfall/authoring.py +341 -0
- cloudfall/cli.py +1748 -0
- cloudfall/commands.py +257 -0
- cloudfall/cutover.py +370 -0
- cloudfall/dashboard.py +407 -0
- cloudfall/dashboard_server.py +201 -0
- cloudfall/domain.py +1157 -0
- cloudfall/importer.py +906 -0
- cloudfall/inventory.py +2116 -0
- cloudfall/lifecycle.py +874 -0
- cloudfall/mcp_server.py +704 -0
- cloudfall/migrate.py +730 -0
- cloudfall/observation.py +143 -0
- cloudfall/operations.py +1228 -0
- cloudfall/operator.py +1099 -0
- cloudfall/project.py +841 -0
- cloudfall/py.typed +0 -0
- cloudfall/render_api.py +338 -0
- cloudfall/resources.py +67 -0
- cloudfall/secrets.py +262 -0
- cloudfall/service_evidence.py +659 -0
- cloudfall/validation.py +1340 -0
- cloudfall-0.2.0.dist-info/METADATA +408 -0
- cloudfall-0.2.0.dist-info/RECORD +165 -0
- cloudfall-0.2.0.dist-info/WHEEL +4 -0
- cloudfall-0.2.0.dist-info/entry_points.txt +4 -0
- cloudfall-0.2.0.dist-info/licenses/LICENSE +661 -0
- cloudfall_engine/__init__.py +5 -0
- cloudfall_engine/__main__.py +5 -0
- cloudfall_engine/_bundled/ansible/ansible.cfg +7 -0
- cloudfall_engine/_bundled/ansible/playbooks/backup.yml +86 -0
- cloudfall_engine/_bundled/ansible/playbooks/baseline.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/bootstrap.yml +24 -0
- cloudfall_engine/_bundled/ansible/playbooks/data.yml +28 -0
- cloudfall_engine/_bundled/ansible/playbooks/deploy.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/domains.yml +21 -0
- cloudfall_engine/_bundled/ansible/playbooks/health.yml +31 -0
- cloudfall_engine/_bundled/ansible/playbooks/inspect.yml +15 -0
- cloudfall_engine/_bundled/ansible/playbooks/logging.yml +35 -0
- cloudfall_engine/_bundled/ansible/playbooks/restart.yml +31 -0
- cloudfall_engine/_bundled/ansible/playbooks/rollback.yml +33 -0
- cloudfall_engine/_bundled/ansible/playbooks/services.yml +37 -0
- cloudfall_engine/_bundled/ansible/playbooks/time.yml +9 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/argument_specs.yml +34 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_access/tasks/main.yml +59 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/defaults/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/argument_specs.yml +52 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/tasks/main.yml +99 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/defaults/main.yml +15 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/argument_specs.yml +36 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/tasks/main.yml +201 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/defaults/main.yml +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/argument_specs.yml +125 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health.yml +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health_gate.yml +37 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/main.yml +285 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/restart.yml +17 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/rollback.yml +52 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/templates/component.service.j2 +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/argument_specs.yml +33 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/tasks/main.yml +51 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/templates/nftables.conf.j2 +31 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/argument_specs.yml +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/tasks/main.yml +643 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/handlers/main.yml +29 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/argument_specs.yml +227 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/tasks/main.yml +487 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager-defaults.j2 +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager.yaml.j2 +33 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/grafana.ini.j2 +20 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-datasource.yml.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-systemd-override.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki.yaml.j2 +49 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/nginx-loki-gateway.conf.j2 +45 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-datasource.yml.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-defaults.j2 +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-rules.yaml.j2 +20 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus.yaml.j2 +24 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/defaults/main.yml +7 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/handlers/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/argument_specs.yml +122 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/main.yml +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/tasks/main.yml +224 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/alloy-systemd-override.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/config.alloy.j2 +127 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/defaults/main.yml +4 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/handlers/main.yml +5 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/argument_specs.yml +69 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/tasks/main.yml +212 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/templates/domain-site.conf.j2 +54 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/defaults/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/handlers/main.yml +9 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/argument_specs.yml +91 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/tasks/main.yml +295 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.sh.j2 +17 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/cloudfall.conf.j2 +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.sh.j2 +27 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/handlers/main.yml +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/argument_specs.yml +68 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/tasks/main.yml +148 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.sh.j2 +14 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/cloudfall.conf.j2 +6 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.service.j2 +11 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.sh.j2 +15 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.timer.j2 +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/defaults/main.yml +2 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/argument_specs.yml +10 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_time/tasks/main.yml +119 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/defaults/main.yml +3 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/argument_specs.yml +8 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/main.yml +13 -0
- cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/tasks/main.yml +37 -0
- cloudfall_engine/ansible_inventory.py +253 -0
- cloudfall_engine/artifact.py +258 -0
- cloudfall_engine/cli.py +273 -0
- cloudfall_engine/playbook.py +175 -0
- cloudfall_engine/py.typed +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Validate domain target and declaration
|
|
3
|
+
ansible.builtin.assert:
|
|
4
|
+
that:
|
|
5
|
+
- ansible_facts["distribution"] == "Debian"
|
|
6
|
+
- ansible_facts["service_mgr"] == "systemd"
|
|
7
|
+
- cloudfall_nginx_site_domain.proxy.server == cloudfall_server_id
|
|
8
|
+
- cloudfall_nginx_site_domain.proxy.upstream is defined
|
|
9
|
+
- cloudfall_nginx_site_domain.tls.mode in ["disabled", "required"]
|
|
10
|
+
fail_msg: >-
|
|
11
|
+
Domain deployment requires its declared Debian proxy server and a
|
|
12
|
+
declared upstream endpoint
|
|
13
|
+
|
|
14
|
+
- name: Install Nginx and Certbot
|
|
15
|
+
ansible.builtin.apt:
|
|
16
|
+
name:
|
|
17
|
+
- nginx
|
|
18
|
+
- certbot
|
|
19
|
+
state: present
|
|
20
|
+
update_cache: true
|
|
21
|
+
cache_valid_time: 3600
|
|
22
|
+
|
|
23
|
+
- name: Create the ACME challenge webroot
|
|
24
|
+
ansible.builtin.file:
|
|
25
|
+
path: "{{ cloudfall_nginx_site_acme_webroot }}"
|
|
26
|
+
state: directory
|
|
27
|
+
owner: root
|
|
28
|
+
group: root
|
|
29
|
+
mode: "0755"
|
|
30
|
+
|
|
31
|
+
- name: Inspect existing certificate material
|
|
32
|
+
ansible.builtin.stat:
|
|
33
|
+
path: >-
|
|
34
|
+
/etc/letsencrypt/live/{{
|
|
35
|
+
cloudfall_nginx_site_domain.primaryName
|
|
36
|
+
}}/fullchain.pem
|
|
37
|
+
follow: true
|
|
38
|
+
get_checksum: false
|
|
39
|
+
register: cloudfall_nginx_site_certificate
|
|
40
|
+
|
|
41
|
+
# The TLS server block references certificate files, so on a host without
|
|
42
|
+
# them the vhost first goes live HTTP-only. That serves the ACME challenge
|
|
43
|
+
# location, which is exactly what webroot issuance needs; the vhost is
|
|
44
|
+
# re-rendered with TLS after the certificate exists.
|
|
45
|
+
- name: Determine whether TLS can be enabled before issuance
|
|
46
|
+
ansible.builtin.set_fact:
|
|
47
|
+
cloudfall_nginx_site_tls_active: >-
|
|
48
|
+
{{
|
|
49
|
+
cloudfall_nginx_site_domain.tls.mode == "required"
|
|
50
|
+
and cloudfall_nginx_site_certificate.stat.exists
|
|
51
|
+
}}
|
|
52
|
+
|
|
53
|
+
- name: Render the managed virtual host
|
|
54
|
+
ansible.builtin.template:
|
|
55
|
+
src: domain-site.conf.j2
|
|
56
|
+
dest: "{{ cloudfall_nginx_site_domain.proxy.configurationPath }}"
|
|
57
|
+
owner: root
|
|
58
|
+
group: root
|
|
59
|
+
mode: "0644"
|
|
60
|
+
notify: Reload Nginx
|
|
61
|
+
|
|
62
|
+
- name: Enable the managed virtual host
|
|
63
|
+
ansible.builtin.file:
|
|
64
|
+
src: "{{ cloudfall_nginx_site_domain.proxy.configurationPath }}"
|
|
65
|
+
dest: >-
|
|
66
|
+
/etc/nginx/sites-enabled/{{
|
|
67
|
+
cloudfall_nginx_site_domain.proxy.configurationPath | basename
|
|
68
|
+
}}
|
|
69
|
+
state: link
|
|
70
|
+
notify: Reload Nginx
|
|
71
|
+
when: >-
|
|
72
|
+
cloudfall_nginx_site_domain.proxy.configurationPath.startswith(
|
|
73
|
+
'/etc/nginx/sites-available/'
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
- name: Enable Nginx
|
|
77
|
+
ansible.builtin.systemd_service:
|
|
78
|
+
name: nginx.service
|
|
79
|
+
enabled: true
|
|
80
|
+
state: started
|
|
81
|
+
|
|
82
|
+
- name: Validate the Nginx configuration before issuance
|
|
83
|
+
ansible.builtin.command:
|
|
84
|
+
argv:
|
|
85
|
+
- /usr/sbin/nginx
|
|
86
|
+
- -t
|
|
87
|
+
changed_when: false
|
|
88
|
+
when: not ansible_check_mode
|
|
89
|
+
|
|
90
|
+
- name: Serve the ACME challenge location before issuance
|
|
91
|
+
ansible.builtin.meta: flush_handlers
|
|
92
|
+
|
|
93
|
+
- name: Issue the declared certificate
|
|
94
|
+
ansible.builtin.command:
|
|
95
|
+
argv: >-
|
|
96
|
+
{{
|
|
97
|
+
[
|
|
98
|
+
'/usr/bin/certbot', 'certonly', '--webroot',
|
|
99
|
+
'--webroot-path', cloudfall_nginx_site_acme_webroot,
|
|
100
|
+
'--non-interactive', '--agree-tos',
|
|
101
|
+
'--register-unsafely-without-email',
|
|
102
|
+
'--cert-name', cloudfall_nginx_site_domain.primaryName,
|
|
103
|
+
]
|
|
104
|
+
+ (
|
|
105
|
+
[cloudfall_nginx_site_domain.primaryName]
|
|
106
|
+
+ cloudfall_nginx_site_domain.aliases
|
|
107
|
+
)
|
|
108
|
+
| map('regex_replace', '^', '--domain=')
|
|
109
|
+
| list
|
|
110
|
+
}}
|
|
111
|
+
changed_when: true
|
|
112
|
+
when:
|
|
113
|
+
- not ansible_check_mode
|
|
114
|
+
- cloudfall_nginx_site_domain.tls.mode == "required"
|
|
115
|
+
- cloudfall_nginx_site_issue_certificate
|
|
116
|
+
- not cloudfall_nginx_site_certificate.stat.exists
|
|
117
|
+
|
|
118
|
+
- name: Re-inspect certificate material after issuance
|
|
119
|
+
ansible.builtin.stat:
|
|
120
|
+
path: >-
|
|
121
|
+
/etc/letsencrypt/live/{{
|
|
122
|
+
cloudfall_nginx_site_domain.primaryName
|
|
123
|
+
}}/fullchain.pem
|
|
124
|
+
follow: true
|
|
125
|
+
get_checksum: false
|
|
126
|
+
register: cloudfall_nginx_site_certificate
|
|
127
|
+
|
|
128
|
+
- name: Determine whether TLS can be enabled
|
|
129
|
+
ansible.builtin.set_fact:
|
|
130
|
+
cloudfall_nginx_site_tls_active: >-
|
|
131
|
+
{{
|
|
132
|
+
cloudfall_nginx_site_domain.tls.mode == "required"
|
|
133
|
+
and cloudfall_nginx_site_certificate.stat.exists
|
|
134
|
+
}}
|
|
135
|
+
|
|
136
|
+
- name: Render the managed virtual host with issued material
|
|
137
|
+
ansible.builtin.template:
|
|
138
|
+
src: domain-site.conf.j2
|
|
139
|
+
dest: "{{ cloudfall_nginx_site_domain.proxy.configurationPath }}"
|
|
140
|
+
owner: root
|
|
141
|
+
group: root
|
|
142
|
+
mode: "0644"
|
|
143
|
+
notify: Reload Nginx
|
|
144
|
+
|
|
145
|
+
- name: Enable the certificate renewal timer
|
|
146
|
+
ansible.builtin.systemd_service:
|
|
147
|
+
name: certbot.timer
|
|
148
|
+
enabled: true
|
|
149
|
+
state: started
|
|
150
|
+
when: cloudfall_nginx_site_domain.tls.mode == "required"
|
|
151
|
+
|
|
152
|
+
- name: Validate the complete Nginx configuration
|
|
153
|
+
ansible.builtin.command:
|
|
154
|
+
argv:
|
|
155
|
+
- /usr/sbin/nginx
|
|
156
|
+
- -t
|
|
157
|
+
changed_when: false
|
|
158
|
+
when: not ansible_check_mode
|
|
159
|
+
|
|
160
|
+
- name: Apply the validated virtual host
|
|
161
|
+
ansible.builtin.meta: flush_handlers
|
|
162
|
+
|
|
163
|
+
- name: Hash the applied configuration for the receipt
|
|
164
|
+
ansible.builtin.stat:
|
|
165
|
+
path: "{{ cloudfall_nginx_site_domain.proxy.configurationPath }}"
|
|
166
|
+
checksum_algorithm: sha256
|
|
167
|
+
register: cloudfall_nginx_site_applied
|
|
168
|
+
when:
|
|
169
|
+
- not ansible_check_mode
|
|
170
|
+
- cloudfall_nginx_site_receipt_directory | length > 0
|
|
171
|
+
|
|
172
|
+
- name: Ensure the controller receipt directory exists
|
|
173
|
+
ansible.builtin.file:
|
|
174
|
+
path: "{{ cloudfall_nginx_site_receipt_directory }}"
|
|
175
|
+
state: directory
|
|
176
|
+
mode: "0755"
|
|
177
|
+
delegate_to: localhost
|
|
178
|
+
become: false
|
|
179
|
+
when: cloudfall_nginx_site_receipt_directory | length > 0
|
|
180
|
+
|
|
181
|
+
- name: Write the deployment receipt on the controller
|
|
182
|
+
ansible.builtin.copy:
|
|
183
|
+
content: >-
|
|
184
|
+
{{
|
|
185
|
+
{
|
|
186
|
+
'apiVersion': 'cloudfall/v1',
|
|
187
|
+
'kind': 'DeploymentReceipt',
|
|
188
|
+
'metadata': {
|
|
189
|
+
'id': cloudfall_nginx_site_domain.id,
|
|
190
|
+
'description': 'Deployment receipt written by cloudfall_nginx_site',
|
|
191
|
+
},
|
|
192
|
+
'spec': {
|
|
193
|
+
'domain': cloudfall_nginx_site_domain.id,
|
|
194
|
+
'server': cloudfall_server_id,
|
|
195
|
+
'deployedAt': ansible_facts['date_time']['iso8601'],
|
|
196
|
+
'configurationPath':
|
|
197
|
+
cloudfall_nginx_site_domain.proxy.configurationPath,
|
|
198
|
+
'configurationSha256':
|
|
199
|
+
cloudfall_nginx_site_applied.stat.checksum,
|
|
200
|
+
},
|
|
201
|
+
} | to_nice_json
|
|
202
|
+
}}
|
|
203
|
+
dest: >-
|
|
204
|
+
{{ cloudfall_nginx_site_receipt_directory }}/{{
|
|
205
|
+
cloudfall_nginx_site_domain.id
|
|
206
|
+
}}.json
|
|
207
|
+
mode: "0644"
|
|
208
|
+
delegate_to: localhost
|
|
209
|
+
become: false
|
|
210
|
+
when:
|
|
211
|
+
- not ansible_check_mode
|
|
212
|
+
- cloudfall_nginx_site_receipt_directory | length > 0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
{% set names = (
|
|
3
|
+
[cloudfall_nginx_site_domain.primaryName]
|
|
4
|
+
+ cloudfall_nginx_site_domain.aliases
|
|
5
|
+
) | join(' ') %}
|
|
6
|
+
{% set upstream_address = cloudfall_nginx_site_domain.proxy.upstream.address %}
|
|
7
|
+
{% set upstream_host = '[' ~ upstream_address ~ ']'
|
|
8
|
+
if ':' in upstream_address else upstream_address %}
|
|
9
|
+
{% macro proxy_location() %}
|
|
10
|
+
location / {
|
|
11
|
+
proxy_http_version 1.1;
|
|
12
|
+
proxy_pass http://{{ upstream_host }}:{{ cloudfall_nginx_site_domain.proxy.upstream.port }};
|
|
13
|
+
proxy_pass_request_headers on;
|
|
14
|
+
proxy_set_header Host $host;
|
|
15
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
16
|
+
proxy_set_header X-Forwarded-For $remote_addr;
|
|
17
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
18
|
+
proxy_set_header X-Forwarded-Host $host;
|
|
19
|
+
proxy_set_header X-Forwarded-Port $server_port;
|
|
20
|
+
}
|
|
21
|
+
{% endmacro %}
|
|
22
|
+
server {
|
|
23
|
+
listen 80;
|
|
24
|
+
listen [::]:80;
|
|
25
|
+
server_name {{ names }};
|
|
26
|
+
|
|
27
|
+
location /.well-known/acme-challenge/ {
|
|
28
|
+
root {{ cloudfall_nginx_site_acme_webroot }};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
{% if cloudfall_nginx_site_tls_active %}
|
|
32
|
+
location / {
|
|
33
|
+
return 301 https://$host$request_uri;
|
|
34
|
+
}
|
|
35
|
+
{% else %}
|
|
36
|
+
{{ proxy_location() -}}
|
|
37
|
+
{% endif %}
|
|
38
|
+
}
|
|
39
|
+
{% if cloudfall_nginx_site_tls_active %}
|
|
40
|
+
|
|
41
|
+
server {
|
|
42
|
+
listen 443 ssl;
|
|
43
|
+
listen [::]:443 ssl;
|
|
44
|
+
http2 on;
|
|
45
|
+
server_name {{ names }};
|
|
46
|
+
|
|
47
|
+
ssl_certificate /etc/letsencrypt/live/{{ cloudfall_nginx_site_domain.primaryName }}/fullchain.pem;
|
|
48
|
+
ssl_certificate_key /etc/letsencrypt/live/{{ cloudfall_nginx_site_domain.primaryName }}/privkey.pem;
|
|
49
|
+
ssl_protocols TLSv1.2 TLSv1.3;
|
|
50
|
+
ssl_session_tickets off;
|
|
51
|
+
|
|
52
|
+
{{ proxy_location() -}}
|
|
53
|
+
}
|
|
54
|
+
{% endif %}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
cloudfall_postgresql_metrics_role: alloy
|
|
3
|
+
cloudfall_postgresql_repository_key_url: >-
|
|
4
|
+
https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
|
5
|
+
cloudfall_postgresql_repository_key_path: /etc/apt/keyrings/postgresql.asc
|
|
6
|
+
cloudfall_postgresql_repository_url: https://apt.postgresql.org/pub/repos/apt
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
argument_specs:
|
|
3
|
+
main:
|
|
4
|
+
short_description: Converge one declared PostgreSQL service
|
|
5
|
+
options:
|
|
6
|
+
cloudfall_postgresql_service:
|
|
7
|
+
type: dict
|
|
8
|
+
required: true
|
|
9
|
+
options:
|
|
10
|
+
id:
|
|
11
|
+
type: str
|
|
12
|
+
required: true
|
|
13
|
+
serviceKind:
|
|
14
|
+
type: str
|
|
15
|
+
choices:
|
|
16
|
+
- postgresql
|
|
17
|
+
required: true
|
|
18
|
+
environment:
|
|
19
|
+
type: str
|
|
20
|
+
required: true
|
|
21
|
+
server:
|
|
22
|
+
type: str
|
|
23
|
+
required: true
|
|
24
|
+
bind:
|
|
25
|
+
type: dict
|
|
26
|
+
required: true
|
|
27
|
+
options:
|
|
28
|
+
address:
|
|
29
|
+
type: str
|
|
30
|
+
choices:
|
|
31
|
+
- 127.0.0.1
|
|
32
|
+
required: true
|
|
33
|
+
port:
|
|
34
|
+
type: int
|
|
35
|
+
required: true
|
|
36
|
+
postgresql:
|
|
37
|
+
type: dict
|
|
38
|
+
required: true
|
|
39
|
+
options:
|
|
40
|
+
majorVersion:
|
|
41
|
+
type: str
|
|
42
|
+
required: true
|
|
43
|
+
packageVersion:
|
|
44
|
+
type: str
|
|
45
|
+
databases:
|
|
46
|
+
type: list
|
|
47
|
+
elements: dict
|
|
48
|
+
required: true
|
|
49
|
+
options:
|
|
50
|
+
name:
|
|
51
|
+
type: str
|
|
52
|
+
required: true
|
|
53
|
+
application:
|
|
54
|
+
type: str
|
|
55
|
+
required: true
|
|
56
|
+
owner:
|
|
57
|
+
type: str
|
|
58
|
+
required: true
|
|
59
|
+
backup:
|
|
60
|
+
type: dict
|
|
61
|
+
required: true
|
|
62
|
+
options:
|
|
63
|
+
directory:
|
|
64
|
+
type: path
|
|
65
|
+
required: true
|
|
66
|
+
onCalendar:
|
|
67
|
+
type: str
|
|
68
|
+
required: true
|
|
69
|
+
restoreCheckOnCalendar:
|
|
70
|
+
type: str
|
|
71
|
+
retentionDays:
|
|
72
|
+
type: int
|
|
73
|
+
required: true
|
|
74
|
+
metrics:
|
|
75
|
+
type: dict
|
|
76
|
+
options:
|
|
77
|
+
enabled:
|
|
78
|
+
type: bool
|
|
79
|
+
required: true
|
|
80
|
+
cloudfall_postgresql_metrics_role:
|
|
81
|
+
type: str
|
|
82
|
+
default: alloy
|
|
83
|
+
cloudfall_postgresql_repository_key_url:
|
|
84
|
+
type: str
|
|
85
|
+
default: https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
|
86
|
+
cloudfall_postgresql_repository_key_path:
|
|
87
|
+
type: path
|
|
88
|
+
default: /etc/apt/keyrings/postgresql.asc
|
|
89
|
+
cloudfall_postgresql_repository_url:
|
|
90
|
+
type: str
|
|
91
|
+
default: https://apt.postgresql.org/pub/repos/apt
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
galaxy_info:
|
|
3
|
+
role_name: cloudfall_postgresql
|
|
4
|
+
author: Cloudfall
|
|
5
|
+
description: Install a declared loopback PostgreSQL service with backups
|
|
6
|
+
license: AGPL-3.0-or-later
|
|
7
|
+
min_ansible_version: "2.21"
|
|
8
|
+
platforms:
|
|
9
|
+
- name: Debian
|
|
10
|
+
versions:
|
|
11
|
+
- bookworm
|
|
12
|
+
- trixie
|
|
13
|
+
dependencies: []
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Validate PostgreSQL service target and declaration
|
|
3
|
+
ansible.builtin.assert:
|
|
4
|
+
that:
|
|
5
|
+
- ansible_facts["distribution"] == "Debian"
|
|
6
|
+
- ansible_facts["service_mgr"] == "systemd"
|
|
7
|
+
- cloudfall_postgresql_service.serviceKind == "postgresql"
|
|
8
|
+
- cloudfall_postgresql_service.server == cloudfall_server_id
|
|
9
|
+
- cloudfall_postgresql_service.bind.address == "127.0.0.1"
|
|
10
|
+
- cloudfall_postgresql_service.postgresql.databases | length > 0
|
|
11
|
+
fail_msg: >-
|
|
12
|
+
PostgreSQL deployment requires its declared Debian server and a
|
|
13
|
+
loopback-only bind address
|
|
14
|
+
|
|
15
|
+
- name: Validate the declared backup calendar expression
|
|
16
|
+
ansible.builtin.command:
|
|
17
|
+
argv:
|
|
18
|
+
- /usr/bin/systemd-analyze
|
|
19
|
+
- calendar
|
|
20
|
+
- "{{ cloudfall_postgresql_service.backup.onCalendar }}"
|
|
21
|
+
changed_when: false
|
|
22
|
+
|
|
23
|
+
- name: Install PostgreSQL repository prerequisites
|
|
24
|
+
ansible.builtin.apt:
|
|
25
|
+
name:
|
|
26
|
+
- ca-certificates
|
|
27
|
+
- gnupg
|
|
28
|
+
- python3-debian
|
|
29
|
+
state: present
|
|
30
|
+
update_cache: true
|
|
31
|
+
cache_valid_time: 3600
|
|
32
|
+
|
|
33
|
+
- name: Create APT keyring directory
|
|
34
|
+
ansible.builtin.file:
|
|
35
|
+
path: /etc/apt/keyrings
|
|
36
|
+
state: directory
|
|
37
|
+
owner: root
|
|
38
|
+
group: root
|
|
39
|
+
mode: "0755"
|
|
40
|
+
|
|
41
|
+
- name: Install PostgreSQL repository signing key
|
|
42
|
+
ansible.builtin.get_url:
|
|
43
|
+
url: "{{ cloudfall_postgresql_repository_key_url }}"
|
|
44
|
+
dest: "{{ cloudfall_postgresql_repository_key_path }}"
|
|
45
|
+
owner: root
|
|
46
|
+
group: root
|
|
47
|
+
mode: "0644"
|
|
48
|
+
|
|
49
|
+
- name: Configure the PGDG package repository
|
|
50
|
+
ansible.builtin.deb822_repository:
|
|
51
|
+
name: postgresql
|
|
52
|
+
types:
|
|
53
|
+
- deb
|
|
54
|
+
uris:
|
|
55
|
+
- "{{ cloudfall_postgresql_repository_url }}"
|
|
56
|
+
suites:
|
|
57
|
+
- "{{ ansible_facts['distribution_release'] }}-pgdg"
|
|
58
|
+
components:
|
|
59
|
+
- main
|
|
60
|
+
signed_by: "{{ cloudfall_postgresql_repository_key_path }}"
|
|
61
|
+
state: present
|
|
62
|
+
|
|
63
|
+
- name: Install the pinned PostgreSQL server
|
|
64
|
+
ansible.builtin.apt:
|
|
65
|
+
name: >-
|
|
66
|
+
{{
|
|
67
|
+
'postgresql-' ~ cloudfall_postgresql_service.postgresql.majorVersion
|
|
68
|
+
~ '=' ~ cloudfall_postgresql_service.postgresql.packageVersion
|
|
69
|
+
if 'packageVersion' in cloudfall_postgresql_service.postgresql
|
|
70
|
+
else 'postgresql-'
|
|
71
|
+
~ cloudfall_postgresql_service.postgresql.majorVersion
|
|
72
|
+
}}
|
|
73
|
+
state: present
|
|
74
|
+
update_cache: true
|
|
75
|
+
cache_valid_time: 3600
|
|
76
|
+
policy_rc_d: 101
|
|
77
|
+
|
|
78
|
+
- name: Install the managed cluster configuration
|
|
79
|
+
ansible.builtin.template:
|
|
80
|
+
src: cloudfall.conf.j2
|
|
81
|
+
dest: >-
|
|
82
|
+
/etc/postgresql/{{
|
|
83
|
+
cloudfall_postgresql_service.postgresql.majorVersion
|
|
84
|
+
}}/main/conf.d/cloudfall.conf
|
|
85
|
+
owner: root
|
|
86
|
+
group: postgres
|
|
87
|
+
mode: "0640"
|
|
88
|
+
notify: Restart PostgreSQL
|
|
89
|
+
|
|
90
|
+
- name: Enable and start the PostgreSQL cluster
|
|
91
|
+
ansible.builtin.systemd_service:
|
|
92
|
+
name: >-
|
|
93
|
+
postgresql@{{
|
|
94
|
+
cloudfall_postgresql_service.postgresql.majorVersion
|
|
95
|
+
}}-main.service
|
|
96
|
+
enabled: true
|
|
97
|
+
state: started
|
|
98
|
+
daemon_reload: true
|
|
99
|
+
|
|
100
|
+
- name: Apply the validated cluster configuration
|
|
101
|
+
ansible.builtin.meta: flush_handlers
|
|
102
|
+
|
|
103
|
+
- name: Wait for PostgreSQL readiness
|
|
104
|
+
ansible.builtin.command:
|
|
105
|
+
argv:
|
|
106
|
+
- /usr/bin/pg_isready
|
|
107
|
+
- --quiet
|
|
108
|
+
- --host
|
|
109
|
+
- "{{ cloudfall_postgresql_service.bind.address }}"
|
|
110
|
+
- --port
|
|
111
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
112
|
+
register: cloudfall_postgresql_readiness
|
|
113
|
+
changed_when: false
|
|
114
|
+
retries: 12
|
|
115
|
+
delay: 5
|
|
116
|
+
until: cloudfall_postgresql_readiness.rc == 0
|
|
117
|
+
when: not ansible_check_mode
|
|
118
|
+
|
|
119
|
+
- name: Read existing PostgreSQL roles
|
|
120
|
+
ansible.builtin.command:
|
|
121
|
+
argv:
|
|
122
|
+
- /usr/bin/psql
|
|
123
|
+
- --port
|
|
124
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
125
|
+
- --tuples-only
|
|
126
|
+
- --no-align
|
|
127
|
+
- --command
|
|
128
|
+
- SELECT rolname FROM pg_roles
|
|
129
|
+
become: true
|
|
130
|
+
become_user: postgres
|
|
131
|
+
register: cloudfall_postgresql_existing_roles
|
|
132
|
+
changed_when: false
|
|
133
|
+
when: not ansible_check_mode
|
|
134
|
+
|
|
135
|
+
- name: Create missing application login roles
|
|
136
|
+
ansible.builtin.command:
|
|
137
|
+
argv:
|
|
138
|
+
- /usr/bin/psql
|
|
139
|
+
- --port
|
|
140
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
141
|
+
- --command
|
|
142
|
+
- CREATE ROLE "{{ item }}" LOGIN
|
|
143
|
+
become: true
|
|
144
|
+
become_user: postgres
|
|
145
|
+
loop: >-
|
|
146
|
+
{{
|
|
147
|
+
cloudfall_postgresql_service.postgresql.databases
|
|
148
|
+
| map(attribute='owner')
|
|
149
|
+
| unique
|
|
150
|
+
| list
|
|
151
|
+
}}
|
|
152
|
+
when:
|
|
153
|
+
- not ansible_check_mode
|
|
154
|
+
- item not in cloudfall_postgresql_existing_roles.stdout_lines
|
|
155
|
+
changed_when: true
|
|
156
|
+
|
|
157
|
+
- name: Create the metrics monitoring role
|
|
158
|
+
ansible.builtin.command:
|
|
159
|
+
argv:
|
|
160
|
+
- /usr/bin/psql
|
|
161
|
+
- --port
|
|
162
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
163
|
+
- --command
|
|
164
|
+
- CREATE ROLE "{{ cloudfall_postgresql_metrics_role }}" LOGIN
|
|
165
|
+
become: true
|
|
166
|
+
become_user: postgres
|
|
167
|
+
when:
|
|
168
|
+
- not ansible_check_mode
|
|
169
|
+
- "'metrics' in cloudfall_postgresql_service"
|
|
170
|
+
- >-
|
|
171
|
+
cloudfall_postgresql_metrics_role
|
|
172
|
+
not in cloudfall_postgresql_existing_roles.stdout_lines
|
|
173
|
+
changed_when: true
|
|
174
|
+
|
|
175
|
+
- name: Grant pg_monitor to the metrics monitoring role
|
|
176
|
+
ansible.builtin.command:
|
|
177
|
+
argv:
|
|
178
|
+
- /usr/bin/psql
|
|
179
|
+
- --port
|
|
180
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
181
|
+
- --command
|
|
182
|
+
- GRANT pg_monitor TO "{{ cloudfall_postgresql_metrics_role }}"
|
|
183
|
+
become: true
|
|
184
|
+
become_user: postgres
|
|
185
|
+
when:
|
|
186
|
+
- not ansible_check_mode
|
|
187
|
+
- "'metrics' in cloudfall_postgresql_service"
|
|
188
|
+
changed_when: false
|
|
189
|
+
|
|
190
|
+
- name: Read existing PostgreSQL databases
|
|
191
|
+
ansible.builtin.command:
|
|
192
|
+
argv:
|
|
193
|
+
- /usr/bin/psql
|
|
194
|
+
- --port
|
|
195
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
196
|
+
- --tuples-only
|
|
197
|
+
- --no-align
|
|
198
|
+
- --command
|
|
199
|
+
- SELECT datname FROM pg_database
|
|
200
|
+
become: true
|
|
201
|
+
become_user: postgres
|
|
202
|
+
register: cloudfall_postgresql_existing_databases
|
|
203
|
+
changed_when: false
|
|
204
|
+
when: not ansible_check_mode
|
|
205
|
+
|
|
206
|
+
- name: Create missing application databases
|
|
207
|
+
ansible.builtin.command:
|
|
208
|
+
argv:
|
|
209
|
+
- /usr/bin/psql
|
|
210
|
+
- --port
|
|
211
|
+
- "{{ cloudfall_postgresql_service.bind.port }}"
|
|
212
|
+
- --command
|
|
213
|
+
- CREATE DATABASE "{{ item.name }}" OWNER "{{ item.owner }}"
|
|
214
|
+
become: true
|
|
215
|
+
become_user: postgres
|
|
216
|
+
loop: "{{ cloudfall_postgresql_service.postgresql.databases }}"
|
|
217
|
+
loop_control:
|
|
218
|
+
label: "{{ item.name }}"
|
|
219
|
+
when:
|
|
220
|
+
- not ansible_check_mode
|
|
221
|
+
- item.name not in cloudfall_postgresql_existing_databases.stdout_lines
|
|
222
|
+
changed_when: true
|
|
223
|
+
|
|
224
|
+
- name: Create the backup directory
|
|
225
|
+
ansible.builtin.file:
|
|
226
|
+
path: "{{ cloudfall_postgresql_service.backup.directory }}"
|
|
227
|
+
state: directory
|
|
228
|
+
owner: postgres
|
|
229
|
+
group: postgres
|
|
230
|
+
mode: "0700"
|
|
231
|
+
|
|
232
|
+
- name: Install the backup script
|
|
233
|
+
ansible.builtin.template:
|
|
234
|
+
src: backup.sh.j2
|
|
235
|
+
dest: /usr/local/sbin/cloudfall-postgresql-backup
|
|
236
|
+
owner: root
|
|
237
|
+
group: root
|
|
238
|
+
mode: "0755"
|
|
239
|
+
|
|
240
|
+
- name: Install the restore-check script
|
|
241
|
+
ansible.builtin.template:
|
|
242
|
+
src: restore-check.sh.j2
|
|
243
|
+
dest: /usr/local/sbin/cloudfall-postgresql-restore-check
|
|
244
|
+
owner: root
|
|
245
|
+
group: root
|
|
246
|
+
mode: "0755"
|
|
247
|
+
|
|
248
|
+
- name: Install the backup service unit
|
|
249
|
+
ansible.builtin.template:
|
|
250
|
+
src: backup.service.j2
|
|
251
|
+
dest: /etc/systemd/system/cloudfall-postgresql-backup.service
|
|
252
|
+
owner: root
|
|
253
|
+
group: root
|
|
254
|
+
mode: "0644"
|
|
255
|
+
|
|
256
|
+
- name: Install the backup timer unit
|
|
257
|
+
ansible.builtin.template:
|
|
258
|
+
src: backup.timer.j2
|
|
259
|
+
dest: /etc/systemd/system/cloudfall-postgresql-backup.timer
|
|
260
|
+
owner: root
|
|
261
|
+
group: root
|
|
262
|
+
mode: "0644"
|
|
263
|
+
|
|
264
|
+
- name: Enable the backup timer
|
|
265
|
+
ansible.builtin.systemd_service:
|
|
266
|
+
name: cloudfall-postgresql-backup.timer
|
|
267
|
+
enabled: true
|
|
268
|
+
state: started
|
|
269
|
+
daemon_reload: true
|
|
270
|
+
|
|
271
|
+
- name: Install the restore-drill service unit
|
|
272
|
+
ansible.builtin.template:
|
|
273
|
+
src: restore-check.service.j2
|
|
274
|
+
dest: /etc/systemd/system/cloudfall-postgresql-restore-check.service
|
|
275
|
+
owner: root
|
|
276
|
+
group: root
|
|
277
|
+
mode: "0644"
|
|
278
|
+
when: cloudfall_postgresql_service.backup.restoreCheckOnCalendar is defined
|
|
279
|
+
|
|
280
|
+
- name: Install the restore-drill timer unit
|
|
281
|
+
ansible.builtin.template:
|
|
282
|
+
src: restore-check.timer.j2
|
|
283
|
+
dest: /etc/systemd/system/cloudfall-postgresql-restore-check.timer
|
|
284
|
+
owner: root
|
|
285
|
+
group: root
|
|
286
|
+
mode: "0644"
|
|
287
|
+
when: cloudfall_postgresql_service.backup.restoreCheckOnCalendar is defined
|
|
288
|
+
|
|
289
|
+
- name: Enable the restore-drill timer
|
|
290
|
+
ansible.builtin.systemd_service:
|
|
291
|
+
name: cloudfall-postgresql-restore-check.timer
|
|
292
|
+
enabled: true
|
|
293
|
+
state: started
|
|
294
|
+
daemon_reload: true
|
|
295
|
+
when: cloudfall_postgresql_service.backup.restoreCheckOnCalendar is defined
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Managed by Cloudfall. Local changes will be overwritten.
|
|
2
|
+
[Unit]
|
|
3
|
+
Description=Cloudfall PostgreSQL backup for {{ cloudfall_postgresql_service.id }}
|
|
4
|
+
After=postgresql@{{ cloudfall_postgresql_service.postgresql.majorVersion }}-main.service
|
|
5
|
+
Requires=postgresql@{{ cloudfall_postgresql_service.postgresql.majorVersion }}-main.service
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
User=postgres
|
|
10
|
+
Group=postgres
|
|
11
|
+
ExecStart=/usr/local/sbin/cloudfall-postgresql-backup
|