/
/
/
1---
2# ========================================
3# CONNECTIVITY ROLE PREREQUISITES
4# ========================================
5# Validates system requirements and prepares for connectivity services
6# Follows runner/storage role patterns with comprehensive validation
7
8- name: "Validate connectivity role prerequisites"
9 ansible.builtin.assert:
10 that:
11 - ansible_system == 'Linux'
12 - ansible_distribution in ['Ubuntu', 'Debian', 'CentOS', 'RedHat', 'Rocky', 'AlmaLinux']
13 - connectivity_docker_base_path is defined
14 - connectivity_docker_base_path | length > 0
15 - connectivity_docker_owner is defined
16 - connectivity_docker_group is defined
17 fail_msg: |
18 Connectivity role requires:
19 - Linux system with supported distribution (Ubuntu/Debian/CentOS/RHEL/Rocky/AlmaLinux)
20 - Defined docker_base_path
21 - Defined docker owner and group
22 success_msg: "Prerequisites validated successfully"
23 tags: [always, prerequisites]
24
25- name: "Check if Docker is installed and running"
26 block:
27 - name: "Check Docker daemon status"
28 systemd:
29 name: docker
30 state: started
31 enabled: yes
32 register: docker_service_status
33
34 - name: "Check Docker CLI availability"
35 ansible.builtin.command: docker --version
36 register: docker_version_check
37 changed_when: false
38 failed_when: false
39
40 - name: "Verify Docker compose availability"
41 ansible.builtin.command: docker compose version
42 register: docker_compose_check
43 changed_when: false
44 failed_when: false
45
46 rescue:
47 - name: "Fail if Docker is not properly configured"
48 ansible.builtin.fail:
49 msg: |
50 Docker is required for connectivity services but is not properly configured.
51 Please ensure:
52 1. Docker engine is installed and running
53 2. Docker compose plugin is available
54 3. System meets Docker requirements
55
56 Current status:
57 - Docker service: {{ docker_service_status is defined and docker_service_status.changed | default('Unknown') }}
58 - Docker CLI: {{ docker_version_check.rc | default(1) == 0 }}
59 - Docker Compose: {{ docker_compose_check.rc | default(1) == 0 }}
60 tags: [always, prerequisites]
61
62- name: "Validate network connectivity"
63 block:
64 - name: "Check internet connectivity"
65 ansible.builtin.uri:
66 url: https://www.google.com
67 method: GET
68 status_code: 200
69 timeout: 10
70 register: internet_check
71 ignore_errors: yes
72
73 - name: "Check DNS resolution"
74 ansible.builtin.command: nslookup google.com
75 register: dns_check
76 changed_when: false
77 ignore_errors: yes
78
79 rescue:
80 - name: "Warn about network connectivity issues"
81 ansible.builtin.debug:
82 msg: |
83 WARNING: Network connectivity issues detected
84 - Internet: {{ 'Available' if internet_check is defined and internet_check.status == 200 else 'Unavailable' }}
85 - DNS: {{ 'Working' if dns_check is defined and dns_check.rc == 0 else 'Failing' }}
86
87 Connectivity services may require internet access for:
88 - Docker image pulls
89 - WireGuard updates
90 - Pi-hole blocklist updates
91 - Unbound DNS resolution
92 tags: [always, prerequisites]
93
94- name: "Validate system resources"
95 block:
96 - name: "Check available memory"
97 ansible.builtin.set_fact:
98 available_memory_mb: "{{ ansible_memtotal_mb | default(0) }}"
99
100 - name: "Check available disk space"
101 ansible.builtin.set_fact:
102 docker_dir_free_space: "{{ (ansible_facts.mounts | selectattr('mount', 'equalto', connectivity_docker_base_path) | map(attribute='size_available') | first | default(0)) | int }}"
103
104 always:
105 - name: "Warn if system resources are low"
106 ansible.builtin.debug:
107 msg: |
108 System Resource Check:
109 - Total Memory: {{ available_memory_mb | default(0) }} MB
110 - Docker Directory Free Space: {{ (docker_dir_free_space | default(0) / 1024 / 1024) | round(2) }} GB
111
112 Minimum Recommended:
113 - Memory: 2GB+ for basic services, 4GB+ for full stack
114 - Disk Space: 10GB+ for Docker images and configurations
115 when:
116 - available_memory_mb | default(0) < 2048
117 or docker_dir_free_space | default(0) < 10737418240 # 10GB
118 tags: [always, prerequisites]
119
120- name: "Validate required ports are available"
121 block:
122 - name: "Check for port conflicts"
123 ansible.builtin.shell: |
124 netstat -tuln | grep -E ':({{
125 connectivity_wireguard_port | default(51820) }}|{{
126 connectivity_wireguard_web_port | default(51821) }}|{{
127 connectivity_nginx_proxy_admin_port | default(81) }}|{{
128 connectivity_nginx_proxy_http_port | default(80) }}|{{
129 connectivity_nginx_proxy_https_port | default(443) }}|{{
130 connectivity_pihole_web_port | default(8080) }}|{{
131 connectivity_pihole_dns_port | default(53) }}|{{
132 connectivity_unbound_port | default(5335)
133 }})\s'
134 register: port_check
135 changed_when: false
136 failed_when: false
137
138 always:
139 - name: "Warn about port conflicts"
140 ansible.builtin.debug:
141 msg: |
142 Port Conflict Check:
143 {{ port_check.stdout | default('No conflicts detected') }}
144
145 If ports are in use, services may fail to start. Consider:
146 - Changing port mappings in host variables
147 - Stopping conflicting services
148 - Using different ports for connectivity services
149 when: port_check.stdout | length > 0
150 tags: [always, prerequisites]
151
152- name: "Validate user and group permissions"
153 block:
154 - name: "Check if docker user exists"
155 ansible.builtin.user:
156 name: "{{ connectivity_docker_owner }}"
157 state: present
158 register: user_check
159
160 - name: "Check if docker group exists"
161 ansible.builtin.group:
162 name: "{{ connectivity_docker_group }}"
163 state: present
164 register: group_check
165
166 - name: "Verify user is in docker group"
167 ansible.builtin.shell: "groups {{ connectivity_docker_owner }} | grep -q docker"
168 register: docker_group_check
169 changed_when: false
170 ignore_errors: yes
171
172 rescue:
173 - name: "Warn about permission issues"
174 ansible.builtin.debug:
175 msg: |
176 Permission Validation:
177 - User {{ connectivity_docker_owner }}: {{ 'Exists' if user_check is defined and not user_check.failed else 'Missing' }}
178 - Group {{ connectivity_docker_group }}: {{ 'Exists' if group_check is defined and not group_check.failed else 'Missing' }}
179 - User in docker group: {{ 'Yes' if docker_group_check.rc == 0 else 'No' }}
180
181 Ensure the deployment user has proper Docker permissions.
182 tags: [always, prerequisites]
183
184- name: "Configure local DNS server settings"
185 block:
186 - name: "Check if systemd-resolved is running"
187 systemd:
188 name: systemd-resolved
189 state: stopped
190 enabled: no
191 masked: yes
192 when:
193 - connectivity_dns_stack_enabled | default(false)
194 - ansible_facts.services['systemd-resolved.service'].state == 'running'
195
196 - name: "Check current resolv.conf content"
197 ansible.builtin.slurp:
198 src: /etc/resolv.conf
199 register: current_resolv_conf
200 changed_when: false
201 when: connectivity_dns_stack_enabled | default(false)
202
203 - name: "Create static resolv.conf with local DNS"
204 copy:
205 content: |
206 # Local DNS server configuration
207 nameserver 127.0.0.1
208 nameserver {{ ansible_default_ipv4.address }}
209 nameserver 1.1.1.1
210 nameserver 8.8.8.8
211 options edns0
212 search home
213 dest: /etc/resolv.conf
214 owner: root
215 group: root
216 mode: '0644'
217 when:
218 - connectivity_dns_stack_enabled | default(false)
219 - current_resolv_conf.content | b64decode != "# Local DNS server configuration\nnameserver 127.0.0.1\nnameserver {{ ansible_default_ipv4.address }}\nnameserver 1.1.1.1\nnameserver 8.8.8.8\noptions edns0\nsearch home\n"
220
221 - name: "Check if resolv.conf is already immutable"
222 ansible.builtin.stat:
223 path: /etc/resolv.conf
224 register: resolv_conf_stat
225 changed_when: false
226 when: connectivity_dns_stack_enabled | default(false)
227
228 - name: "Prevent resolv.conf from being overwritten"
229 file:
230 path: /etc/resolv.conf
231 attributes: immutable
232 when:
233 - connectivity_dns_stack_enabled | default(false)
234 - not resolv_conf_stat.stat.attributes | selectattr('immutable') | list
235
236 - name: "Check current NetworkManager DNS setting"
237 ansible.builtin.slurp:
238 src: /etc/NetworkManager/NetworkManager.conf
239 register: current_nm_conf
240 changed_when: false
241 when: connectivity_dns_stack_enabled | default(false)
242
243 - name: "Configure NetworkManager to use manual DNS"
244 lineinfile:
245 path: /etc/NetworkManager/NetworkManager.conf
246 regexp: '^dns='
247 line: 'dns=none'
248 create: yes
249 when:
250 - connectivity_dns_stack_enabled | default(false)
251 - current_nm_conf.content | b64decode is not search('dns=none')
252
253 - name: "Restart NetworkManager to apply DNS changes"
254 systemd:
255 name: NetworkManager
256 state: restarted
257 when:
258 - connectivity_dns_stack_enabled | default(false)
259 - current_nm_conf.content | b64decode is search('dns=none')
260
261 tags: [dns, setup, prerequisites]
262
263- name: "Verify DNS configuration"
264 command: cat /etc/resolv.conf
265 register: resolv_conf_content
266 changed_when: false
267 tags: [dns, verification]
268
269- name: "Prerequisites validation complete"
270 ansible.builtin.debug:
271 msg: |
272 â
Connectivity role prerequisites validated successfully!
273
274 System Ready For:
275 - WireGuard VPN: {{ connectivity_wireguard_enabled | default(false) }}
276 - Nginx Proxy Manager: {{ connectivity_nginx_proxy_enabled | default(false) }}
277 - DNS Stack (Pi-hole + Unbound): {{ connectivity_dns_stack_enabled | default(false) }}
278
279 DNS Server Configuration:
280 - systemd-resolved: Stopped and masked
281 - Local DNS: 127.0.0.1, {{ ansible_default_ipv4.address }}
282 - Fallback DNS: 1.1.1.1, 8.8.8.8
283 - resolv.conf protected from modification
284
285 Proceeding with service deployment...
286 tags: [always, prerequisites]