Function App Security Restrictions
The DR failover Azure Function is configured with multiple layers of security to ensure it can ONLY be triggered by Azure Monitor alerts, not by arbitrary HTTP requests.
The security architecture is shown in the following diagram:
![]() |
Security Controls Implemented:
| Layer | Control | Configuration | Purpose |
|---|---|---|---|
| Network | IP Restriction |
ip_restriction_default_action = "Deny"
| Deny all traffic by default |
| Network | Service Tag Allow |
service_tag = "ActionGroup"
| Only allow Azure Monitor Action Groups |
| Transport | HTTPS Only |
https_only = true
| Enforce encrypted connections |
| Transport | TLS 1.2 Minimum |
minimum_tls_version = "1.2"
| Prevent downgrade attacks |
| Transport | FTPS Disabled |
ftps_state = "Disabled"
| No FTP access to function files |
| Application | Function Key |
auth_level = func.AuthLevel.FUNCTION
| Require function key in URL |
| Deployment | SCM Restrictions |
scm_ip_restriction_default_action = "Deny"
| Restrict deployment access |
Terraform Configuration
(modules/azure/dr-failover-function/main.tf):
resource "azurerm_linux_function_app" "dr_failover" {
# ... other configuration ...
# Security: Enforce HTTPS only
https_only = true
site_config {
# Security: Require HTTPS and minimum TLS version
ftps_state = "Disabled"
minimum_tls_version = "1.2"
# Security: Restrict access to Azure Monitor Action Groups only
# Azure Action Groups use the ActionGroup service tag to call webhooks/functions
# This ensures only Azure Monitor alerts can trigger the DR failover function
ip_restriction_default_action = "Deny"
ip_restriction {
name = "AllowAzureMonitor"
service_tag = "ActionGroup"
priority = 100
action = "Allow"
}
# SCM (deployment) site restrictions - deny all external access
scm_ip_restriction_default_action = "Deny"
scm_ip_restriction {
name = "AllowAzureCloud"
service_tag = "AzureCloud"
priority = 100
action = "Allow"
}
}
}
Why ActionGroup Service Tag:
Azure Monitor Action Groups call webhooks and Azure Functions from a
specific set of IP addresses defined by the
ActionGroup service tag. By denying all traffic
except this service tag, the function cannot be triggered by:
Direct HTTP requests from the internet
Curl commands or scripts
Other Azure services
Internal corporate networks
Only Azure Monitor alerts routed through Action Groups can reach the function.
Verification:
# Verify security settings are in the Terraform plan
terraform init -backend-config=backend-configs/production-secondary.hcl -reconfigure
terraform plan -var-file=secondary-<region>.tfvars | grep -A5 "ip_restriction"
# After apply, verify function URL is available (won't work from local - blocked by IP restriction)
terraform output dr-failover-function_url
# Verify function outbound IPs for AKS API access
terraform output dr-failover-function_outbound_ip_cidrsTesting the Alert Chain
The function cannot be called directly due to IP restrictions. To test the complete alert chain end-to-end, temporarily disable the primary Traffic Manager endpoint and confirm the Azure Monitor alert triggers the Function App (which scales humio-operator 0→1 on the standby cluster).
Safety: This forces the global DR hostname to stop routing to the primary endpoint. Do this only during a controlled DR test window.
# In the PRIMARY workspace (the one that created Traffic Manager):
terraform workspace select primary
TM_RG="$(terraform output -raw azure-load-balancer-resource-group)"
TM_PROFILE="$(terraform output -raw traffic_manager_fqdn | cut -d. -f1)"
PRIMARY_ENDPOINT_ID="$(terraform output -raw traffic_manager_primary_endpoint_id)"
PRIMARY_ENDPOINT_NAME="$(az resource show --ids "$PRIMARY_ENDPOINT_ID" --query name -o tsv)"
# Disable primary endpoint (forces Traffic Manager to prefer the secondary endpoint)
az network traffic-manager endpoint update \
--resource-group "$TM_RG" \
--profile-name "$TM_PROFILE" \
--type externalEndpoints \
--name "$PRIMARY_ENDPOINT_NAME" \
--endpoint-status Disabled
# Wait for the alert/function chain (~1-5 minutes), then verify on the secondary:
kubectl --context aks-secondary -n logging get deploy humio-operator
# Re-enable primary endpoint after testing
az network traffic-manager endpoint update \
--resource-group "$TM_RG" \
--profile-name "$TM_PROFILE" \
--type externalEndpoints \
--name "$PRIMARY_ENDPOINT_NAME" \
--endpoint-status EnabledNote
This repo does not currently include a
test/simulate-azure-dr-failover.sh helper script.
Direct curl calls to the function URL will return 403 Forbidden because your IP is not in the ActionGroup service tag. This is expected behavior confirming the security restrictions are working.
