[ -f "$STATE_DIR/.env" ] && source "$STATE_DIR/.env" {% if firewalls and firewalls | length > 0 %} echo "" echo "=== Firewall Reconciliation ===" {% for fw in firewalls %} FW_NAME="{{ fw.name }}" # ── Create firewall if it doesn't exist ────────────────────────────────────── if hcloud firewall describe "$FW_NAME" > /dev/null 2>&1; then echo "✓ Firewall '$FW_NAME' exists" else echo "Creating firewall '$FW_NAME'..." hcloud firewall create \ --name "$FW_NAME" \ {%- for key, val in fw.labels %} --label "{{ key }}={{ val }}" \ {%- endfor %} > /dev/null echo "✓ Firewall '$FW_NAME' created" fi # ── Reconcile rules: add missing, leave existing untouched ─────────────────── # Strategy: try add-rule per desired rule; hcloud ignores if rule is duplicate echo " Reconciling {{ fw.rules | length }} rule(s)..." {% for rule in fw.rules %} {%- if rule.direction == "in" %} {%- if rule.protocol == "icmp" %} hcloud firewall add-rule "$FW_NAME" \ --direction in --protocol icmp \ {%- for ip in rule.source_ips %} --source-ips {{ ip }} \ {%- endfor %} > /dev/null 2>&1 || true {%- else %} hcloud firewall add-rule "$FW_NAME" \ --direction in --protocol {{ rule.protocol }} --port {{ rule.port }} \ {%- for ip in rule.source_ips %} --source-ips {{ ip }} \ {%- endfor %} > /dev/null 2>&1 || true {%- endif %} {%- else %} {%- if rule.protocol == "icmp" %} hcloud firewall add-rule "$FW_NAME" \ --direction out --protocol icmp \ {%- for ip in rule.destination_ips %} --destination-ips {{ ip }} \ {%- endfor %} > /dev/null 2>&1 || true {%- else %} hcloud firewall add-rule "$FW_NAME" \ --direction out --protocol {{ rule.protocol }} --port {{ rule.port }} \ {%- for ip in rule.destination_ips %} --destination-ips {{ ip }} \ {%- endfor %} > /dev/null 2>&1 || true {%- endif %} {%- endif %} {% endfor %} echo " ✓ Rules reconciled for '$FW_NAME'" # ── Apply firewall to this server ───────────────────────────────────────────── {% if servers is defined %} {%- for srv in servers %} {%- if srv.firewall is defined and srv.firewall == fw.name %} echo " Applying '$FW_NAME' to server '{{ srv.hostname }}'..." hcloud firewall apply-to-resource "$FW_NAME" \ --type server \ --server "{{ srv.hostname }}" 2>/dev/null || true echo " ✓ Firewall applied to '{{ srv.hostname }}'" {%- endif %} {%- endfor %} {% endif %} {% endfor %} echo "" echo "=== Firewall Reconciliation Complete ===" echo "FIREWALL_NAMES={{ firewalls | map(attribute='name') | join(d=',') }}" >> "$STATE_DIR/.env" {% else %} {# Firewall config not in server-create context — reconciliation handled by bootstrap #} {% endif %}