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.
Files changed (165) hide show
  1. cloudfall/__init__.py +19 -0
  2. cloudfall/__main__.py +5 -0
  3. cloudfall/_bundled/schemas/v1/alert-rule.schema.json +63 -0
  4. cloudfall/_bundled/schemas/v1/application.schema.json +60 -0
  5. cloudfall/_bundled/schemas/v1/artifact.schema.json +71 -0
  6. cloudfall/_bundled/schemas/v1/backup-receipt.schema.json +58 -0
  7. cloudfall/_bundled/schemas/v1/common.schema.json +115 -0
  8. cloudfall/_bundled/schemas/v1/component.schema.json +234 -0
  9. cloudfall/_bundled/schemas/v1/deployment-receipt.schema.json +53 -0
  10. cloudfall/_bundled/schemas/v1/domain.schema.json +208 -0
  11. cloudfall/_bundled/schemas/v1/environment-receipt.schema.json +55 -0
  12. cloudfall/_bundled/schemas/v1/logging-stack.schema.json +473 -0
  13. cloudfall/_bundled/schemas/v1/observed-domain.schema.json +158 -0
  14. cloudfall/_bundled/schemas/v1/observed-server.schema.json +627 -0
  15. cloudfall/_bundled/schemas/v1/operator-policy.schema.json +97 -0
  16. cloudfall/_bundled/schemas/v1/operator-proposal.schema.json +253 -0
  17. cloudfall/_bundled/schemas/v1/release-receipt.schema.json +66 -0
  18. cloudfall/_bundled/schemas/v1/server-type.schema.json +289 -0
  19. cloudfall/_bundled/schemas/v1/server.schema.json +146 -0
  20. cloudfall/_bundled/schemas/v1/service.schema.json +222 -0
  21. cloudfall/_bundled/schemas/v1/ssh-public-key.schema.json +55 -0
  22. cloudfall/agent_tools.py +868 -0
  23. cloudfall/arguments.py +92 -0
  24. cloudfall/audit.py +905 -0
  25. cloudfall/authoring.py +341 -0
  26. cloudfall/cli.py +1748 -0
  27. cloudfall/commands.py +257 -0
  28. cloudfall/cutover.py +370 -0
  29. cloudfall/dashboard.py +407 -0
  30. cloudfall/dashboard_server.py +201 -0
  31. cloudfall/domain.py +1157 -0
  32. cloudfall/importer.py +906 -0
  33. cloudfall/inventory.py +2116 -0
  34. cloudfall/lifecycle.py +874 -0
  35. cloudfall/mcp_server.py +704 -0
  36. cloudfall/migrate.py +730 -0
  37. cloudfall/observation.py +143 -0
  38. cloudfall/operations.py +1228 -0
  39. cloudfall/operator.py +1099 -0
  40. cloudfall/project.py +841 -0
  41. cloudfall/py.typed +0 -0
  42. cloudfall/render_api.py +338 -0
  43. cloudfall/resources.py +67 -0
  44. cloudfall/secrets.py +262 -0
  45. cloudfall/service_evidence.py +659 -0
  46. cloudfall/validation.py +1340 -0
  47. cloudfall-0.2.0.dist-info/METADATA +408 -0
  48. cloudfall-0.2.0.dist-info/RECORD +165 -0
  49. cloudfall-0.2.0.dist-info/WHEEL +4 -0
  50. cloudfall-0.2.0.dist-info/entry_points.txt +4 -0
  51. cloudfall-0.2.0.dist-info/licenses/LICENSE +661 -0
  52. cloudfall_engine/__init__.py +5 -0
  53. cloudfall_engine/__main__.py +5 -0
  54. cloudfall_engine/_bundled/ansible/ansible.cfg +7 -0
  55. cloudfall_engine/_bundled/ansible/playbooks/backup.yml +86 -0
  56. cloudfall_engine/_bundled/ansible/playbooks/baseline.yml +35 -0
  57. cloudfall_engine/_bundled/ansible/playbooks/bootstrap.yml +24 -0
  58. cloudfall_engine/_bundled/ansible/playbooks/data.yml +28 -0
  59. cloudfall_engine/_bundled/ansible/playbooks/deploy.yml +35 -0
  60. cloudfall_engine/_bundled/ansible/playbooks/domains.yml +21 -0
  61. cloudfall_engine/_bundled/ansible/playbooks/health.yml +31 -0
  62. cloudfall_engine/_bundled/ansible/playbooks/inspect.yml +15 -0
  63. cloudfall_engine/_bundled/ansible/playbooks/logging.yml +35 -0
  64. cloudfall_engine/_bundled/ansible/playbooks/restart.yml +31 -0
  65. cloudfall_engine/_bundled/ansible/playbooks/rollback.yml +33 -0
  66. cloudfall_engine/_bundled/ansible/playbooks/services.yml +37 -0
  67. cloudfall_engine/_bundled/ansible/playbooks/time.yml +9 -0
  68. cloudfall_engine/_bundled/ansible/roles/cloudfall_access/defaults/main.yml +2 -0
  69. cloudfall_engine/_bundled/ansible/roles/cloudfall_access/handlers/main.yml +5 -0
  70. cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/argument_specs.yml +34 -0
  71. cloudfall_engine/_bundled/ansible/roles/cloudfall_access/meta/main.yml +13 -0
  72. cloudfall_engine/_bundled/ansible/roles/cloudfall_access/tasks/main.yml +59 -0
  73. cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/defaults/main.yml +11 -0
  74. cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/argument_specs.yml +52 -0
  75. cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/meta/main.yml +13 -0
  76. cloudfall_engine/_bundled/ansible/roles/cloudfall_bootstrap/tasks/main.yml +99 -0
  77. cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/defaults/main.yml +15 -0
  78. cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/argument_specs.yml +36 -0
  79. cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/meta/main.yml +13 -0
  80. cloudfall_engine/_bundled/ansible/roles/cloudfall_data_migration/tasks/main.yml +201 -0
  81. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/defaults/main.yml +10 -0
  82. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/argument_specs.yml +125 -0
  83. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/meta/main.yml +13 -0
  84. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health.yml +3 -0
  85. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/health_gate.yml +37 -0
  86. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/main.yml +285 -0
  87. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/restart.yml +17 -0
  88. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/tasks/rollback.yml +52 -0
  89. cloudfall_engine/_bundled/ansible/roles/cloudfall_deploy/templates/component.service.j2 +24 -0
  90. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/defaults/main.yml +2 -0
  91. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/handlers/main.yml +5 -0
  92. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/argument_specs.yml +33 -0
  93. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/meta/main.yml +13 -0
  94. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/tasks/main.yml +51 -0
  95. cloudfall_engine/_bundled/ansible/roles/cloudfall_firewall/templates/nftables.conf.j2 +31 -0
  96. cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/defaults/main.yml +6 -0
  97. cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/argument_specs.yml +24 -0
  98. cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/meta/main.yml +13 -0
  99. cloudfall_engine/_bundled/ansible/roles/cloudfall_inspect/tasks/main.yml +643 -0
  100. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/defaults/main.yml +6 -0
  101. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/handlers/main.yml +29 -0
  102. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/argument_specs.yml +227 -0
  103. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/meta/main.yml +11 -0
  104. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/tasks/main.yml +487 -0
  105. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager-defaults.j2 +2 -0
  106. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/alertmanager.yaml.j2 +33 -0
  107. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/grafana.ini.j2 +20 -0
  108. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-datasource.yml.j2 +11 -0
  109. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki-systemd-override.conf.j2 +3 -0
  110. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/loki.yaml.j2 +49 -0
  111. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/nginx-loki-gateway.conf.j2 +45 -0
  112. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-datasource.yml.j2 +11 -0
  113. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-defaults.j2 +2 -0
  114. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus-rules.yaml.j2 +20 -0
  115. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_backend/templates/prometheus.yaml.j2 +24 -0
  116. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/defaults/main.yml +7 -0
  117. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/handlers/main.yml +6 -0
  118. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/argument_specs.yml +122 -0
  119. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/meta/main.yml +11 -0
  120. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/tasks/main.yml +224 -0
  121. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/alloy-systemd-override.conf.j2 +3 -0
  122. cloudfall_engine/_bundled/ansible/roles/cloudfall_logging_collector/templates/config.alloy.j2 +127 -0
  123. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/defaults/main.yml +4 -0
  124. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/handlers/main.yml +5 -0
  125. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/argument_specs.yml +69 -0
  126. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/meta/main.yml +13 -0
  127. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/tasks/main.yml +212 -0
  128. cloudfall_engine/_bundled/ansible/roles/cloudfall_nginx_site/templates/domain-site.conf.j2 +54 -0
  129. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/defaults/main.yml +6 -0
  130. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/handlers/main.yml +9 -0
  131. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/argument_specs.yml +91 -0
  132. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/meta/main.yml +13 -0
  133. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/tasks/main.yml +295 -0
  134. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.service.j2 +11 -0
  135. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.sh.j2 +17 -0
  136. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/backup.timer.j2 +10 -0
  137. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/cloudfall.conf.j2 +3 -0
  138. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2 +11 -0
  139. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.sh.j2 +27 -0
  140. cloudfall_engine/_bundled/ansible/roles/cloudfall_postgresql/templates/restore-check.timer.j2 +10 -0
  141. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/defaults/main.yml +2 -0
  142. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/handlers/main.yml +6 -0
  143. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/argument_specs.yml +68 -0
  144. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/meta/main.yml +13 -0
  145. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/tasks/main.yml +148 -0
  146. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.service.j2 +11 -0
  147. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.sh.j2 +14 -0
  148. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/backup.timer.j2 +10 -0
  149. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/cloudfall.conf.j2 +6 -0
  150. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.service.j2 +11 -0
  151. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.sh.j2 +15 -0
  152. cloudfall_engine/_bundled/ansible/roles/cloudfall_redis/templates/restore-check.timer.j2 +10 -0
  153. cloudfall_engine/_bundled/ansible/roles/cloudfall_time/defaults/main.yml +2 -0
  154. cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/argument_specs.yml +10 -0
  155. cloudfall_engine/_bundled/ansible/roles/cloudfall_time/meta/main.yml +13 -0
  156. cloudfall_engine/_bundled/ansible/roles/cloudfall_time/tasks/main.yml +119 -0
  157. cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/defaults/main.yml +3 -0
  158. cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/argument_specs.yml +8 -0
  159. cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/meta/main.yml +13 -0
  160. cloudfall_engine/_bundled/ansible/roles/cloudfall_unattended_upgrades/tasks/main.yml +37 -0
  161. cloudfall_engine/ansible_inventory.py +253 -0
  162. cloudfall_engine/artifact.py +258 -0
  163. cloudfall_engine/cli.py +273 -0
  164. cloudfall_engine/playbook.py +175 -0
  165. cloudfall_engine/py.typed +0 -0
@@ -0,0 +1,7 @@
1
+ [defaults]
2
+ roles_path = ./roles
3
+ retry_files_enabled = False
4
+ interpreter_python = auto_silent
5
+
6
+ [ssh_connection]
7
+ pipelining = True
@@ -0,0 +1,86 @@
1
+ ---
2
+ - name: Run one declared backup operation with a controller receipt
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ tasks:
9
+ - name: Select the requested service on this host
10
+ ansible.builtin.set_fact:
11
+ cloudfall_backup_matched: >-
12
+ {{
13
+ cloudfall_services | default([])
14
+ | selectattr('id', 'equalto', cloudfall_backup_service)
15
+ | list
16
+ }}
17
+
18
+ - name: Execute the requested backup action as the service user
19
+ ansible.builtin.command:
20
+ argv:
21
+ - >-
22
+ /usr/local/sbin/cloudfall-{{ cloudfall_backup_item.serviceKind
23
+ }}-{{
24
+ 'backup'
25
+ if cloudfall_backup_action == 'backup'
26
+ else 'restore-check'
27
+ }}
28
+ become: true
29
+ become_user: >-
30
+ {{
31
+ 'postgres'
32
+ if cloudfall_backup_item.serviceKind == 'postgresql'
33
+ else 'redis'
34
+ }}
35
+ loop: "{{ cloudfall_backup_matched }}"
36
+ loop_control:
37
+ loop_var: cloudfall_backup_item
38
+ label: "{{ cloudfall_backup_item.id }}"
39
+ register: cloudfall_backup_execution
40
+ changed_when: cloudfall_backup_action == 'backup'
41
+
42
+ - name: Ensure the controller receipt directory exists
43
+ ansible.builtin.file:
44
+ path: "{{ cloudfall_backup_receipt_directory }}"
45
+ state: directory
46
+ mode: "0755"
47
+ delegate_to: localhost
48
+ become: false
49
+ when: cloudfall_backup_matched | length > 0
50
+
51
+ - name: Write the backup receipt on the controller
52
+ ansible.builtin.copy:
53
+ content: >-
54
+ {{
55
+ {
56
+ 'apiVersion': 'cloudfall/v1',
57
+ 'kind': 'BackupReceipt',
58
+ 'metadata': {
59
+ 'id': cloudfall_backup_result.cloudfall_backup_item.id
60
+ ~ '-' ~ cloudfall_backup_action,
61
+ 'description':
62
+ 'Backup operation receipt written by backup.yml',
63
+ },
64
+ 'spec': {
65
+ 'service': cloudfall_backup_result.cloudfall_backup_item.id,
66
+ 'server': cloudfall_server_id,
67
+ 'action': cloudfall_backup_action,
68
+ 'executedAt': ansible_facts['date_time']['iso8601'],
69
+ 'summary': (
70
+ (cloudfall_backup_result.stdout_lines | default([]))[-5:]
71
+ | join(' | ')
72
+ )[:2000] or 'completed',
73
+ },
74
+ } | to_nice_json
75
+ }}
76
+ dest: >-
77
+ {{ cloudfall_backup_receipt_directory }}/{{
78
+ cloudfall_backup_result.cloudfall_backup_item.id
79
+ }}-{{ cloudfall_backup_action }}.json
80
+ mode: "0644"
81
+ delegate_to: localhost
82
+ become: false
83
+ loop: "{{ cloudfall_backup_execution.results | default([]) }}"
84
+ loop_control:
85
+ loop_var: cloudfall_backup_result
86
+ label: "{{ cloudfall_backup_result.cloudfall_backup_item.id }}"
@@ -0,0 +1,35 @@
1
+ ---
2
+ - name: Converge Cloudfall servers to the managed baseline
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ vars:
9
+ cloudfall_bootstrap_component_keys:
10
+ - id
11
+ - install_root
12
+ - application
13
+ - application_user
14
+ roles:
15
+ - role: cloudfall_bootstrap
16
+ cloudfall_bootstrap_applications: "{{ cloudfall_applications }}"
17
+ cloudfall_bootstrap_components: >-
18
+ {{
19
+ cloudfall_components
20
+ | map('dict2items')
21
+ | map('selectattr', 'key', 'in', cloudfall_bootstrap_component_keys)
22
+ | map('items2dict')
23
+ | list
24
+ }}
25
+ - role: cloudfall_time
26
+ - role: cloudfall_access
27
+ cloudfall_access_ssh_public_keys: "{{ cloudfall_ssh_public_keys }}"
28
+ - role: cloudfall_unattended_upgrades
29
+ tasks:
30
+ - name: Enforce the declared firewall
31
+ ansible.builtin.include_role:
32
+ name: cloudfall_firewall
33
+ vars:
34
+ cloudfall_firewall_ruleset: "{{ cloudfall_firewall }}"
35
+ when: cloudfall_firewall is defined
@@ -0,0 +1,24 @@
1
+ ---
2
+ - name: Bootstrap Cloudfall application servers
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ vars:
9
+ cloudfall_bootstrap_component_keys:
10
+ - id
11
+ - install_root
12
+ - application
13
+ - application_user
14
+ roles:
15
+ - role: cloudfall_bootstrap
16
+ cloudfall_bootstrap_applications: "{{ cloudfall_applications }}"
17
+ cloudfall_bootstrap_components: >-
18
+ {{
19
+ cloudfall_components
20
+ | map('dict2items')
21
+ | map('selectattr', 'key', 'in', cloudfall_bootstrap_component_keys)
22
+ | map('items2dict')
23
+ | list
24
+ }}
@@ -0,0 +1,28 @@
1
+ ---
2
+ - name: Migrate external data into declared Cloudfall services
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ tasks:
9
+ - name: Migrate data into the selected PostgreSQL service
10
+ ansible.builtin.include_role:
11
+ name: cloudfall_data_migration
12
+ vars:
13
+ cloudfall_data_migration_service: "{{ cloudfall_data_service_item }}"
14
+ cloudfall_data_migration_database: "{{ cloudfall_data_database }}"
15
+ cloudfall_data_migration_source_url_file: >-
16
+ {{ cloudfall_data_source_url_file }}
17
+ cloudfall_data_migration_receipt_directory: >-
18
+ {{ cloudfall_data_receipt_directory | default("") }}
19
+ loop: >-
20
+ {{
21
+ cloudfall_services | default([])
22
+ | selectattr('serviceKind', 'equalto', 'postgresql')
23
+ | selectattr('id', 'equalto', cloudfall_data_service_id)
24
+ | list
25
+ }}
26
+ loop_control:
27
+ loop_var: cloudfall_data_service_item
28
+ label: "{{ cloudfall_data_service_item.id }}"
@@ -0,0 +1,35 @@
1
+ ---
2
+ - name: Deploy one Cloudfall component release
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ pre_tasks:
9
+ - name: Require an explicit component and release selection
10
+ ansible.builtin.assert:
11
+ that:
12
+ - cloudfall_deploy_component_id is defined
13
+ - cloudfall_deploy_release is defined
14
+ - cloudfall_deploy_artifact_archive is defined
15
+ - cloudfall_deploy_artifact_sha256 is defined
16
+ fail_msg: >-
17
+ Deployment requires cloudfall_deploy_component_id,
18
+ cloudfall_deploy_release, cloudfall_deploy_artifact_archive, and
19
+ cloudfall_deploy_artifact_sha256 extra variables
20
+ run_once: true
21
+ tasks:
22
+ - name: Deploy the selected component on its declared servers
23
+ ansible.builtin.include_role:
24
+ name: cloudfall_deploy
25
+ vars:
26
+ cloudfall_deploy_component: "{{ cloudfall_component_item }}"
27
+ loop: >-
28
+ {{
29
+ cloudfall_components | default([])
30
+ | selectattr('id', 'equalto', cloudfall_deploy_component_id)
31
+ | list
32
+ }}
33
+ loop_control:
34
+ loop_var: cloudfall_component_item
35
+ label: "{{ cloudfall_component_item.id }}"
@@ -0,0 +1,21 @@
1
+ ---
2
+ - name: Deploy declared Cloudfall public domain routes
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ tasks:
9
+ - name: Render declared domains as managed virtual hosts
10
+ ansible.builtin.include_role:
11
+ name: cloudfall_nginx_site
12
+ vars:
13
+ cloudfall_nginx_site_domain: "{{ cloudfall_domain_item }}"
14
+ cloudfall_nginx_site_issue_certificate: >-
15
+ {{ cloudfall_domains_issue_certificates | default(false) | bool }}
16
+ cloudfall_nginx_site_receipt_directory: >-
17
+ {{ cloudfall_domains_receipt_directory | default("") }}
18
+ loop: "{{ cloudfall_domains | default([]) }}"
19
+ loop_control:
20
+ loop_var: cloudfall_domain_item
21
+ label: "{{ cloudfall_domain_item.id }}"
@@ -0,0 +1,31 @@
1
+ ---
2
+ - name: Probe one Cloudfall component's declared health check
3
+ hosts: cloudfall_servers
4
+ become: false
5
+ gather_facts: false
6
+ any_errors_fatal: true
7
+ pre_tasks:
8
+ - name: Require an explicit component selection
9
+ ansible.builtin.assert:
10
+ that:
11
+ - cloudfall_deploy_component_id is defined
12
+ fail_msg: >-
13
+ Health probing requires the cloudfall_deploy_component_id extra
14
+ variable
15
+ run_once: true
16
+ tasks:
17
+ - name: Probe the selected component on its declared servers
18
+ ansible.builtin.include_role:
19
+ name: cloudfall_deploy
20
+ tasks_from: health
21
+ vars:
22
+ cloudfall_deploy_component: "{{ cloudfall_component_item }}"
23
+ loop: >-
24
+ {{
25
+ cloudfall_components | default([])
26
+ | selectattr('id', 'equalto', cloudfall_deploy_component_id)
27
+ | list
28
+ }}
29
+ loop_control:
30
+ loop_var: cloudfall_component_item
31
+ label: "{{ cloudfall_component_item.id }}"
@@ -0,0 +1,15 @@
1
+ ---
2
+ - name: Inspect Cloudfall servers without changing remote state
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ roles:
9
+ - role: cloudfall_inspect
10
+ cloudfall_inspect_server_id: "{{ cloudfall_server_id }}"
11
+ cloudfall_inspect_server_type: "{{ cloudfall_server_type }}"
12
+ cloudfall_inspect_logging_backend: >-
13
+ {{ cloudfall_logging_backend | default({}) }}
14
+ cloudfall_inspect_components: >-
15
+ {{ cloudfall_components | default([]) }}
@@ -0,0 +1,35 @@
1
+ ---
2
+ - name: Validate Cloudfall logging deployment inventory
3
+ hosts: localhost
4
+ gather_facts: false
5
+ tasks:
6
+ - name: Require one declared logging backend and at least one collector
7
+ ansible.builtin.assert:
8
+ that:
9
+ - groups["cloudfall_logging_backends"] | length == 1
10
+ - groups["cloudfall_logging_collectors"] | length > 0
11
+ fail_msg: >-
12
+ Validated state must declare exactly one logging backend and at least
13
+ one collector before deployment
14
+
15
+ - name: Deploy Cloudfall logging backend
16
+ hosts: cloudfall_logging_backends
17
+ become: true
18
+ gather_facts: true
19
+ any_errors_fatal: true
20
+ serial: 1
21
+ roles:
22
+ - role: cloudfall_logging_backend
23
+ cloudfall_logging_backend_stack: >-
24
+ {{ hostvars[inventory_hostname].cloudfall_logging_backend }}
25
+
26
+ - name: Deploy Cloudfall logging collectors
27
+ hosts: cloudfall_logging_collectors
28
+ become: true
29
+ gather_facts: true
30
+ any_errors_fatal: true
31
+ serial: 1
32
+ roles:
33
+ - role: cloudfall_logging_collector
34
+ cloudfall_logging_collector_stack: >-
35
+ {{ hostvars[inventory_hostname].cloudfall_logging_collector }}
@@ -0,0 +1,31 @@
1
+ ---
2
+ - name: Restart one Cloudfall component behind its health check
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ pre_tasks:
9
+ - name: Require an explicit component selection
10
+ ansible.builtin.assert:
11
+ that:
12
+ - cloudfall_deploy_component_id is defined
13
+ fail_msg: >-
14
+ Restart requires the cloudfall_deploy_component_id extra variable
15
+ run_once: true
16
+ tasks:
17
+ - name: Restart the selected component on its declared servers
18
+ ansible.builtin.include_role:
19
+ name: cloudfall_deploy
20
+ tasks_from: restart
21
+ vars:
22
+ cloudfall_deploy_component: "{{ cloudfall_component_item }}"
23
+ loop: >-
24
+ {{
25
+ cloudfall_components | default([])
26
+ | selectattr('id', 'equalto', cloudfall_deploy_component_id)
27
+ | list
28
+ }}
29
+ loop_control:
30
+ loop_var: cloudfall_component_item
31
+ label: "{{ cloudfall_component_item.id }}"
@@ -0,0 +1,33 @@
1
+ ---
2
+ - name: Roll back one Cloudfall component release
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ pre_tasks:
9
+ - name: Require an explicit component and release selection
10
+ ansible.builtin.assert:
11
+ that:
12
+ - cloudfall_deploy_component_id is defined
13
+ - cloudfall_deploy_release is defined
14
+ fail_msg: >-
15
+ Rollback requires cloudfall_deploy_component_id and
16
+ cloudfall_deploy_release extra variables
17
+ run_once: true
18
+ tasks:
19
+ - name: Roll the selected component back on its declared servers
20
+ ansible.builtin.include_role:
21
+ name: cloudfall_deploy
22
+ tasks_from: rollback
23
+ vars:
24
+ cloudfall_deploy_component: "{{ cloudfall_component_item }}"
25
+ loop: >-
26
+ {{
27
+ cloudfall_components | default([])
28
+ | selectattr('id', 'equalto', cloudfall_deploy_component_id)
29
+ | list
30
+ }}
31
+ loop_control:
32
+ loop_var: cloudfall_component_item
33
+ label: "{{ cloudfall_component_item.id }}"
@@ -0,0 +1,37 @@
1
+ ---
2
+ - name: Deploy declared Cloudfall infrastructure services
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ tasks:
9
+ - name: Deploy declared PostgreSQL services
10
+ ansible.builtin.include_role:
11
+ name: cloudfall_postgresql
12
+ vars:
13
+ cloudfall_postgresql_service: "{{ cloudfall_service_item }}"
14
+ loop: >-
15
+ {{
16
+ cloudfall_services | default([])
17
+ | selectattr('serviceKind', 'equalto', 'postgresql')
18
+ | list
19
+ }}
20
+ loop_control:
21
+ loop_var: cloudfall_service_item
22
+ label: "{{ cloudfall_service_item.id }}"
23
+
24
+ - name: Deploy declared Redis services
25
+ ansible.builtin.include_role:
26
+ name: cloudfall_redis
27
+ vars:
28
+ cloudfall_redis_service: "{{ cloudfall_service_item }}"
29
+ loop: >-
30
+ {{
31
+ cloudfall_services | default([])
32
+ | selectattr('serviceKind', 'equalto', 'redis')
33
+ | list
34
+ }}
35
+ loop_control:
36
+ loop_var: cloudfall_service_item
37
+ label: "{{ cloudfall_service_item.id }}"
@@ -0,0 +1,9 @@
1
+ ---
2
+ - name: Enforce the Cloudfall UTC time baseline
3
+ hosts: cloudfall_servers
4
+ become: true
5
+ gather_facts: true
6
+ any_errors_fatal: true
7
+ serial: 1
8
+ roles:
9
+ - role: cloudfall_time
@@ -0,0 +1,2 @@
1
+ ---
2
+ cloudfall_access_sshd_drop_in: /etc/ssh/sshd_config.d/00-cloudfall-key-only.conf
@@ -0,0 +1,5 @@
1
+ ---
2
+ - name: Reload OpenSSH
3
+ ansible.builtin.systemd_service:
4
+ name: ssh.service
5
+ state: reloaded
@@ -0,0 +1,34 @@
1
+ ---
2
+ argument_specs:
3
+ main:
4
+ short_description: Enforce declared key-only SSH access for root
5
+ options:
6
+ cloudfall_access_ssh_public_keys:
7
+ type: list
8
+ elements: dict
9
+ required: true
10
+ options:
11
+ id:
12
+ type: str
13
+ required: true
14
+ owner:
15
+ type: str
16
+ required: true
17
+ environment:
18
+ type: str
19
+ required: true
20
+ algorithm:
21
+ type: str
22
+ required: true
23
+ publicKey:
24
+ type: str
25
+ required: true
26
+ lifecycle:
27
+ type: str
28
+ choices:
29
+ - active
30
+ - revoked
31
+ required: true
32
+ cloudfall_access_sshd_drop_in:
33
+ type: path
34
+ default: /etc/ssh/sshd_config.d/00-cloudfall-key-only.conf
@@ -0,0 +1,13 @@
1
+ ---
2
+ galaxy_info:
3
+ role_name: cloudfall_access
4
+ author: Cloudfall
5
+ description: Install declared SSH keys and enforce key-only root access
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,59 @@
1
+ ---
2
+ - name: Select active declared SSH keys
3
+ ansible.builtin.set_fact:
4
+ cloudfall_access_active_keys: >-
5
+ {{
6
+ cloudfall_access_ssh_public_keys
7
+ | selectattr('lifecycle', 'equalto', 'active')
8
+ | list
9
+ }}
10
+
11
+ - name: Require at least one active declared SSH key
12
+ ansible.builtin.assert:
13
+ that:
14
+ - cloudfall_access_active_keys | length > 0
15
+ fail_msg: Refusing to disable password access without an active SSH key
16
+
17
+ - name: Create root SSH configuration directory
18
+ ansible.builtin.file:
19
+ path: /root/.ssh
20
+ state: directory
21
+ owner: root
22
+ group: root
23
+ mode: "0700"
24
+
25
+ - name: Install active root SSH keys
26
+ ansible.builtin.lineinfile:
27
+ path: /root/.ssh/authorized_keys
28
+ line: "{{ item.publicKey }}"
29
+ create: true
30
+ owner: root
31
+ group: root
32
+ mode: "0600"
33
+ loop: "{{ cloudfall_access_active_keys }}"
34
+ loop_control:
35
+ label: "{{ item.id }}"
36
+
37
+ - name: Install key-only OpenSSH policy
38
+ ansible.builtin.copy:
39
+ dest: "{{ cloudfall_access_sshd_drop_in }}"
40
+ content: |-
41
+ # Managed by Cloudfall. Local changes will be overwritten.
42
+ PubkeyAuthentication yes
43
+ PasswordAuthentication no
44
+ KbdInteractiveAuthentication no
45
+ PermitRootLogin prohibit-password
46
+ owner: root
47
+ group: root
48
+ mode: "0644"
49
+ notify: Reload OpenSSH
50
+
51
+ - name: Validate complete OpenSSH configuration
52
+ ansible.builtin.command:
53
+ argv:
54
+ - /usr/sbin/sshd
55
+ - -t
56
+ changed_when: false
57
+
58
+ - name: Apply validated OpenSSH policy
59
+ ansible.builtin.meta: flush_handlers
@@ -0,0 +1,11 @@
1
+ ---
2
+ cloudfall_bootstrap_apps_root: /srv/apps
3
+ cloudfall_bootstrap_packages:
4
+ - acl
5
+ - ca-certificates
6
+ - curl
7
+ - git
8
+ - rsync
9
+ - unzip
10
+ cloudfall_bootstrap_applications: []
11
+ cloudfall_bootstrap_components: []
@@ -0,0 +1,52 @@
1
+ ---
2
+ argument_specs:
3
+ main:
4
+ short_description: Prepare a Debian host for Cloudfall application deployments
5
+ options:
6
+ cloudfall_bootstrap_apps_root:
7
+ type: path
8
+ default: /srv/apps
9
+ cloudfall_bootstrap_packages:
10
+ type: list
11
+ elements: str
12
+ default:
13
+ - acl
14
+ - ca-certificates
15
+ - curl
16
+ - git
17
+ - rsync
18
+ - unzip
19
+ cloudfall_bootstrap_applications:
20
+ type: list
21
+ elements: dict
22
+ required: true
23
+ options:
24
+ id:
25
+ type: str
26
+ required: true
27
+ user:
28
+ type: str
29
+ required: true
30
+ approval:
31
+ type: str
32
+ choices:
33
+ - automatic
34
+ - manual
35
+ required: true
36
+ cloudfall_bootstrap_components:
37
+ type: list
38
+ elements: dict
39
+ required: true
40
+ options:
41
+ id:
42
+ type: str
43
+ required: true
44
+ application:
45
+ type: str
46
+ required: true
47
+ application_user:
48
+ type: str
49
+ required: true
50
+ install_root:
51
+ type: path
52
+ required: true
@@ -0,0 +1,13 @@
1
+ ---
2
+ galaxy_info:
3
+ role_name: cloudfall_bootstrap
4
+ author: Cloudfall
5
+ description: Prepare Debian application hosts for Cloudfall deployments
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: []