The azure-native:network:FirewallPolicyRuleCollectionGroup resource, part of the Pulumi Azure Native provider, organizes firewall rules into collections within an Azure Firewall Policy. It controls evaluation order through priority values and groups related rules together. This guide focuses on four capabilities: DNAT rules for inbound translation, network and application filtering, IP Groups and web category filtering, and HTTP header injection.
Rule collection groups belong to a Firewall Policy and may reference IP Groups or other Azure resources. The examples are intentionally small. Combine them with your own Firewall Policy, IP Groups, and network infrastructure.
Translate inbound traffic with DNAT rules
Organizations exposing internal services through Azure Firewall use DNAT to map public IPs to private backend addresses, allowing external clients to reach internal resources.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const firewallPolicyRuleCollectionGroup = new azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", {
firewallPolicyName: "firewallPolicy",
priority: 100,
resourceGroupName: "rg1",
ruleCollectionGroupName: "ruleCollectionGroup1",
ruleCollections: [{
action: {
type: azure_native.network.FirewallPolicyNatRuleCollectionActionType.DNAT,
},
name: "Example-Nat-Rule-Collection",
priority: 100,
ruleCollectionType: "FirewallPolicyNatRuleCollection",
rules: [{
destinationAddresses: ["152.23.32.23"],
destinationPorts: ["8080"],
ipProtocols: [
azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP,
azure_native.network.FirewallPolicyRuleNetworkProtocol.UDP,
],
name: "nat-rule1",
ruleType: "NatRule",
sourceAddresses: ["2.2.2.2"],
sourceIpGroups: [],
translatedFqdn: "internalhttp.server.net",
translatedPort: "8080",
}],
}],
});
import pulumi
import pulumi_azure_native as azure_native
firewall_policy_rule_collection_group = azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup",
firewall_policy_name="firewallPolicy",
priority=100,
resource_group_name="rg1",
rule_collection_group_name="ruleCollectionGroup1",
rule_collections=[{
"action": {
"type": azure_native.network.FirewallPolicyNatRuleCollectionActionType.DNAT,
},
"name": "Example-Nat-Rule-Collection",
"priority": 100,
"rule_collection_type": "FirewallPolicyNatRuleCollection",
"rules": [{
"destination_addresses": ["152.23.32.23"],
"destination_ports": ["8080"],
"ip_protocols": [
azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP,
azure_native.network.FirewallPolicyRuleNetworkProtocol.UDP,
],
"name": "nat-rule1",
"rule_type": "NatRule",
"source_addresses": ["2.2.2.2"],
"source_ip_groups": [],
"translated_fqdn": "internalhttp.server.net",
"translated_port": "8080",
}],
}])
package main
import (
network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := network.NewFirewallPolicyRuleCollectionGroup(ctx, "firewallPolicyRuleCollectionGroup", &network.FirewallPolicyRuleCollectionGroupArgs{
FirewallPolicyName: pulumi.String("firewallPolicy"),
Priority: pulumi.Int(100),
ResourceGroupName: pulumi.String("rg1"),
RuleCollectionGroupName: pulumi.String("ruleCollectionGroup1"),
RuleCollections: pulumi.Array{
network.FirewallPolicyNatRuleCollection{
Action: network.FirewallPolicyNatRuleCollectionAction{
Type: network.FirewallPolicyNatRuleCollectionActionTypeDNAT,
},
Name: "Example-Nat-Rule-Collection",
Priority: 100,
RuleCollectionType: "FirewallPolicyNatRuleCollection",
Rules: []interface{}{
network.NatRuleType{
DestinationAddresses: []string{
"152.23.32.23",
},
DestinationPorts: []string{
"8080",
},
IpProtocols: []network.FirewallPolicyRuleNetworkProtocol{
network.FirewallPolicyRuleNetworkProtocolTCP,
network.FirewallPolicyRuleNetworkProtocolUDP,
},
Name: "nat-rule1",
RuleType: "NatRule",
SourceAddresses: []string{
"2.2.2.2",
},
SourceIpGroups: []interface{}{},
TranslatedFqdn: "internalhttp.server.net",
TranslatedPort: "8080",
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var firewallPolicyRuleCollectionGroup = new AzureNative.Network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", new()
{
FirewallPolicyName = "firewallPolicy",
Priority = 100,
ResourceGroupName = "rg1",
RuleCollectionGroupName = "ruleCollectionGroup1",
RuleCollections = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyNatRuleCollectionArgs
{
Action = new AzureNative.Network.Inputs.FirewallPolicyNatRuleCollectionActionArgs
{
Type = AzureNative.Network.FirewallPolicyNatRuleCollectionActionType.DNAT,
},
Name = "Example-Nat-Rule-Collection",
Priority = 100,
RuleCollectionType = "FirewallPolicyNatRuleCollection",
Rules = new[]
{
new AzureNative.Network.Inputs.NatRuleArgs
{
DestinationAddresses = new[]
{
"152.23.32.23",
},
DestinationPorts = new[]
{
"8080",
},
IpProtocols = new[]
{
AzureNative.Network.FirewallPolicyRuleNetworkProtocol.TCP,
AzureNative.Network.FirewallPolicyRuleNetworkProtocol.UDP,
},
Name = "nat-rule1",
RuleType = "NatRule",
SourceAddresses = new[]
{
"2.2.2.2",
},
SourceIpGroups = new() { },
TranslatedFqdn = "internalhttp.server.net",
TranslatedPort = "8080",
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroup;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroupArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var firewallPolicyRuleCollectionGroup = new FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", FirewallPolicyRuleCollectionGroupArgs.builder()
.firewallPolicyName("firewallPolicy")
.priority(100)
.resourceGroupName("rg1")
.ruleCollectionGroupName("ruleCollectionGroup1")
.ruleCollections(FirewallPolicyNatRuleCollectionArgs.builder()
.action(FirewallPolicyNatRuleCollectionActionArgs.builder()
.type("DNAT")
.build())
.name("Example-Nat-Rule-Collection")
.priority(100)
.ruleCollectionType("FirewallPolicyNatRuleCollection")
.rules(%!v(PANIC=Format method: interface conversion: model.Expression is *model.FunctionCallExpression, not *model.ObjectConsExpression))
.build())
.build());
}
}
resources:
firewallPolicyRuleCollectionGroup:
type: azure-native:network:FirewallPolicyRuleCollectionGroup
properties:
firewallPolicyName: firewallPolicy
priority: 100
resourceGroupName: rg1
ruleCollectionGroupName: ruleCollectionGroup1
ruleCollections:
- action:
type: DNAT
name: Example-Nat-Rule-Collection
priority: 100
ruleCollectionType: FirewallPolicyNatRuleCollection
rules:
- destinationAddresses:
- 152.23.32.23
destinationPorts:
- '8080'
ipProtocols:
- TCP
- UDP
name: nat-rule1
ruleType: NatRule
sourceAddresses:
- 2.2.2.2
sourceIpGroups: []
translatedFqdn: internalhttp.server.net
translatedPort: '8080'
When traffic arrives at the firewall’s public IP (destinationAddresses), the DNAT action translates it to the internal FQDN (translatedFqdn) and port (translatedPort). The rule matches based on sourceAddresses, destinationPorts, and ipProtocols. Priority determines evaluation order when multiple rule collections exist.
Block traffic with network filter rules
Network administrators create deny rules to block specific traffic patterns, providing a first line of defense before application rules evaluate.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const firewallPolicyRuleCollectionGroup = new azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", {
firewallPolicyName: "firewallPolicy",
priority: 100,
resourceGroupName: "rg1",
ruleCollectionGroupName: "ruleCollectionGroup1",
ruleCollections: [{
action: {
type: azure_native.network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
name: "Example-Filter-Rule-Collection",
priority: 100,
ruleCollectionType: "FirewallPolicyFilterRuleCollection",
rules: [{
destinationAddresses: ["*"],
destinationPorts: ["*"],
ipProtocols: [azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP],
name: "network-rule1",
ruleType: "NetworkRule",
sourceAddresses: ["10.1.25.0/24"],
}],
}],
});
import pulumi
import pulumi_azure_native as azure_native
firewall_policy_rule_collection_group = azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup",
firewall_policy_name="firewallPolicy",
priority=100,
resource_group_name="rg1",
rule_collection_group_name="ruleCollectionGroup1",
rule_collections=[{
"action": {
"type": azure_native.network.FirewallPolicyFilterRuleCollectionActionType.DENY,
},
"name": "Example-Filter-Rule-Collection",
"priority": 100,
"rule_collection_type": "FirewallPolicyFilterRuleCollection",
"rules": [{
"destination_addresses": ["*"],
"destination_ports": ["*"],
"ip_protocols": [azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP],
"name": "network-rule1",
"rule_type": "NetworkRule",
"source_addresses": ["10.1.25.0/24"],
}],
}])
package main
import (
network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := network.NewFirewallPolicyRuleCollectionGroup(ctx, "firewallPolicyRuleCollectionGroup", &network.FirewallPolicyRuleCollectionGroupArgs{
FirewallPolicyName: pulumi.String("firewallPolicy"),
Priority: pulumi.Int(100),
ResourceGroupName: pulumi.String("rg1"),
RuleCollectionGroupName: pulumi.String("ruleCollectionGroup1"),
RuleCollections: pulumi.Array{
network.FirewallPolicyFilterRuleCollection{
Action: network.FirewallPolicyFilterRuleCollectionAction{
Type: network.FirewallPolicyFilterRuleCollectionActionTypeDeny,
},
Name: "Example-Filter-Rule-Collection",
Priority: 100,
RuleCollectionType: "FirewallPolicyFilterRuleCollection",
Rules: []interface{}{
network.NetworkRule{
DestinationAddresses: []string{
"*",
},
DestinationPorts: []string{
"*",
},
IpProtocols: []network.FirewallPolicyRuleNetworkProtocol{
network.FirewallPolicyRuleNetworkProtocolTCP,
},
Name: "network-rule1",
RuleType: "NetworkRule",
SourceAddresses: []string{
"10.1.25.0/24",
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var firewallPolicyRuleCollectionGroup = new AzureNative.Network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", new()
{
FirewallPolicyName = "firewallPolicy",
Priority = 100,
ResourceGroupName = "rg1",
RuleCollectionGroupName = "ruleCollectionGroup1",
RuleCollections = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionArgs
{
Action = new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionActionArgs
{
Type = AzureNative.Network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
Name = "Example-Filter-Rule-Collection",
Priority = 100,
RuleCollectionType = "FirewallPolicyFilterRuleCollection",
Rules = new[]
{
new AzureNative.Network.Inputs.NetworkRuleArgs
{
DestinationAddresses = new[]
{
"*",
},
DestinationPorts = new[]
{
"*",
},
IpProtocols = new[]
{
AzureNative.Network.FirewallPolicyRuleNetworkProtocol.TCP,
},
Name = "network-rule1",
RuleType = "NetworkRule",
SourceAddresses = new[]
{
"10.1.25.0/24",
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroup;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroupArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var firewallPolicyRuleCollectionGroup = new FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", FirewallPolicyRuleCollectionGroupArgs.builder()
.firewallPolicyName("firewallPolicy")
.priority(100)
.resourceGroupName("rg1")
.ruleCollectionGroupName("ruleCollectionGroup1")
.ruleCollections(FirewallPolicyFilterRuleCollectionArgs.builder()
.action(FirewallPolicyFilterRuleCollectionActionArgs.builder()
.type("Deny")
.build())
.name("Example-Filter-Rule-Collection")
.priority(100)
.ruleCollectionType("FirewallPolicyFilterRuleCollection")
.rules(%!v(PANIC=Format method: interface conversion: model.Expression is *model.FunctionCallExpression, not *model.ObjectConsExpression))
.build())
.build());
}
}
resources:
firewallPolicyRuleCollectionGroup:
type: azure-native:network:FirewallPolicyRuleCollectionGroup
properties:
firewallPolicyName: firewallPolicy
priority: 100
resourceGroupName: rg1
ruleCollectionGroupName: ruleCollectionGroup1
ruleCollections:
- action:
type: Deny
name: Example-Filter-Rule-Collection
priority: 100
ruleCollectionType: FirewallPolicyFilterRuleCollection
rules:
- destinationAddresses:
- '*'
destinationPorts:
- '*'
ipProtocols:
- TCP
name: network-rule1
ruleType: NetworkRule
sourceAddresses:
- 10.1.25.0/24
The Deny action drops matching traffic. Network rules evaluate based on sourceAddresses, destinationAddresses, destinationPorts, and ipProtocols. The wildcard (*) matches any destination or port. Rules within a collection are evaluated in order until a match occurs.
Reference IP Groups for centralized address management
Teams managing large address lists use IP Groups to centralize definitions and reference them across multiple rules, simplifying updates when ranges change.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const firewallPolicyRuleCollectionGroup = new azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", {
firewallPolicyName: "firewallPolicy",
priority: 110,
resourceGroupName: "rg1",
ruleCollectionGroupName: "ruleCollectionGroup1",
ruleCollections: [{
action: {
type: azure_native.network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
name: "Example-Filter-Rule-Collection",
ruleCollectionType: "FirewallPolicyFilterRuleCollection",
rules: [{
destinationIpGroups: ["/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups2"],
destinationPorts: ["*"],
ipProtocols: [azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP],
name: "network-1",
ruleType: "NetworkRule",
sourceIpGroups: ["/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1"],
}],
}],
});
import pulumi
import pulumi_azure_native as azure_native
firewall_policy_rule_collection_group = azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup",
firewall_policy_name="firewallPolicy",
priority=110,
resource_group_name="rg1",
rule_collection_group_name="ruleCollectionGroup1",
rule_collections=[{
"action": {
"type": azure_native.network.FirewallPolicyFilterRuleCollectionActionType.DENY,
},
"name": "Example-Filter-Rule-Collection",
"rule_collection_type": "FirewallPolicyFilterRuleCollection",
"rules": [{
"destination_ip_groups": ["/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups2"],
"destination_ports": ["*"],
"ip_protocols": [azure_native.network.FirewallPolicyRuleNetworkProtocol.TCP],
"name": "network-1",
"rule_type": "NetworkRule",
"source_ip_groups": ["/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1"],
}],
}])
package main
import (
network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := network.NewFirewallPolicyRuleCollectionGroup(ctx, "firewallPolicyRuleCollectionGroup", &network.FirewallPolicyRuleCollectionGroupArgs{
FirewallPolicyName: pulumi.String("firewallPolicy"),
Priority: pulumi.Int(110),
ResourceGroupName: pulumi.String("rg1"),
RuleCollectionGroupName: pulumi.String("ruleCollectionGroup1"),
RuleCollections: pulumi.Array{
network.FirewallPolicyFilterRuleCollection{
Action: network.FirewallPolicyFilterRuleCollectionAction{
Type: network.FirewallPolicyFilterRuleCollectionActionTypeDeny,
},
Name: "Example-Filter-Rule-Collection",
RuleCollectionType: "FirewallPolicyFilterRuleCollection",
Rules: []interface{}{
network.NetworkRule{
DestinationIpGroups: []string{
"/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups2",
},
DestinationPorts: []string{
"*",
},
IpProtocols: []network.FirewallPolicyRuleNetworkProtocol{
network.FirewallPolicyRuleNetworkProtocolTCP,
},
Name: "network-1",
RuleType: "NetworkRule",
SourceIpGroups: []string{
"/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1",
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var firewallPolicyRuleCollectionGroup = new AzureNative.Network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", new()
{
FirewallPolicyName = "firewallPolicy",
Priority = 110,
ResourceGroupName = "rg1",
RuleCollectionGroupName = "ruleCollectionGroup1",
RuleCollections = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionArgs
{
Action = new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionActionArgs
{
Type = AzureNative.Network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
Name = "Example-Filter-Rule-Collection",
RuleCollectionType = "FirewallPolicyFilterRuleCollection",
Rules = new[]
{
new AzureNative.Network.Inputs.NetworkRuleArgs
{
DestinationIpGroups = new[]
{
"/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups2",
},
DestinationPorts = new[]
{
"*",
},
IpProtocols = new[]
{
AzureNative.Network.FirewallPolicyRuleNetworkProtocol.TCP,
},
Name = "network-1",
RuleType = "NetworkRule",
SourceIpGroups = new[]
{
"/subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1",
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroup;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroupArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var firewallPolicyRuleCollectionGroup = new FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", FirewallPolicyRuleCollectionGroupArgs.builder()
.firewallPolicyName("firewallPolicy")
.priority(110)
.resourceGroupName("rg1")
.ruleCollectionGroupName("ruleCollectionGroup1")
.ruleCollections(FirewallPolicyFilterRuleCollectionArgs.builder()
.action(FirewallPolicyFilterRuleCollectionActionArgs.builder()
.type("Deny")
.build())
.name("Example-Filter-Rule-Collection")
.ruleCollectionType("FirewallPolicyFilterRuleCollection")
.rules(%!v(PANIC=Format method: interface conversion: model.Expression is *model.FunctionCallExpression, not *model.ObjectConsExpression))
.build())
.build());
}
}
resources:
firewallPolicyRuleCollectionGroup:
type: azure-native:network:FirewallPolicyRuleCollectionGroup
properties:
firewallPolicyName: firewallPolicy
priority: 110
resourceGroupName: rg1
ruleCollectionGroupName: ruleCollectionGroup1
ruleCollections:
- action:
type: Deny
name: Example-Filter-Rule-Collection
ruleCollectionType: FirewallPolicyFilterRuleCollection
rules:
- destinationIpGroups:
- /subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups2
destinationPorts:
- '*'
ipProtocols:
- TCP
name: network-1
ruleType: NetworkRule
sourceIpGroups:
- /subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1
Instead of listing individual addresses, sourceIpGroups and destinationIpGroups reference IP Group resource IDs. When you update an IP Group, all rules referencing it automatically use the new addresses. This reduces duplication and maintenance overhead.
Block traffic by web category
Security teams use web categories to block entire classes of websites without maintaining explicit domain lists.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const firewallPolicyRuleCollectionGroup = new azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", {
firewallPolicyName: "firewallPolicy",
priority: 110,
resourceGroupName: "rg1",
ruleCollectionGroupName: "ruleCollectionGroup1",
ruleCollections: [{
action: {
type: azure_native.network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
name: "Example-Filter-Rule-Collection",
ruleCollectionType: "FirewallPolicyFilterRuleCollection",
rules: [{
description: "Deny inbound rule",
name: "rule1",
protocols: [{
port: 443,
protocolType: azure_native.network.FirewallPolicyRuleApplicationProtocolType.Https,
}],
ruleType: "ApplicationRule",
sourceAddresses: [
"216.58.216.164",
"10.0.0.0/24",
],
webCategories: ["Hacking"],
}],
}],
});
import pulumi
import pulumi_azure_native as azure_native
firewall_policy_rule_collection_group = azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup",
firewall_policy_name="firewallPolicy",
priority=110,
resource_group_name="rg1",
rule_collection_group_name="ruleCollectionGroup1",
rule_collections=[{
"action": {
"type": azure_native.network.FirewallPolicyFilterRuleCollectionActionType.DENY,
},
"name": "Example-Filter-Rule-Collection",
"rule_collection_type": "FirewallPolicyFilterRuleCollection",
"rules": [{
"description": "Deny inbound rule",
"name": "rule1",
"protocols": [{
"port": 443,
"protocol_type": azure_native.network.FirewallPolicyRuleApplicationProtocolType.HTTPS,
}],
"rule_type": "ApplicationRule",
"source_addresses": [
"216.58.216.164",
"10.0.0.0/24",
],
"web_categories": ["Hacking"],
}],
}])
package main
import (
network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := network.NewFirewallPolicyRuleCollectionGroup(ctx, "firewallPolicyRuleCollectionGroup", &network.FirewallPolicyRuleCollectionGroupArgs{
FirewallPolicyName: pulumi.String("firewallPolicy"),
Priority: pulumi.Int(110),
ResourceGroupName: pulumi.String("rg1"),
RuleCollectionGroupName: pulumi.String("ruleCollectionGroup1"),
RuleCollections: pulumi.Array{
network.FirewallPolicyFilterRuleCollection{
Action: network.FirewallPolicyFilterRuleCollectionAction{
Type: network.FirewallPolicyFilterRuleCollectionActionTypeDeny,
},
Name: "Example-Filter-Rule-Collection",
RuleCollectionType: "FirewallPolicyFilterRuleCollection",
Rules: []interface{}{
network.ApplicationRule{
Description: "Deny inbound rule",
Name: "rule1",
Protocols: []network.FirewallPolicyRuleApplicationProtocol{
{
Port: 443,
ProtocolType: network.FirewallPolicyRuleApplicationProtocolTypeHttps,
},
},
RuleType: "ApplicationRule",
SourceAddresses: []string{
"216.58.216.164",
"10.0.0.0/24",
},
WebCategories: []string{
"Hacking",
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var firewallPolicyRuleCollectionGroup = new AzureNative.Network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", new()
{
FirewallPolicyName = "firewallPolicy",
Priority = 110,
ResourceGroupName = "rg1",
RuleCollectionGroupName = "ruleCollectionGroup1",
RuleCollections = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionArgs
{
Action = new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionActionArgs
{
Type = AzureNative.Network.FirewallPolicyFilterRuleCollectionActionType.Deny,
},
Name = "Example-Filter-Rule-Collection",
RuleCollectionType = "FirewallPolicyFilterRuleCollection",
Rules = new[]
{
new AzureNative.Network.Inputs.ApplicationRuleArgs
{
Description = "Deny inbound rule",
Name = "rule1",
Protocols = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyRuleApplicationProtocolArgs
{
Port = 443,
ProtocolType = AzureNative.Network.FirewallPolicyRuleApplicationProtocolType.Https,
},
},
RuleType = "ApplicationRule",
SourceAddresses = new[]
{
"216.58.216.164",
"10.0.0.0/24",
},
WebCategories = new[]
{
"Hacking",
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroup;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroupArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var firewallPolicyRuleCollectionGroup = new FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", FirewallPolicyRuleCollectionGroupArgs.builder()
.firewallPolicyName("firewallPolicy")
.priority(110)
.resourceGroupName("rg1")
.ruleCollectionGroupName("ruleCollectionGroup1")
.ruleCollections(FirewallPolicyFilterRuleCollectionArgs.builder()
.action(FirewallPolicyFilterRuleCollectionActionArgs.builder()
.type("Deny")
.build())
.name("Example-Filter-Rule-Collection")
.ruleCollectionType("FirewallPolicyFilterRuleCollection")
.rules(%!v(PANIC=Format method: interface conversion: model.Expression is *model.FunctionCallExpression, not *model.ObjectConsExpression))
.build())
.build());
}
}
resources:
firewallPolicyRuleCollectionGroup:
type: azure-native:network:FirewallPolicyRuleCollectionGroup
properties:
firewallPolicyName: firewallPolicy
priority: 110
resourceGroupName: rg1
ruleCollectionGroupName: ruleCollectionGroup1
ruleCollections:
- action:
type: Deny
name: Example-Filter-Rule-Collection
ruleCollectionType: FirewallPolicyFilterRuleCollection
rules:
- description: Deny inbound rule
name: rule1
protocols:
- port: 443
protocolType: Https
ruleType: ApplicationRule
sourceAddresses:
- 216.58.216.164
- 10.0.0.0/24
webCategories:
- Hacking
The webCategories property accepts predefined categories like “Hacking”, “Gambling”, or “Adult Content”. Azure Firewall maintains the underlying domain lists. Application rules also specify protocols (HTTP/HTTPS) and sourceAddresses. The Deny action blocks matching requests.
Insert HTTP headers for tenant restriction
Organizations implementing tenant restrictions inject HTTP headers into outbound requests to control which Azure AD tenants users can authenticate against.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const firewallPolicyRuleCollectionGroup = new azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", {
firewallPolicyName: "firewallPolicy",
priority: 110,
resourceGroupName: "rg1",
ruleCollectionGroupName: "ruleCollectionGroup1",
ruleCollections: [{
action: {
type: azure_native.network.FirewallPolicyFilterRuleCollectionActionType.Allow,
},
name: "Example-Filter-Rule-Collection",
ruleCollectionType: "FirewallPolicyFilterRuleCollection",
rules: [{
description: "Insert trusted tenants header",
fqdnTags: ["WindowsVirtualDesktop"],
httpHeadersToInsert: [{
headerName: "Restrict-Access-To-Tenants",
headerValue: "contoso.com,fabrikam.onmicrosoft.com",
}],
name: "rule1",
protocols: [{
port: 80,
protocolType: azure_native.network.FirewallPolicyRuleApplicationProtocolType.Http,
}],
ruleType: "ApplicationRule",
sourceAddresses: [
"216.58.216.164",
"10.0.0.0/24",
],
}],
}],
});
import pulumi
import pulumi_azure_native as azure_native
firewall_policy_rule_collection_group = azure_native.network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup",
firewall_policy_name="firewallPolicy",
priority=110,
resource_group_name="rg1",
rule_collection_group_name="ruleCollectionGroup1",
rule_collections=[{
"action": {
"type": azure_native.network.FirewallPolicyFilterRuleCollectionActionType.ALLOW,
},
"name": "Example-Filter-Rule-Collection",
"rule_collection_type": "FirewallPolicyFilterRuleCollection",
"rules": [{
"description": "Insert trusted tenants header",
"fqdn_tags": ["WindowsVirtualDesktop"],
"http_headers_to_insert": [{
"header_name": "Restrict-Access-To-Tenants",
"header_value": "contoso.com,fabrikam.onmicrosoft.com",
}],
"name": "rule1",
"protocols": [{
"port": 80,
"protocol_type": azure_native.network.FirewallPolicyRuleApplicationProtocolType.HTTP,
}],
"rule_type": "ApplicationRule",
"source_addresses": [
"216.58.216.164",
"10.0.0.0/24",
],
}],
}])
package main
import (
network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := network.NewFirewallPolicyRuleCollectionGroup(ctx, "firewallPolicyRuleCollectionGroup", &network.FirewallPolicyRuleCollectionGroupArgs{
FirewallPolicyName: pulumi.String("firewallPolicy"),
Priority: pulumi.Int(110),
ResourceGroupName: pulumi.String("rg1"),
RuleCollectionGroupName: pulumi.String("ruleCollectionGroup1"),
RuleCollections: pulumi.Array{
network.FirewallPolicyFilterRuleCollection{
Action: network.FirewallPolicyFilterRuleCollectionAction{
Type: network.FirewallPolicyFilterRuleCollectionActionTypeAllow,
},
Name: "Example-Filter-Rule-Collection",
RuleCollectionType: "FirewallPolicyFilterRuleCollection",
Rules: []interface{}{
network.ApplicationRule{
Description: "Insert trusted tenants header",
FqdnTags: []string{
"WindowsVirtualDesktop",
},
HttpHeadersToInsert: []network.FirewallPolicyHttpHeaderToInsert{
{
HeaderName: "Restrict-Access-To-Tenants",
HeaderValue: "contoso.com,fabrikam.onmicrosoft.com",
},
},
Name: "rule1",
Protocols: []network.FirewallPolicyRuleApplicationProtocol{
{
Port: 80,
ProtocolType: network.FirewallPolicyRuleApplicationProtocolTypeHttp,
},
},
RuleType: "ApplicationRule",
SourceAddresses: []string{
"216.58.216.164",
"10.0.0.0/24",
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var firewallPolicyRuleCollectionGroup = new AzureNative.Network.FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", new()
{
FirewallPolicyName = "firewallPolicy",
Priority = 110,
ResourceGroupName = "rg1",
RuleCollectionGroupName = "ruleCollectionGroup1",
RuleCollections = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionArgs
{
Action = new AzureNative.Network.Inputs.FirewallPolicyFilterRuleCollectionActionArgs
{
Type = AzureNative.Network.FirewallPolicyFilterRuleCollectionActionType.Allow,
},
Name = "Example-Filter-Rule-Collection",
RuleCollectionType = "FirewallPolicyFilterRuleCollection",
Rules = new[]
{
new AzureNative.Network.Inputs.ApplicationRuleArgs
{
Description = "Insert trusted tenants header",
FqdnTags = new[]
{
"WindowsVirtualDesktop",
},
HttpHeadersToInsert = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyHttpHeaderToInsertArgs
{
HeaderName = "Restrict-Access-To-Tenants",
HeaderValue = "contoso.com,fabrikam.onmicrosoft.com",
},
},
Name = "rule1",
Protocols = new[]
{
new AzureNative.Network.Inputs.FirewallPolicyRuleApplicationProtocolArgs
{
Port = 80,
ProtocolType = AzureNative.Network.FirewallPolicyRuleApplicationProtocolType.Http,
},
},
RuleType = "ApplicationRule",
SourceAddresses = new[]
{
"216.58.216.164",
"10.0.0.0/24",
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroup;
import com.pulumi.azurenative.network.FirewallPolicyRuleCollectionGroupArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var firewallPolicyRuleCollectionGroup = new FirewallPolicyRuleCollectionGroup("firewallPolicyRuleCollectionGroup", FirewallPolicyRuleCollectionGroupArgs.builder()
.firewallPolicyName("firewallPolicy")
.priority(110)
.resourceGroupName("rg1")
.ruleCollectionGroupName("ruleCollectionGroup1")
.ruleCollections(FirewallPolicyFilterRuleCollectionArgs.builder()
.action(FirewallPolicyFilterRuleCollectionActionArgs.builder()
.type("Allow")
.build())
.name("Example-Filter-Rule-Collection")
.ruleCollectionType("FirewallPolicyFilterRuleCollection")
.rules(%!v(PANIC=Format method: interface conversion: model.Expression is *model.FunctionCallExpression, not *model.ObjectConsExpression))
.build())
.build());
}
}
resources:
firewallPolicyRuleCollectionGroup:
type: azure-native:network:FirewallPolicyRuleCollectionGroup
properties:
firewallPolicyName: firewallPolicy
priority: 110
resourceGroupName: rg1
ruleCollectionGroupName: ruleCollectionGroup1
ruleCollections:
- action:
type: Allow
name: Example-Filter-Rule-Collection
ruleCollectionType: FirewallPolicyFilterRuleCollection
rules:
- description: Insert trusted tenants header
fqdnTags:
- WindowsVirtualDesktop
httpHeadersToInsert:
- headerName: Restrict-Access-To-Tenants
headerValue: contoso.com,fabrikam.onmicrosoft.com
name: rule1
protocols:
- port: 80
protocolType: Http
ruleType: ApplicationRule
sourceAddresses:
- 216.58.216.164
- 10.0.0.0/24
The httpHeadersToInsert property adds headers to matching requests. Here, “Restrict-Access-To-Tenants” limits authentication to specified domains. The fqdnTags property uses predefined service tags like “WindowsVirtualDesktop” instead of explicit FQDNs. The Allow action permits traffic after header insertion.
Beyond these examples
These snippets focus on specific rule collection group features: NAT, network, and application rule types, IP Groups and web category filtering, and HTTP header injection for tenant control. They’re intentionally minimal rather than complete firewall policies.
The examples reference pre-existing infrastructure such as Firewall Policy resources, IP Group resources for relevant examples, and resource groups and subscriptions. They focus on rule collection configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common rule collection patterns are omitted, including:
- Rule collection priority ordering and conflict resolution
- FQDN-based filtering (targetFqdns)
- TLS inspection configuration
- Threat intelligence integration
These omissions are intentional: the goal is to illustrate how each rule collection feature is wired, not provide drop-in firewall modules. See the FirewallPolicyRuleCollectionGroup resource reference for all available configuration options.
Let's configure Azure Firewall Policy Rule Collection Groups
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Rule Types & Collections
FirewallPolicyNatRuleCollection with DNAT action to translate destination addresses and ports. Filter collections use FirewallPolicyFilterRuleCollection with Allow or Deny actions to permit or block traffic.NatRule for destination NAT, NetworkRule for layer 3/4 filtering, and ApplicationRule for layer 7 filtering with FQDN or web category support.NatRule types, while Filter collections can contain both NetworkRule and ApplicationRule types depending on your filtering needs.Configuration & Priority
priority value, with lower numbers evaluated first. Within a collection, rules are evaluated in the order they appear.ipProtocols property.Advanced Features
sourceIpGroups and destinationIpGroups properties with full resource IDs (e.g., /subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1) instead of sourceAddresses and destinationAddresses.ApplicationRule types, use the webCategories property with category names like “Hacking” to block or allow traffic to specific website categories.httpHeadersToInsert in ApplicationRule with headerName and headerValue properties. This is useful for scenarios like tenant restrictions (e.g., Restrict-Access-To-Tenants header).Immutability & Limitations
firewallPolicyName, resourceGroupName, and ruleCollectionGroupName properties are immutable and require resource replacement if changed.