The aws:networkfirewall/firewallPolicy:FirewallPolicy resource, part of the Pulumi AWS provider, defines a Network Firewall policy that specifies default traffic actions, attaches rule groups, and configures inspection behavior. This guide focuses on four capabilities: default action configuration, rule group attachment and ordering, variable overrides and custom actions, and threat detection modes.
Firewall policies reference existing Network Firewall rule groups and may reference TLS inspection configurations. The examples are intentionally small. Combine them with your own rule groups and network topology.
Define default actions and attach rule groups
Most policies start by defining how to handle traffic that doesn’t match any rules, then attach rule groups for inspection.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getRegion({});
const currentGetPartition = aws.getPartition({});
const currentGetCallerIdentity = aws.getCallerIdentity({});
const example = new aws.networkfirewall.FirewallPolicy("example", {
name: "example",
firewallPolicy: {
statelessDefaultActions: ["aws:pass"],
statelessFragmentDefaultActions: ["aws:drop"],
statelessRuleGroupReferences: [{
priority: 1,
resourceArn: exampleAwsNetworkfirewallRuleGroup.arn,
}],
tlsInspectionConfigurationArn: Promise.all([currentGetPartition, current, currentGetCallerIdentity]).then(([currentGetPartition, current, currentGetCallerIdentity]) => `arn:${currentGetPartition.partition}:network-firewall:${current.region}:${currentGetCallerIdentity.accountId}:tls-configuration/example`),
},
tags: {
Tag1: "Value1",
Tag2: "Value2",
},
});
import pulumi
import pulumi_aws as aws
current = aws.get_region()
current_get_partition = aws.get_partition()
current_get_caller_identity = aws.get_caller_identity()
example = aws.networkfirewall.FirewallPolicy("example",
name="example",
firewall_policy={
"stateless_default_actions": ["aws:pass"],
"stateless_fragment_default_actions": ["aws:drop"],
"stateless_rule_group_references": [{
"priority": 1,
"resource_arn": example_aws_networkfirewall_rule_group["arn"],
}],
"tls_inspection_configuration_arn": f"arn:{current_get_partition.partition}:network-firewall:{current.region}:{current_get_caller_identity.account_id}:tls-configuration/example",
},
tags={
"Tag1": "Value1",
"Tag2": "Value2",
})
package main
import (
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkfirewall"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetRegion(ctx, &aws.GetRegionArgs{}, nil)
if err != nil {
return err
}
currentGetPartition, err := aws.GetPartition(ctx, &aws.GetPartitionArgs{}, nil)
if err != nil {
return err
}
currentGetCallerIdentity, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
_, err = networkfirewall.NewFirewallPolicy(ctx, "example", &networkfirewall.FirewallPolicyArgs{
Name: pulumi.String("example"),
FirewallPolicy: &networkfirewall.FirewallPolicyFirewallPolicyArgs{
StatelessDefaultActions: pulumi.StringArray{
pulumi.String("aws:pass"),
},
StatelessFragmentDefaultActions: pulumi.StringArray{
pulumi.String("aws:drop"),
},
StatelessRuleGroupReferences: networkfirewall.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs{
Priority: pulumi.Int(1),
ResourceArn: pulumi.Any(exampleAwsNetworkfirewallRuleGroup.Arn),
},
},
TlsInspectionConfigurationArn: pulumi.Sprintf("arn:%v:network-firewall:%v:%v:tls-configuration/example", currentGetPartition.Partition, current.Region, currentGetCallerIdentity.AccountId),
},
Tags: pulumi.StringMap{
"Tag1": pulumi.String("Value1"),
"Tag2": pulumi.String("Value2"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetRegion.Invoke();
var currentGetPartition = Aws.GetPartition.Invoke();
var currentGetCallerIdentity = Aws.GetCallerIdentity.Invoke();
var example = new Aws.NetworkFirewall.FirewallPolicy("example", new()
{
Name = "example",
FirewallPolicyConfiguration = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyArgs
{
StatelessDefaultActions = new[]
{
"aws:pass",
},
StatelessFragmentDefaultActions = new[]
{
"aws:drop",
},
StatelessRuleGroupReferences = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs
{
Priority = 1,
ResourceArn = exampleAwsNetworkfirewallRuleGroup.Arn,
},
},
TlsInspectionConfigurationArn = Output.Tuple(currentGetPartition, current, currentGetCallerIdentity).Apply(values =>
{
var currentGetPartition = values.Item1;
var current = values.Item2;
var currentGetCallerIdentity = values.Item3;
return $"arn:{currentGetPartition.Apply(getPartitionResult => getPartitionResult.Partition)}:network-firewall:{current.Apply(getRegionResult => getRegionResult.Region)}:{currentGetCallerIdentity.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:tls-configuration/example";
}),
},
Tags =
{
{ "Tag1", "Value1" },
{ "Tag2", "Value2" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetRegionArgs;
import com.pulumi.aws.inputs.GetPartitionArgs;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.networkfirewall.FirewallPolicy;
import com.pulumi.aws.networkfirewall.FirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyArgs;
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) {
final var current = AwsFunctions.getRegion(GetRegionArgs.builder()
.build());
final var currentGetPartition = AwsFunctions.getPartition(GetPartitionArgs.builder()
.build());
final var currentGetCallerIdentity = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
.build());
var example = new FirewallPolicy("example", FirewallPolicyArgs.builder()
.name("example")
.firewallPolicy(FirewallPolicyFirewallPolicyArgs.builder()
.statelessDefaultActions("aws:pass")
.statelessFragmentDefaultActions("aws:drop")
.statelessRuleGroupReferences(FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs.builder()
.priority(1)
.resourceArn(exampleAwsNetworkfirewallRuleGroup.arn())
.build())
.tlsInspectionConfigurationArn(String.format("arn:%s:network-firewall:%s:%s:tls-configuration/example", currentGetPartition.partition(),current.region(),currentGetCallerIdentity.accountId()))
.build())
.tags(Map.ofEntries(
Map.entry("Tag1", "Value1"),
Map.entry("Tag2", "Value2")
))
.build());
}
}
resources:
example:
type: aws:networkfirewall:FirewallPolicy
properties:
name: example
firewallPolicy:
statelessDefaultActions:
- aws:pass
statelessFragmentDefaultActions:
- aws:drop
statelessRuleGroupReferences:
- priority: 1
resourceArn: ${exampleAwsNetworkfirewallRuleGroup.arn}
tlsInspectionConfigurationArn: arn:${currentGetPartition.partition}:network-firewall:${current.region}:${currentGetCallerIdentity.accountId}:tls-configuration/example
tags:
Tag1: Value1
Tag2: Value2
variables:
current:
fn::invoke:
function: aws:getRegion
arguments: {}
currentGetPartition:
fn::invoke:
function: aws:getPartition
arguments: {}
currentGetCallerIdentity:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
The statelessDefaultActions property sets what happens to packets that don’t match stateless rules (here, “aws:pass” allows them through). The statelessFragmentDefaultActions property handles fragmented packets separately. The statelessRuleGroupReferences array attaches rule groups with priority values that control evaluation order.
Override HOME_NET variable for custom networks
Rule groups often reference the HOME_NET variable to identify internal networks. Policies can override this to match your topology.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.networkfirewall.FirewallPolicy("example", {
name: "example",
firewallPolicy: {
policyVariables: {
ruleVariables: [{
key: "HOME_NET",
ipSet: {
definitions: [
"10.0.0.0/16",
"10.1.0.0/24",
],
},
}],
},
statelessDefaultActions: ["aws:pass"],
statelessFragmentDefaultActions: ["aws:drop"],
statelessRuleGroupReferences: [{
priority: 1,
resourceArn: exampleAwsNetworkfirewallRuleGroup.arn,
}],
},
tags: {
Tag1: "Value1",
Tag2: "Value2",
},
});
import pulumi
import pulumi_aws as aws
example = aws.networkfirewall.FirewallPolicy("example",
name="example",
firewall_policy={
"policy_variables": {
"rule_variables": [{
"key": "HOME_NET",
"ip_set": {
"definitions": [
"10.0.0.0/16",
"10.1.0.0/24",
],
},
}],
},
"stateless_default_actions": ["aws:pass"],
"stateless_fragment_default_actions": ["aws:drop"],
"stateless_rule_group_references": [{
"priority": 1,
"resource_arn": example_aws_networkfirewall_rule_group["arn"],
}],
},
tags={
"Tag1": "Value1",
"Tag2": "Value2",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkfirewall"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := networkfirewall.NewFirewallPolicy(ctx, "example", &networkfirewall.FirewallPolicyArgs{
Name: pulumi.String("example"),
FirewallPolicy: &networkfirewall.FirewallPolicyFirewallPolicyArgs{
PolicyVariables: &networkfirewall.FirewallPolicyFirewallPolicyPolicyVariablesArgs{
RuleVariables: networkfirewall.FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableArray{
&networkfirewall.FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableArgs{
Key: pulumi.String("HOME_NET"),
IpSet: &networkfirewall.FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableIpSetArgs{
Definitions: pulumi.StringArray{
pulumi.String("10.0.0.0/16"),
pulumi.String("10.1.0.0/24"),
},
},
},
},
},
StatelessDefaultActions: pulumi.StringArray{
pulumi.String("aws:pass"),
},
StatelessFragmentDefaultActions: pulumi.StringArray{
pulumi.String("aws:drop"),
},
StatelessRuleGroupReferences: networkfirewall.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs{
Priority: pulumi.Int(1),
ResourceArn: pulumi.Any(exampleAwsNetworkfirewallRuleGroup.Arn),
},
},
},
Tags: pulumi.StringMap{
"Tag1": pulumi.String("Value1"),
"Tag2": pulumi.String("Value2"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.NetworkFirewall.FirewallPolicy("example", new()
{
Name = "example",
FirewallPolicyConfiguration = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyArgs
{
PolicyVariables = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyPolicyVariablesArgs
{
RuleVariables = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableArgs
{
Key = "HOME_NET",
IpSet = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableIpSetArgs
{
Definitions = new[]
{
"10.0.0.0/16",
"10.1.0.0/24",
},
},
},
},
},
StatelessDefaultActions = new[]
{
"aws:pass",
},
StatelessFragmentDefaultActions = new[]
{
"aws:drop",
},
StatelessRuleGroupReferences = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs
{
Priority = 1,
ResourceArn = exampleAwsNetworkfirewallRuleGroup.Arn,
},
},
},
Tags =
{
{ "Tag1", "Value1" },
{ "Tag2", "Value2" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.networkfirewall.FirewallPolicy;
import com.pulumi.aws.networkfirewall.FirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyPolicyVariablesArgs;
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 example = new FirewallPolicy("example", FirewallPolicyArgs.builder()
.name("example")
.firewallPolicy(FirewallPolicyFirewallPolicyArgs.builder()
.policyVariables(FirewallPolicyFirewallPolicyPolicyVariablesArgs.builder()
.ruleVariables(FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableArgs.builder()
.key("HOME_NET")
.ipSet(FirewallPolicyFirewallPolicyPolicyVariablesRuleVariableIpSetArgs.builder()
.definitions(
"10.0.0.0/16",
"10.1.0.0/24")
.build())
.build())
.build())
.statelessDefaultActions("aws:pass")
.statelessFragmentDefaultActions("aws:drop")
.statelessRuleGroupReferences(FirewallPolicyFirewallPolicyStatelessRuleGroupReferenceArgs.builder()
.priority(1)
.resourceArn(exampleAwsNetworkfirewallRuleGroup.arn())
.build())
.build())
.tags(Map.ofEntries(
Map.entry("Tag1", "Value1"),
Map.entry("Tag2", "Value2")
))
.build());
}
}
resources:
example:
type: aws:networkfirewall:FirewallPolicy
properties:
name: example
firewallPolicy:
policyVariables:
ruleVariables:
- key: HOME_NET
ipSet:
definitions:
- 10.0.0.0/16
- 10.1.0.0/24
statelessDefaultActions:
- aws:pass
statelessFragmentDefaultActions:
- aws:drop
statelessRuleGroupReferences:
- priority: 1
resourceArn: ${exampleAwsNetworkfirewallRuleGroup.arn}
tags:
Tag1: Value1
Tag2: Value2
The policyVariables block defines variable overrides. The ruleVariables array sets HOME_NET to your internal CIDR ranges. Rule groups that reference HOME_NET will use these definitions instead of defaults.
Publish metrics with custom stateless actions
Beyond built-in pass, drop, and forward actions, policies can define custom actions that publish CloudWatch metrics.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.networkfirewall.FirewallPolicy("example", {
name: "example",
firewallPolicy: {
statelessDefaultActions: [
"aws:pass",
"ExampleCustomAction",
],
statelessFragmentDefaultActions: ["aws:drop"],
statelessCustomActions: [{
actionDefinition: {
publishMetricAction: {
dimensions: [{
value: "1",
}],
},
},
actionName: "ExampleCustomAction",
}],
},
});
import pulumi
import pulumi_aws as aws
example = aws.networkfirewall.FirewallPolicy("example",
name="example",
firewall_policy={
"stateless_default_actions": [
"aws:pass",
"ExampleCustomAction",
],
"stateless_fragment_default_actions": ["aws:drop"],
"stateless_custom_actions": [{
"action_definition": {
"publish_metric_action": {
"dimensions": [{
"value": "1",
}],
},
},
"action_name": "ExampleCustomAction",
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkfirewall"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := networkfirewall.NewFirewallPolicy(ctx, "example", &networkfirewall.FirewallPolicyArgs{
Name: pulumi.String("example"),
FirewallPolicy: &networkfirewall.FirewallPolicyFirewallPolicyArgs{
StatelessDefaultActions: pulumi.StringArray{
pulumi.String("aws:pass"),
pulumi.String("ExampleCustomAction"),
},
StatelessFragmentDefaultActions: pulumi.StringArray{
pulumi.String("aws:drop"),
},
StatelessCustomActions: networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionArgs{
ActionDefinition: &networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionArgs{
PublishMetricAction: &networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionArgs{
Dimensions: networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionDimensionArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionDimensionArgs{
Value: pulumi.String("1"),
},
},
},
},
ActionName: pulumi.String("ExampleCustomAction"),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.NetworkFirewall.FirewallPolicy("example", new()
{
Name = "example",
FirewallPolicyConfiguration = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyArgs
{
StatelessDefaultActions = new[]
{
"aws:pass",
"ExampleCustomAction",
},
StatelessFragmentDefaultActions = new[]
{
"aws:drop",
},
StatelessCustomActions = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessCustomActionArgs
{
ActionDefinition = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionArgs
{
PublishMetricAction = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionArgs
{
Dimensions = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionDimensionArgs
{
Value = "1",
},
},
},
},
ActionName = "ExampleCustomAction",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.networkfirewall.FirewallPolicy;
import com.pulumi.aws.networkfirewall.FirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyArgs;
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 example = new FirewallPolicy("example", FirewallPolicyArgs.builder()
.name("example")
.firewallPolicy(FirewallPolicyFirewallPolicyArgs.builder()
.statelessDefaultActions(
"aws:pass",
"ExampleCustomAction")
.statelessFragmentDefaultActions("aws:drop")
.statelessCustomActions(FirewallPolicyFirewallPolicyStatelessCustomActionArgs.builder()
.actionDefinition(FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionArgs.builder()
.publishMetricAction(FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionArgs.builder()
.dimensions(FirewallPolicyFirewallPolicyStatelessCustomActionActionDefinitionPublishMetricActionDimensionArgs.builder()
.value("1")
.build())
.build())
.build())
.actionName("ExampleCustomAction")
.build())
.build())
.build());
}
}
resources:
example:
type: aws:networkfirewall:FirewallPolicy
properties:
name: example
firewallPolicy:
statelessDefaultActions:
- aws:pass
- ExampleCustomAction
statelessFragmentDefaultActions:
- aws:drop
statelessCustomActions:
- actionDefinition:
publishMetricAction:
dimensions:
- value: '1'
actionName: ExampleCustomAction
The statelessCustomActions array defines named actions. The publishMetricAction block sends metrics to CloudWatch with custom dimensions. Reference the action name in statelessDefaultActions to invoke it.
Enable deep threat inspection with AWS-managed rules
AWS provides managed stateful rule groups that detect known attack patterns. Policies can enable deep inspection on these groups.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getRegion({});
const currentGetPartition = aws.getPartition({});
const example = new aws.networkfirewall.FirewallPolicy("example", {
name: "example",
firewallPolicy: {
statelessFragmentDefaultActions: ["aws:drop"],
statelessDefaultActions: ["aws:pass"],
statefulRuleGroupReferences: [{
deepThreatInspection: "true",
resourceArn: Promise.all([currentGetPartition, current]).then(([currentGetPartition, current]) => `arn:${currentGetPartition.partition}:network-firewall:${current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder`),
}],
},
});
import pulumi
import pulumi_aws as aws
current = aws.get_region()
current_get_partition = aws.get_partition()
example = aws.networkfirewall.FirewallPolicy("example",
name="example",
firewall_policy={
"stateless_fragment_default_actions": ["aws:drop"],
"stateless_default_actions": ["aws:pass"],
"stateful_rule_group_references": [{
"deep_threat_inspection": "true",
"resource_arn": f"arn:{current_get_partition.partition}:network-firewall:{current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder",
}],
})
package main
import (
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkfirewall"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetRegion(ctx, &aws.GetRegionArgs{}, nil)
if err != nil {
return err
}
currentGetPartition, err := aws.GetPartition(ctx, &aws.GetPartitionArgs{}, nil)
if err != nil {
return err
}
_, err = networkfirewall.NewFirewallPolicy(ctx, "example", &networkfirewall.FirewallPolicyArgs{
Name: pulumi.String("example"),
FirewallPolicy: &networkfirewall.FirewallPolicyFirewallPolicyArgs{
StatelessFragmentDefaultActions: pulumi.StringArray{
pulumi.String("aws:drop"),
},
StatelessDefaultActions: pulumi.StringArray{
pulumi.String("aws:pass"),
},
StatefulRuleGroupReferences: networkfirewall.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs{
DeepThreatInspection: pulumi.String("true"),
ResourceArn: pulumi.Sprintf("arn:%v:network-firewall:%v:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder", currentGetPartition.Partition, current.Region),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetRegion.Invoke();
var currentGetPartition = Aws.GetPartition.Invoke();
var example = new Aws.NetworkFirewall.FirewallPolicy("example", new()
{
Name = "example",
FirewallPolicyConfiguration = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyArgs
{
StatelessFragmentDefaultActions = new[]
{
"aws:drop",
},
StatelessDefaultActions = new[]
{
"aws:pass",
},
StatefulRuleGroupReferences = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs
{
DeepThreatInspection = "true",
ResourceArn = Output.Tuple(currentGetPartition, current).Apply(values =>
{
var currentGetPartition = values.Item1;
var current = values.Item2;
return $"arn:{currentGetPartition.Apply(getPartitionResult => getPartitionResult.Partition)}:network-firewall:{current.Apply(getRegionResult => getRegionResult.Region)}:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder";
}),
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetRegionArgs;
import com.pulumi.aws.inputs.GetPartitionArgs;
import com.pulumi.aws.networkfirewall.FirewallPolicy;
import com.pulumi.aws.networkfirewall.FirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyArgs;
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) {
final var current = AwsFunctions.getRegion(GetRegionArgs.builder()
.build());
final var currentGetPartition = AwsFunctions.getPartition(GetPartitionArgs.builder()
.build());
var example = new FirewallPolicy("example", FirewallPolicyArgs.builder()
.name("example")
.firewallPolicy(FirewallPolicyFirewallPolicyArgs.builder()
.statelessFragmentDefaultActions("aws:drop")
.statelessDefaultActions("aws:pass")
.statefulRuleGroupReferences(FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs.builder()
.deepThreatInspection("true")
.resourceArn(String.format("arn:%s:network-firewall:%s:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder", currentGetPartition.partition(),current.region()))
.build())
.build())
.build());
}
}
resources:
example:
type: aws:networkfirewall:FirewallPolicy
properties:
name: example
firewallPolicy:
statelessFragmentDefaultActions:
- aws:drop
statelessDefaultActions:
- aws:pass
statefulRuleGroupReferences:
- deepThreatInspection: true
resourceArn: arn:${currentGetPartition.partition}:network-firewall:${current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureActionOrder
variables:
current:
fn::invoke:
function: aws:getRegion
arguments: {}
currentGetPartition:
fn::invoke:
function: aws:getPartition
arguments: {}
The statefulRuleGroupReferences array attaches stateful rule groups. Setting deepThreatInspection to “true” enables enhanced detection. The resourceArn points to an AWS-managed rule group that contains attack signatures.
Control rule evaluation order with strict ordering
By default, Network Firewall evaluates stateful rules in action order (pass, drop, alert). Strict ordering evaluates rules by priority.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getRegion({});
const currentGetPartition = aws.getPartition({});
const example = new aws.networkfirewall.FirewallPolicy("example", {
name: "example",
firewallPolicy: {
statelessFragmentDefaultActions: ["aws:drop"],
statelessDefaultActions: ["aws:pass"],
statefulEngineOptions: {
ruleOrder: "STRICT_ORDER",
},
statefulRuleGroupReferences: [{
deepThreatInspection: "false",
priority: 1,
resourceArn: Promise.all([currentGetPartition, current]).then(([currentGetPartition, current]) => `arn:${currentGetPartition.partition}:network-firewall:${current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder`),
}],
},
});
import pulumi
import pulumi_aws as aws
current = aws.get_region()
current_get_partition = aws.get_partition()
example = aws.networkfirewall.FirewallPolicy("example",
name="example",
firewall_policy={
"stateless_fragment_default_actions": ["aws:drop"],
"stateless_default_actions": ["aws:pass"],
"stateful_engine_options": {
"rule_order": "STRICT_ORDER",
},
"stateful_rule_group_references": [{
"deep_threat_inspection": "false",
"priority": 1,
"resource_arn": f"arn:{current_get_partition.partition}:network-firewall:{current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder",
}],
})
package main
import (
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkfirewall"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetRegion(ctx, &aws.GetRegionArgs{}, nil)
if err != nil {
return err
}
currentGetPartition, err := aws.GetPartition(ctx, &aws.GetPartitionArgs{}, nil)
if err != nil {
return err
}
_, err = networkfirewall.NewFirewallPolicy(ctx, "example", &networkfirewall.FirewallPolicyArgs{
Name: pulumi.String("example"),
FirewallPolicy: &networkfirewall.FirewallPolicyFirewallPolicyArgs{
StatelessFragmentDefaultActions: pulumi.StringArray{
pulumi.String("aws:drop"),
},
StatelessDefaultActions: pulumi.StringArray{
pulumi.String("aws:pass"),
},
StatefulEngineOptions: &networkfirewall.FirewallPolicyFirewallPolicyStatefulEngineOptionsArgs{
RuleOrder: pulumi.String("STRICT_ORDER"),
},
StatefulRuleGroupReferences: networkfirewall.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArray{
&networkfirewall.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs{
DeepThreatInspection: pulumi.String("false"),
Priority: pulumi.Int(1),
ResourceArn: pulumi.Sprintf("arn:%v:network-firewall:%v:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder", currentGetPartition.Partition, current.Region),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetRegion.Invoke();
var currentGetPartition = Aws.GetPartition.Invoke();
var example = new Aws.NetworkFirewall.FirewallPolicy("example", new()
{
Name = "example",
FirewallPolicyConfiguration = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyArgs
{
StatelessFragmentDefaultActions = new[]
{
"aws:drop",
},
StatelessDefaultActions = new[]
{
"aws:pass",
},
StatefulEngineOptions = new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatefulEngineOptionsArgs
{
RuleOrder = "STRICT_ORDER",
},
StatefulRuleGroupReferences = new[]
{
new Aws.NetworkFirewall.Inputs.FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs
{
DeepThreatInspection = "false",
Priority = 1,
ResourceArn = Output.Tuple(currentGetPartition, current).Apply(values =>
{
var currentGetPartition = values.Item1;
var current = values.Item2;
return $"arn:{currentGetPartition.Apply(getPartitionResult => getPartitionResult.Partition)}:network-firewall:{current.Apply(getRegionResult => getRegionResult.Region)}:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder";
}),
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetRegionArgs;
import com.pulumi.aws.inputs.GetPartitionArgs;
import com.pulumi.aws.networkfirewall.FirewallPolicy;
import com.pulumi.aws.networkfirewall.FirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyArgs;
import com.pulumi.aws.networkfirewall.inputs.FirewallPolicyFirewallPolicyStatefulEngineOptionsArgs;
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) {
final var current = AwsFunctions.getRegion(GetRegionArgs.builder()
.build());
final var currentGetPartition = AwsFunctions.getPartition(GetPartitionArgs.builder()
.build());
var example = new FirewallPolicy("example", FirewallPolicyArgs.builder()
.name("example")
.firewallPolicy(FirewallPolicyFirewallPolicyArgs.builder()
.statelessFragmentDefaultActions("aws:drop")
.statelessDefaultActions("aws:pass")
.statefulEngineOptions(FirewallPolicyFirewallPolicyStatefulEngineOptionsArgs.builder()
.ruleOrder("STRICT_ORDER")
.build())
.statefulRuleGroupReferences(FirewallPolicyFirewallPolicyStatefulRuleGroupReferenceArgs.builder()
.deepThreatInspection("false")
.priority(1)
.resourceArn(String.format("arn:%s:network-firewall:%s:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder", currentGetPartition.partition(),current.region()))
.build())
.build())
.build());
}
}
resources:
example:
type: aws:networkfirewall:FirewallPolicy
properties:
name: example
firewallPolicy:
statelessFragmentDefaultActions:
- aws:drop
statelessDefaultActions:
- aws:pass
statefulEngineOptions:
ruleOrder: STRICT_ORDER
statefulRuleGroupReferences:
- deepThreatInspection: false
priority: 1
resourceArn: arn:${currentGetPartition.partition}:network-firewall:${current.region}:aws-managed:stateful-rulegroup/AttackInfrastructureStrictOrder
variables:
current:
fn::invoke:
function: aws:getRegion
arguments: {}
currentGetPartition:
fn::invoke:
function: aws:getPartition
arguments: {}
The statefulEngineOptions block sets ruleOrder to “STRICT_ORDER”. In this mode, you must assign priority values to each rule group. Rules evaluate in ascending priority order regardless of their action type.
Beyond these examples
These snippets focus on specific firewall policy features: default actions and rule group attachment, variable overrides and custom actions, and threat detection and rule ordering. They’re intentionally minimal rather than full network security configurations.
The examples reference pre-existing infrastructure such as Network Firewall rule groups (stateless and stateful) and TLS inspection configurations. They focus on policy configuration rather than provisioning rule groups or firewall resources.
To keep things focused, common policy patterns are omitted, including:
- Encryption configuration (encryptionConfiguration)
- Stateful rule group priority in action order mode
- Multiple custom actions and complex metric dimensions
- Combining stateless and stateful rule groups in one policy
These omissions are intentional: the goal is to illustrate how each policy feature is wired, not provide drop-in security modules. See the Network Firewall Policy resource reference for all available configuration options.
Let's configure AWS Network Firewall Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Immutability
name property is immutable and cannot be changed after the policy is created. You’ll need to create a new policy with the desired name.name, statelessDefaultActions (e.g., ["aws:pass"]), and statelessFragmentDefaultActions (e.g., ["aws:drop"]).policyVariables.ruleVariables with key "HOME_NET" and an ipSet containing your custom CIDR definitions like ["10.0.0.0/16", "10.1.0.0/24"].Rule Ordering & Evaluation
statefulEngineOptions.ruleOrder to "STRICT_ORDER" to use priority-based evaluation.statefulRuleGroupReferences only when using statefulEngineOptions.ruleOrder = "STRICT_ORDER". In default action order mode, priority is not needed.AttackInfrastructureActionOrder or AttackInfrastructureStrictOrder in statefulRuleGroupReferences with the appropriate ARN format.Custom Actions & Metrics
statelessCustomActions with an actionName and actionDefinition, then reference that actionName in statelessDefaultActions to activate it.deepThreatInspection to "true" or "false" (as a string) on statefulRuleGroupReferences to enable or disable deep packet inspection for AWS-managed threat defense rule groups.