The azure-native:network:FirewallPolicyRuleCollectionGroup resource, part of the Pulumi Azure Native provider, organizes firewall rules into prioritized collections within an Azure Firewall Policy. 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 architecture.
Translate external traffic to internal destinations
Organizations exposing internal services use DNAT rules to translate public addresses and ports to private backend targets.
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) on port 8080, the DNAT action translates it to the internal FQDN (translatedFqdn) and port (translatedPort). The ipProtocols property specifies which protocols trigger the translation. This enables external clients to reach internal services without exposing private addresses.
Block traffic with network filtering rules
Network administrators create deny rules to prevent specific source networks from reaching destinations.
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 FirewallPolicyFilterRuleCollection with a Deny action blocks matching traffic. The NetworkRule type filters by IP addresses and protocols rather than application-layer attributes. Here, all TCP traffic from 10.1.25.0/24 is denied regardless of destination, implementing network segmentation.
Reference IP Groups for scalable address management
Large deployments manage IP addresses centrally through IP Groups, allowing rules to reference collections rather than individual addresses.
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 resources by their Azure resource IDs. When you update an IP Group, all rules referencing it automatically use the new addresses without rule modifications.
Block traffic by web content category
Security teams use web categories to block entire classes of sites without maintaining URL 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 ApplicationRule type filters HTTPS traffic by webCategories, blocking access to sites Azure classifies as “Hacking” without specifying individual domains. The protocols property defines which application protocols to inspect. This provides broad protection against entire threat categories.
Insert HTTP headers for tenant restriction
Organizations implementing multi-tenant access controls inject HTTP headers to restrict 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 HTTP traffic. Here, the Restrict-Access-To-Tenants header limits authentication to specified tenants (contoso.com, fabrikam.onmicrosoft.com). The fqdnTags property matches traffic to Windows Virtual Desktop services without listing individual FQDNs.
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. They’re intentionally minimal rather than complete firewall configurations.
The examples reference pre-existing infrastructure such as Firewall Policy resources, IP Groups for relevant examples, and resource groups and subscriptions. They focus on rule collection configuration rather than provisioning the surrounding firewall infrastructure.
To keep things focused, common rule patterns are omitted, including:
- Rule 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 policies. 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
Configuration & Immutability
firewallPolicyName, resourceGroupName, and ruleCollectionGroupName properties are immutable and cannot be modified after creation. Changing these requires recreating the resource.priority integer value that determines its evaluation order. Lower priority values are evaluated first. Examples show priorities like 100 and 110.Rule Collections & Types
FirewallPolicyNatRuleCollection) perform destination NAT with DNAT action, while Filter rule collections (FirewallPolicyFilterRuleCollection) allow or deny traffic. Specify the type using the ruleCollectionType property.action.type property.ruleType property within each rule.Advanced Features
sourceIpGroups and destinationIpGroups properties with resource IDs pointing to IP Group resources (e.g., /subscriptions/subid/providers/Microsoft.Network/resourceGroup/rg1/ipGroups/ipGroups1).webCategories property in ApplicationRule rules within a Filter collection. For example, set webCategories: ["Hacking"] to block hacking-related sites.httpHeadersToInsert property in ApplicationRule rules, specifying headerName and headerValue pairs (e.g., headerName: "Restrict-Access-To-Tenants").Resource Properties
size output property is a read-only string showing the size of the rule collection group in MB (e.g., “1.2MB”).