The aws:networkfirewall/firewallPolicy:FirewallPolicy resource, part of the Pulumi AWS provider, defines a Network Firewall policy that controls traffic inspection behavior: default actions, rule group references, and evaluation order. This guide focuses on four capabilities: default action configuration, policy variables and custom actions, AWS-managed threat detection, and rule evaluation ordering.
Firewall policies reference existing rule groups (stateless and stateful) and optionally TLS inspection configurations. The examples are intentionally small. Combine them with your own rule groups and network infrastructure.
Define default actions and attach rule groups
Network Firewall 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 (
"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: {}
When traffic doesn’t match any rule, Network Firewall applies the default action. The statelessDefaultActions property handles complete packets; statelessFragmentDefaultActions handles fragments. The statelessRuleGroupReferences array attaches rule groups with priority values that control evaluation order. The tlsInspectionConfigurationArn enables TLS decryption for encrypted traffic inspection.
Override HOME_NET with custom IP ranges
Rule groups often reference the HOME_NET variable to distinguish internal from external traffic. Policies override this variable to match your network 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 variables that rule groups can reference. The ruleVariables array sets HOME_NET to your internal IP ranges. Rule groups use this variable to identify traffic originating from or destined to your network.
Publish metrics with custom stateless actions
Beyond AWS’s built-in actions (pass, drop, forward), 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 actions you can reference in default actions or rule groups. Each action has an actionName and an actionDefinition. The publishMetricAction sends custom dimensions to CloudWatch when the action executes. 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 enable deep threat inspection on these rule groups for enhanced security.
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 (
"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. Set deepThreatInspection to “true” to enable enhanced threat detection. AWS-managed rule groups like AttackInfrastructureActionOrder provide continuously updated threat intelligence without manual rule maintenance.
Control rule evaluation order with strict ordering
By default, Network Firewall evaluates stateful rules in action order (pass rules first, then drop/alert). Strict order mode evaluates rules by explicit 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 (
"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 controls how Network Firewall evaluates stateful rules. Set ruleOrder to “STRICT_ORDER” to evaluate rules by priority value instead of action type. Each rule group reference must include a priority property. Lower priority values evaluate first. This extends the threat detection pattern from the previous example by adding explicit control over evaluation sequence.
Beyond these examples
These snippets focus on specific policy-level features: default actions and rule group attachment, policy variables 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:
- Stateful rule group references without threat detection
- KMS encryption configuration (encryptionConfiguration)
- Multiple rule group priorities and ordering
- Custom action definitions beyond metrics
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, so changing it forces replacement of the entire firewall policy resource.statelessDefaultActions (e.g., aws:pass) and statelessFragmentDefaultActions (e.g., aws:drop) for stateless traffic inspection.Rule Groups & Ordering
ACTION_ORDER (default) evaluates rules by action priority without requiring explicit priority values. STRICT_ORDER requires you to set a priority for each stateful rule group reference.STRICT_ORDER in statefulEngineOptions.ruleOrder. With ACTION_ORDER, priority is not used.Advanced Features
policyVariables.ruleVariables with key: "HOME_NET" and provide IP definitions in ipSet.definitions (e.g., ["10.0.0.0/16", "10.1.0.0/24"]).statelessCustomActions with an actionDefinition (such as publishMetricAction) and reference the actionName in your statelessDefaultActions array.deepThreatInspection: "true" in statefulRuleGroupReferences and use AWS-managed rule groups like AttackInfrastructureActionOrder or AttackInfrastructureStrictOrder.tlsInspectionConfigurationArn in the firewallPolicy block, pointing to your TLS inspection configuration ARN.statelessRuleGroupReferences for stateless rules and statefulRuleGroupReferences for stateful rules within the same firewallPolicy block.