138 lines
4.1 KiB
Django/Jinja
138 lines
4.1 KiB
Django/Jinja
#!/bin/bash
|
|
# DigitalOcean Cloud Firewall provisioning script
|
|
# Generated by provisioning {{ provisioning_version }} at {{ now }}
|
|
# Reference: DigitalOcean API v2 Firewalls - https://docs.digitalocean.com/reference/api/api-reference/#firewalls
|
|
|
|
set -e
|
|
{% if debug and debug == "yes" %}set -x{% endif %}
|
|
|
|
# Validate required environment
|
|
if [ -z "$DIGITALOCEAN_TOKEN" ]; then
|
|
echo "ERROR: DIGITALOCEAN_TOKEN environment variable not set"
|
|
exit 1
|
|
fi
|
|
|
|
# Firewall configuration
|
|
FIREWALL_NAME="{{ firewall.name }}"
|
|
FIREWALL_DESCRIPTION="{{ firewall.description | default('Cloud Firewall') }}"
|
|
|
|
# Validate required fields
|
|
if [ -z "$FIREWALL_NAME" ]; then
|
|
echo "ERROR: Firewall name is required"
|
|
exit 1
|
|
fi
|
|
|
|
# Create firewall
|
|
echo "Creating firewall: $FIREWALL_NAME..."
|
|
|
|
# Build inbound rules JSON
|
|
cat > /tmp/inbound_rules.json << 'INBOUND_EOF'
|
|
[
|
|
{% for rule in firewall.inbound_rules %}
|
|
{
|
|
"protocol": "{{ rule.protocol | default('tcp') }}",
|
|
"ports": "{{ rule.ports | default('all') }}",
|
|
{% if rule.sources %}
|
|
"sources": {
|
|
{% if rule.sources.droplet_ids %}
|
|
"droplet_ids": [{{ rule.sources.droplet_ids | join(', ') }}],
|
|
{% endif %}
|
|
{% if rule.sources.addresses %}
|
|
"addresses": [{{ rule.sources.addresses | map('tojson') | join(', ') }}]
|
|
{% endif %}
|
|
}
|
|
{% endif %}
|
|
}{{ "," if not loop.last else "" }}
|
|
{% endfor %}
|
|
]
|
|
INBOUND_EOF
|
|
|
|
# Build outbound rules JSON
|
|
cat > /tmp/outbound_rules.json << 'OUTBOUND_EOF'
|
|
[
|
|
{% for rule in firewall.outbound_rules %}
|
|
{
|
|
"protocol": "{{ rule.protocol | default('tcp') }}",
|
|
"ports": "{{ rule.ports | default('all') }}",
|
|
{% if rule.destinations %}
|
|
"destinations": {
|
|
{% if rule.destinations.droplet_ids %}
|
|
"droplet_ids": [{{ rule.destinations.droplet_ids | join(', ') }}],
|
|
{% endif %}
|
|
{% if rule.destinations.addresses %}
|
|
"addresses": [{{ rule.destinations.addresses | map('tojson') | join(', ') }}]
|
|
{% endif %}
|
|
}
|
|
{% endif %}
|
|
}{{ "," if not loop.last else "" }}
|
|
{% endfor %}
|
|
]
|
|
OUTBOUND_EOF
|
|
|
|
# Create firewall using doctl
|
|
doctl compute firewall create \
|
|
--inbound-rules "$(cat /tmp/inbound_rules.json)" \
|
|
--outbound-rules "$(cat /tmp/outbound_rules.json)" \
|
|
--format ID \
|
|
--no-header \
|
|
"$FIREWALL_NAME"
|
|
|
|
# Get the firewall ID
|
|
FIREWALL_ID=$(doctl compute firewall list --format Name,ID --no-header | grep "^${FIREWALL_NAME} " | awk '{print $NF}')
|
|
|
|
if [ -z "$FIREWALL_ID" ]; then
|
|
echo "ERROR: Failed to create firewall $FIREWALL_NAME"
|
|
rm -f /tmp/inbound_rules.json /tmp/outbound_rules.json
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ Firewall $FIREWALL_NAME created successfully"
|
|
echo " ID: $FIREWALL_ID"
|
|
echo " Inbound rules: {{ firewall.inbound_rules | length }}"
|
|
echo " Outbound rules: {{ firewall.outbound_rules | length }}"
|
|
|
|
{% if firewall.apply_to_droplets %}
|
|
# Apply firewall to droplets
|
|
echo "Applying firewall to droplets..."
|
|
{% for droplet_name in firewall.apply_to_droplets %}
|
|
|
|
DROPLET_ID=$(doctl compute droplet list --format Name,ID --no-header | grep "^{{ droplet_name }} " | awk '{print $NF}')
|
|
if [ -n "$DROPLET_ID" ]; then
|
|
doctl compute firewall add-droplets \
|
|
"$FIREWALL_ID" \
|
|
"$DROPLET_ID"
|
|
echo " ✓ Applied to droplet: {{ droplet_name }} (ID: $DROPLET_ID)"
|
|
else
|
|
echo " ⚠ Droplet '{{ droplet_name }}' not found - skipping"
|
|
fi
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if firewall.apply_to_tags %}
|
|
# Apply firewall to tagged resources
|
|
echo "Applying firewall to tagged resources..."
|
|
{% for tag in firewall.apply_to_tags %}
|
|
doctl compute firewall add-tags \
|
|
"$FIREWALL_ID" \
|
|
"{{ tag }}"
|
|
echo " ✓ Applied to tag: {{ tag }}"
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if firewall.tags %}
|
|
# Apply tags to firewall itself
|
|
{% for tag in firewall.tags %}
|
|
doctl compute firewall tag "$FIREWALL_ID" --tag-name "{{ tag }}"
|
|
{% endfor %}
|
|
echo "✓ Firewall tags applied: {{ firewall.tags | join(', ') }}"
|
|
{% endif %}
|
|
|
|
# Clean up temporary files
|
|
rm -f /tmp/inbound_rules.json /tmp/outbound_rules.json
|
|
|
|
# Output firewall details
|
|
echo ""
|
|
echo "Firewall configuration:"
|
|
doctl compute firewall get "$FIREWALL_ID" --format ID,Name,InboundRulesCount,OutboundRulesCount,Status --no-header
|
|
|
|
exit 0
|