Create AWS WAFv2 Rule Groups

The aws:wafv2/ruleGroup:RuleGroup resource, part of the Pulumi AWS provider, defines a reusable collection of WAFv2 rules that filter web requests based on conditions like geography, IP addresses, request patterns, and SQL injection attempts. This guide focuses on three capabilities: geographic filtering, logical statement composition, and raw JSON for complex nesting.

Rule groups can reference IpSet and RegexPatternSet resources for pattern matching, and are typically attached to WebACLs for enforcement. The examples are intentionally small. Combine them with your own WebACL configuration and monitoring setup.

Block or allow traffic by geographic location

Many applications restrict access based on where requests originate, either to comply with data residency requirements or to reduce exposure to specific regions.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.wafv2.RuleGroup("example", {
    name: "example-rule",
    scope: "REGIONAL",
    capacity: 2,
    rules: [{
        name: "rule-1",
        priority: 1,
        action: {
            allow: {},
        },
        statement: {
            geoMatchStatement: {
                countryCodes: [
                    "US",
                    "NL",
                ],
            },
        },
        visibilityConfig: {
            cloudwatchMetricsEnabled: false,
            metricName: "friendly-rule-metric-name",
            sampledRequestsEnabled: false,
        },
    }],
    visibilityConfig: {
        cloudwatchMetricsEnabled: false,
        metricName: "friendly-metric-name",
        sampledRequestsEnabled: false,
    },
});
import pulumi
import pulumi_aws as aws

example = aws.wafv2.RuleGroup("example",
    name="example-rule",
    scope="REGIONAL",
    capacity=2,
    rules=[{
        "name": "rule-1",
        "priority": 1,
        "action": {
            "allow": {},
        },
        "statement": {
            "geo_match_statement": {
                "country_codes": [
                    "US",
                    "NL",
                ],
            },
        },
        "visibility_config": {
            "cloudwatch_metrics_enabled": False,
            "metric_name": "friendly-rule-metric-name",
            "sampled_requests_enabled": False,
        },
    }],
    visibility_config={
        "cloudwatch_metrics_enabled": False,
        "metric_name": "friendly-metric-name",
        "sampled_requests_enabled": False,
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/wafv2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := wafv2.NewRuleGroup(ctx, "example", &wafv2.RuleGroupArgs{
			Name:     pulumi.String("example-rule"),
			Scope:    pulumi.String("REGIONAL"),
			Capacity: pulumi.Int(2),
			Rules: wafv2.RuleGroupRuleArray{
				&wafv2.RuleGroupRuleArgs{
					Name:     pulumi.String("rule-1"),
					Priority: pulumi.Int(1),
					Action: &wafv2.RuleGroupRuleActionArgs{
						Allow: &wafv2.RuleGroupRuleActionAllowArgs{},
					},
					Statement: &wafv2.RuleGroupRuleStatementArgs{
						GeoMatchStatement: &wafv2.RuleGroupRuleStatementGeoMatchStatementArgs{
							CountryCodes: pulumi.StringArray{
								pulumi.String("US"),
								pulumi.String("NL"),
							},
						},
					},
					VisibilityConfig: &wafv2.RuleGroupRuleVisibilityConfigArgs{
						CloudwatchMetricsEnabled: pulumi.Bool(false),
						MetricName:               pulumi.String("friendly-rule-metric-name"),
						SampledRequestsEnabled:   pulumi.Bool(false),
					},
				},
			},
			VisibilityConfig: &wafv2.RuleGroupVisibilityConfigArgs{
				CloudwatchMetricsEnabled: pulumi.Bool(false),
				MetricName:               pulumi.String("friendly-metric-name"),
				SampledRequestsEnabled:   pulumi.Bool(false),
			},
		})
		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.WafV2.RuleGroup("example", new()
    {
        Name = "example-rule",
        Scope = "REGIONAL",
        Capacity = 2,
        Rules = new[]
        {
            new Aws.WafV2.Inputs.RuleGroupRuleArgs
            {
                Name = "rule-1",
                Priority = 1,
                Action = new Aws.WafV2.Inputs.RuleGroupRuleActionArgs
                {
                    Allow = null,
                },
                Statement = new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                {
                    GeoMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementGeoMatchStatementArgs
                    {
                        CountryCodes = new[]
                        {
                            "US",
                            "NL",
                        },
                    },
                },
                VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupRuleVisibilityConfigArgs
                {
                    CloudwatchMetricsEnabled = false,
                    MetricName = "friendly-rule-metric-name",
                    SampledRequestsEnabled = false,
                },
            },
        },
        VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupVisibilityConfigArgs
        {
            CloudwatchMetricsEnabled = false,
            MetricName = "friendly-metric-name",
            SampledRequestsEnabled = false,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.wafv2.RuleGroup;
import com.pulumi.aws.wafv2.RuleGroupArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleActionArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleActionAllowArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementGeoMatchStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleVisibilityConfigArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupVisibilityConfigArgs;
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 RuleGroup("example", RuleGroupArgs.builder()
            .name("example-rule")
            .scope("REGIONAL")
            .capacity(2)
            .rules(RuleGroupRuleArgs.builder()
                .name("rule-1")
                .priority(1)
                .action(RuleGroupRuleActionArgs.builder()
                    .allow(RuleGroupRuleActionAllowArgs.builder()
                        .build())
                    .build())
                .statement(RuleGroupRuleStatementArgs.builder()
                    .geoMatchStatement(RuleGroupRuleStatementGeoMatchStatementArgs.builder()
                        .countryCodes(                        
                            "US",
                            "NL")
                        .build())
                    .build())
                .visibilityConfig(RuleGroupRuleVisibilityConfigArgs.builder()
                    .cloudwatchMetricsEnabled(false)
                    .metricName("friendly-rule-metric-name")
                    .sampledRequestsEnabled(false)
                    .build())
                .build())
            .visibilityConfig(RuleGroupVisibilityConfigArgs.builder()
                .cloudwatchMetricsEnabled(false)
                .metricName("friendly-metric-name")
                .sampledRequestsEnabled(false)
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:wafv2:RuleGroup
    properties:
      name: example-rule
      scope: REGIONAL
      capacity: 2
      rules:
        - name: rule-1
          priority: 1
          action:
            allow: {}
          statement:
            geoMatchStatement:
              countryCodes:
                - US
                - NL
          visibilityConfig:
            cloudwatchMetricsEnabled: false
            metricName: friendly-rule-metric-name
            sampledRequestsEnabled: false
      visibilityConfig:
        cloudwatchMetricsEnabled: false
        metricName: friendly-metric-name
        sampledRequestsEnabled: false

The geoMatchStatement checks the request’s country of origin against the countryCodes list. The action property determines what happens when the condition matches: allow permits the request, block rejects it, and count logs it without taking action. The visibilityConfig enables CloudWatch metrics and request sampling for monitoring rule behavior.

Combine multiple conditions with logical operators

Real-world filtering often requires combining multiple checks: blocking requests that match certain patterns while allowing others, or requiring several conditions to be true simultaneously.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const test = new aws.wafv2.IpSet("test", {
    name: "test",
    scope: "REGIONAL",
    ipAddressVersion: "IPV4",
    addresses: [
        "1.1.1.1/32",
        "2.2.2.2/32",
    ],
});
const testRegexPatternSet = new aws.wafv2.RegexPatternSet("test", {
    name: "test",
    scope: "REGIONAL",
    regularExpressions: [{
        regexString: "one",
    }],
});
const example = new aws.wafv2.RuleGroup("example", {
    name: "complex-example",
    description: "An rule group containing all statements",
    scope: "REGIONAL",
    capacity: 500,
    rules: [
        {
            name: "rule-1",
            priority: 1,
            action: {
                block: {},
            },
            statement: {
                notStatement: {
                    statements: [{
                        andStatement: {
                            statements: [
                                {
                                    geoMatchStatement: {
                                        countryCodes: ["US"],
                                    },
                                },
                                {
                                    byteMatchStatement: {
                                        positionalConstraint: "CONTAINS",
                                        searchString: "word",
                                        fieldToMatch: {
                                            allQueryArguments: {},
                                        },
                                        textTransformations: [
                                            {
                                                priority: 5,
                                                type: "CMD_LINE",
                                            },
                                            {
                                                priority: 2,
                                                type: "LOWERCASE",
                                            },
                                        ],
                                    },
                                },
                            ],
                        },
                    }],
                },
            },
            visibilityConfig: {
                cloudwatchMetricsEnabled: false,
                metricName: "rule-1",
                sampledRequestsEnabled: false,
            },
        },
        {
            name: "rule-2",
            priority: 2,
            action: {
                count: {},
            },
            statement: {
                orStatement: {
                    statements: [
                        {
                            regexMatchStatement: {
                                regexString: "a-z?",
                                fieldToMatch: {
                                    singleHeader: {
                                        name: "user-agent",
                                    },
                                },
                                textTransformations: [{
                                    priority: 6,
                                    type: "NONE",
                                }],
                            },
                        },
                        {
                            sqliMatchStatement: {
                                fieldToMatch: {
                                    body: {},
                                },
                                textTransformations: [
                                    {
                                        priority: 5,
                                        type: "URL_DECODE",
                                    },
                                    {
                                        priority: 4,
                                        type: "HTML_ENTITY_DECODE",
                                    },
                                    {
                                        priority: 3,
                                        type: "COMPRESS_WHITE_SPACE",
                                    },
                                ],
                            },
                        },
                        {
                            xssMatchStatement: {
                                fieldToMatch: {
                                    method: {},
                                },
                                textTransformations: [{
                                    priority: 2,
                                    type: "NONE",
                                }],
                            },
                        },
                    ],
                },
            },
            visibilityConfig: {
                cloudwatchMetricsEnabled: false,
                metricName: "rule-2",
                sampledRequestsEnabled: false,
            },
            captchaConfig: {
                immunityTimeProperty: {
                    immunityTime: 240,
                },
            },
        },
        {
            name: "rule-3",
            priority: 3,
            action: {
                block: {},
            },
            statement: {
                sizeConstraintStatement: {
                    comparisonOperator: "GT",
                    size: 100,
                    fieldToMatch: {
                        singleQueryArgument: {
                            name: "username",
                        },
                    },
                    textTransformations: [{
                        priority: 5,
                        type: "NONE",
                    }],
                },
            },
            visibilityConfig: {
                cloudwatchMetricsEnabled: false,
                metricName: "rule-3",
                sampledRequestsEnabled: false,
            },
        },
        {
            name: "rule-4",
            priority: 4,
            action: {
                block: {},
            },
            statement: {
                orStatement: {
                    statements: [
                        {
                            ipSetReferenceStatement: {
                                arn: test.arn,
                            },
                        },
                        {
                            regexPatternSetReferenceStatement: {
                                arn: testRegexPatternSet.arn,
                                fieldToMatch: {
                                    singleHeader: {
                                        name: "referer",
                                    },
                                },
                                textTransformations: [{
                                    priority: 2,
                                    type: "NONE",
                                }],
                            },
                        },
                    ],
                },
            },
            visibilityConfig: {
                cloudwatchMetricsEnabled: false,
                metricName: "rule-4",
                sampledRequestsEnabled: false,
            },
        },
    ],
    visibilityConfig: {
        cloudwatchMetricsEnabled: false,
        metricName: "friendly-metric-name",
        sampledRequestsEnabled: false,
    },
    captchaConfig: [{
        immunityTimeProperty: [{
            immunityTime: 120,
        }],
    }],
    tags: {
        Name: "example-and-statement",
        Code: "123456",
    },
});
import pulumi
import pulumi_aws as aws

test = aws.wafv2.IpSet("test",
    name="test",
    scope="REGIONAL",
    ip_address_version="IPV4",
    addresses=[
        "1.1.1.1/32",
        "2.2.2.2/32",
    ])
test_regex_pattern_set = aws.wafv2.RegexPatternSet("test",
    name="test",
    scope="REGIONAL",
    regular_expressions=[{
        "regex_string": "one",
    }])
example = aws.wafv2.RuleGroup("example",
    name="complex-example",
    description="An rule group containing all statements",
    scope="REGIONAL",
    capacity=500,
    rules=[
        {
            "name": "rule-1",
            "priority": 1,
            "action": {
                "block": {},
            },
            "statement": {
                "not_statement": {
                    "statements": [{
                        "and_statement": {
                            "statements": [
                                {
                                    "geo_match_statement": {
                                        "country_codes": ["US"],
                                    },
                                },
                                {
                                    "byte_match_statement": {
                                        "positional_constraint": "CONTAINS",
                                        "search_string": "word",
                                        "field_to_match": {
                                            "all_query_arguments": {},
                                        },
                                        "text_transformations": [
                                            {
                                                "priority": 5,
                                                "type": "CMD_LINE",
                                            },
                                            {
                                                "priority": 2,
                                                "type": "LOWERCASE",
                                            },
                                        ],
                                    },
                                },
                            ],
                        },
                    }],
                },
            },
            "visibility_config": {
                "cloudwatch_metrics_enabled": False,
                "metric_name": "rule-1",
                "sampled_requests_enabled": False,
            },
        },
        {
            "name": "rule-2",
            "priority": 2,
            "action": {
                "count": {},
            },
            "statement": {
                "or_statement": {
                    "statements": [
                        {
                            "regex_match_statement": {
                                "regex_string": "a-z?",
                                "field_to_match": {
                                    "single_header": {
                                        "name": "user-agent",
                                    },
                                },
                                "text_transformations": [{
                                    "priority": 6,
                                    "type": "NONE",
                                }],
                            },
                        },
                        {
                            "sqli_match_statement": {
                                "field_to_match": {
                                    "body": {},
                                },
                                "text_transformations": [
                                    {
                                        "priority": 5,
                                        "type": "URL_DECODE",
                                    },
                                    {
                                        "priority": 4,
                                        "type": "HTML_ENTITY_DECODE",
                                    },
                                    {
                                        "priority": 3,
                                        "type": "COMPRESS_WHITE_SPACE",
                                    },
                                ],
                            },
                        },
                        {
                            "xss_match_statement": {
                                "field_to_match": {
                                    "method": {},
                                },
                                "text_transformations": [{
                                    "priority": 2,
                                    "type": "NONE",
                                }],
                            },
                        },
                    ],
                },
            },
            "visibility_config": {
                "cloudwatch_metrics_enabled": False,
                "metric_name": "rule-2",
                "sampled_requests_enabled": False,
            },
            "captcha_config": {
                "immunity_time_property": {
                    "immunity_time": 240,
                },
            },
        },
        {
            "name": "rule-3",
            "priority": 3,
            "action": {
                "block": {},
            },
            "statement": {
                "size_constraint_statement": {
                    "comparison_operator": "GT",
                    "size": 100,
                    "field_to_match": {
                        "single_query_argument": {
                            "name": "username",
                        },
                    },
                    "text_transformations": [{
                        "priority": 5,
                        "type": "NONE",
                    }],
                },
            },
            "visibility_config": {
                "cloudwatch_metrics_enabled": False,
                "metric_name": "rule-3",
                "sampled_requests_enabled": False,
            },
        },
        {
            "name": "rule-4",
            "priority": 4,
            "action": {
                "block": {},
            },
            "statement": {
                "or_statement": {
                    "statements": [
                        {
                            "ip_set_reference_statement": {
                                "arn": test.arn,
                            },
                        },
                        {
                            "regex_pattern_set_reference_statement": {
                                "arn": test_regex_pattern_set.arn,
                                "field_to_match": {
                                    "single_header": {
                                        "name": "referer",
                                    },
                                },
                                "text_transformations": [{
                                    "priority": 2,
                                    "type": "NONE",
                                }],
                            },
                        },
                    ],
                },
            },
            "visibility_config": {
                "cloudwatch_metrics_enabled": False,
                "metric_name": "rule-4",
                "sampled_requests_enabled": False,
            },
        },
    ],
    visibility_config={
        "cloudwatch_metrics_enabled": False,
        "metric_name": "friendly-metric-name",
        "sampled_requests_enabled": False,
    },
    captcha_config=[{
        "immunityTimeProperty": [{
            "immunityTime": 120,
        }],
    }],
    tags={
        "Name": "example-and-statement",
        "Code": "123456",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/wafv2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		test, err := wafv2.NewIpSet(ctx, "test", &wafv2.IpSetArgs{
			Name:             pulumi.String("test"),
			Scope:            pulumi.String("REGIONAL"),
			IpAddressVersion: pulumi.String("IPV4"),
			Addresses: pulumi.StringArray{
				pulumi.String("1.1.1.1/32"),
				pulumi.String("2.2.2.2/32"),
			},
		})
		if err != nil {
			return err
		}
		testRegexPatternSet, err := wafv2.NewRegexPatternSet(ctx, "test", &wafv2.RegexPatternSetArgs{
			Name:  pulumi.String("test"),
			Scope: pulumi.String("REGIONAL"),
			RegularExpressions: wafv2.RegexPatternSetRegularExpressionArray{
				&wafv2.RegexPatternSetRegularExpressionArgs{
					RegexString: pulumi.String("one"),
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = wafv2.NewRuleGroup(ctx, "example", &wafv2.RuleGroupArgs{
			Name:        pulumi.String("complex-example"),
			Description: pulumi.String("An rule group containing all statements"),
			Scope:       pulumi.String("REGIONAL"),
			Capacity:    pulumi.Int(500),
			Rules: wafv2.RuleGroupRuleArray{
				&wafv2.RuleGroupRuleArgs{
					Name:     pulumi.String("rule-1"),
					Priority: pulumi.Int(1),
					Action: &wafv2.RuleGroupRuleActionArgs{
						Block: &wafv2.RuleGroupRuleActionBlockArgs{},
					},
					Statement: &wafv2.RuleGroupRuleStatementArgs{
						NotStatement: &wafv2.RuleGroupRuleStatementNotStatementArgs{
							Statements: wafv2.RuleGroupRuleStatementArray{
								&wafv2.RuleGroupRuleStatementArgs{
									AndStatement: &wafv2.RuleGroupRuleStatementAndStatementArgs{
										Statements: wafv2.RuleGroupRuleStatementArray{
											&wafv2.RuleGroupRuleStatementArgs{
												GeoMatchStatement: &wafv2.RuleGroupRuleStatementGeoMatchStatementArgs{
													CountryCodes: pulumi.StringArray{
														pulumi.String("US"),
													},
												},
											},
											&wafv2.RuleGroupRuleStatementArgs{
												ByteMatchStatement: &wafv2.RuleGroupRuleStatementByteMatchStatementArgs{
													PositionalConstraint: pulumi.String("CONTAINS"),
													SearchString:         pulumi.String("word"),
													FieldToMatch: &wafv2.RuleGroupRuleStatementByteMatchStatementFieldToMatchArgs{
														AllQueryArguments: &wafv2.RuleGroupRuleStatementByteMatchStatementFieldToMatchAllQueryArgumentsArgs{},
													},
													TextTransformations: wafv2.RuleGroupRuleStatementByteMatchStatementTextTransformationArray{
														&wafv2.RuleGroupRuleStatementByteMatchStatementTextTransformationArgs{
															Priority: pulumi.Int(5),
															Type:     pulumi.String("CMD_LINE"),
														},
														&wafv2.RuleGroupRuleStatementByteMatchStatementTextTransformationArgs{
															Priority: pulumi.Int(2),
															Type:     pulumi.String("LOWERCASE"),
														},
													},
												},
											},
										},
									},
								},
							},
						},
					},
					VisibilityConfig: &wafv2.RuleGroupRuleVisibilityConfigArgs{
						CloudwatchMetricsEnabled: pulumi.Bool(false),
						MetricName:               pulumi.String("rule-1"),
						SampledRequestsEnabled:   pulumi.Bool(false),
					},
				},
				&wafv2.RuleGroupRuleArgs{
					Name:     pulumi.String("rule-2"),
					Priority: pulumi.Int(2),
					Action: &wafv2.RuleGroupRuleActionArgs{
						Count: &wafv2.RuleGroupRuleActionCountArgs{},
					},
					Statement: &wafv2.RuleGroupRuleStatementArgs{
						OrStatement: &wafv2.RuleGroupRuleStatementOrStatementArgs{
							Statements: wafv2.RuleGroupRuleStatementArray{
								&wafv2.RuleGroupRuleStatementArgs{
									RegexMatchStatement: &wafv2.RuleGroupRuleStatementRegexMatchStatementArgs{
										RegexString: pulumi.String("a-z?"),
										FieldToMatch: &wafv2.RuleGroupRuleStatementRegexMatchStatementFieldToMatchArgs{
											SingleHeader: &wafv2.RuleGroupRuleStatementRegexMatchStatementFieldToMatchSingleHeaderArgs{
												Name: pulumi.String("user-agent"),
											},
										},
										TextTransformations: wafv2.RuleGroupRuleStatementRegexMatchStatementTextTransformationArray{
											&wafv2.RuleGroupRuleStatementRegexMatchStatementTextTransformationArgs{
												Priority: pulumi.Int(6),
												Type:     pulumi.String("NONE"),
											},
										},
									},
								},
								&wafv2.RuleGroupRuleStatementArgs{
									SqliMatchStatement: &wafv2.RuleGroupRuleStatementSqliMatchStatementArgs{
										FieldToMatch: &wafv2.RuleGroupRuleStatementSqliMatchStatementFieldToMatchArgs{
											Body: &wafv2.RuleGroupRuleStatementSqliMatchStatementFieldToMatchBodyArgs{},
										},
										TextTransformations: wafv2.RuleGroupRuleStatementSqliMatchStatementTextTransformationArray{
											&wafv2.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs{
												Priority: pulumi.Int(5),
												Type:     pulumi.String("URL_DECODE"),
											},
											&wafv2.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs{
												Priority: pulumi.Int(4),
												Type:     pulumi.String("HTML_ENTITY_DECODE"),
											},
											&wafv2.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs{
												Priority: pulumi.Int(3),
												Type:     pulumi.String("COMPRESS_WHITE_SPACE"),
											},
										},
									},
								},
								&wafv2.RuleGroupRuleStatementArgs{
									XssMatchStatement: &wafv2.RuleGroupRuleStatementXssMatchStatementArgs{
										FieldToMatch: &wafv2.RuleGroupRuleStatementXssMatchStatementFieldToMatchArgs{
											Method: &wafv2.RuleGroupRuleStatementXssMatchStatementFieldToMatchMethodArgs{},
										},
										TextTransformations: wafv2.RuleGroupRuleStatementXssMatchStatementTextTransformationArray{
											&wafv2.RuleGroupRuleStatementXssMatchStatementTextTransformationArgs{
												Priority: pulumi.Int(2),
												Type:     pulumi.String("NONE"),
											},
										},
									},
								},
							},
						},
					},
					VisibilityConfig: &wafv2.RuleGroupRuleVisibilityConfigArgs{
						CloudwatchMetricsEnabled: pulumi.Bool(false),
						MetricName:               pulumi.String("rule-2"),
						SampledRequestsEnabled:   pulumi.Bool(false),
					},
					CaptchaConfig: &wafv2.RuleGroupRuleCaptchaConfigArgs{
						ImmunityTimeProperty: &wafv2.RuleGroupRuleCaptchaConfigImmunityTimePropertyArgs{
							ImmunityTime: pulumi.Int(240),
						},
					},
				},
				&wafv2.RuleGroupRuleArgs{
					Name:     pulumi.String("rule-3"),
					Priority: pulumi.Int(3),
					Action: &wafv2.RuleGroupRuleActionArgs{
						Block: &wafv2.RuleGroupRuleActionBlockArgs{},
					},
					Statement: &wafv2.RuleGroupRuleStatementArgs{
						SizeConstraintStatement: &wafv2.RuleGroupRuleStatementSizeConstraintStatementArgs{
							ComparisonOperator: pulumi.String("GT"),
							Size:               pulumi.Int(100),
							FieldToMatch: &wafv2.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchArgs{
								SingleQueryArgument: &wafv2.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchSingleQueryArgumentArgs{
									Name: pulumi.String("username"),
								},
							},
							TextTransformations: wafv2.RuleGroupRuleStatementSizeConstraintStatementTextTransformationArray{
								&wafv2.RuleGroupRuleStatementSizeConstraintStatementTextTransformationArgs{
									Priority: pulumi.Int(5),
									Type:     pulumi.String("NONE"),
								},
							},
						},
					},
					VisibilityConfig: &wafv2.RuleGroupRuleVisibilityConfigArgs{
						CloudwatchMetricsEnabled: pulumi.Bool(false),
						MetricName:               pulumi.String("rule-3"),
						SampledRequestsEnabled:   pulumi.Bool(false),
					},
				},
				&wafv2.RuleGroupRuleArgs{
					Name:     pulumi.String("rule-4"),
					Priority: pulumi.Int(4),
					Action: &wafv2.RuleGroupRuleActionArgs{
						Block: &wafv2.RuleGroupRuleActionBlockArgs{},
					},
					Statement: &wafv2.RuleGroupRuleStatementArgs{
						OrStatement: &wafv2.RuleGroupRuleStatementOrStatementArgs{
							Statements: wafv2.RuleGroupRuleStatementArray{
								&wafv2.RuleGroupRuleStatementArgs{
									IpSetReferenceStatement: &wafv2.RuleGroupRuleStatementIpSetReferenceStatementArgs{
										Arn: test.Arn,
									},
								},
								&wafv2.RuleGroupRuleStatementArgs{
									RegexPatternSetReferenceStatement: &wafv2.RuleGroupRuleStatementRegexPatternSetReferenceStatementArgs{
										Arn: testRegexPatternSet.Arn,
										FieldToMatch: &wafv2.RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchArgs{
											SingleHeader: &wafv2.RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchSingleHeaderArgs{
												Name: pulumi.String("referer"),
											},
										},
										TextTransformations: wafv2.RuleGroupRuleStatementRegexPatternSetReferenceStatementTextTransformationArray{
											&wafv2.RuleGroupRuleStatementRegexPatternSetReferenceStatementTextTransformationArgs{
												Priority: pulumi.Int(2),
												Type:     pulumi.String("NONE"),
											},
										},
									},
								},
							},
						},
					},
					VisibilityConfig: &wafv2.RuleGroupRuleVisibilityConfigArgs{
						CloudwatchMetricsEnabled: pulumi.Bool(false),
						MetricName:               pulumi.String("rule-4"),
						SampledRequestsEnabled:   pulumi.Bool(false),
					},
				},
			},
			VisibilityConfig: &wafv2.RuleGroupVisibilityConfigArgs{
				CloudwatchMetricsEnabled: pulumi.Bool(false),
				MetricName:               pulumi.String("friendly-metric-name"),
				SampledRequestsEnabled:   pulumi.Bool(false),
			},
			CaptchaConfig: []map[string]interface{}{
				map[string]interface{}{
					"immunityTimeProperty": []map[string]interface{}{
						map[string]interface{}{
							"immunityTime": 120,
						},
					},
				},
			},
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example-and-statement"),
				"Code": pulumi.String("123456"),
			},
		})
		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 test = new Aws.WafV2.IpSet("test", new()
    {
        Name = "test",
        Scope = "REGIONAL",
        IpAddressVersion = "IPV4",
        Addresses = new[]
        {
            "1.1.1.1/32",
            "2.2.2.2/32",
        },
    });

    var testRegexPatternSet = new Aws.WafV2.RegexPatternSet("test", new()
    {
        Name = "test",
        Scope = "REGIONAL",
        RegularExpressions = new[]
        {
            new Aws.WafV2.Inputs.RegexPatternSetRegularExpressionArgs
            {
                RegexString = "one",
            },
        },
    });

    var example = new Aws.WafV2.RuleGroup("example", new()
    {
        Name = "complex-example",
        Description = "An rule group containing all statements",
        Scope = "REGIONAL",
        Capacity = 500,
        Rules = new[]
        {
            new Aws.WafV2.Inputs.RuleGroupRuleArgs
            {
                Name = "rule-1",
                Priority = 1,
                Action = new Aws.WafV2.Inputs.RuleGroupRuleActionArgs
                {
                    Block = null,
                },
                Statement = new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                {
                    NotStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementNotStatementArgs
                    {
                        Statements = new[]
                        {
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                AndStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementAndStatementArgs
                                {
                                    Statements = new[]
                                    {
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                                        {
                                            GeoMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementGeoMatchStatementArgs
                                            {
                                                CountryCodes = new[]
                                                {
                                                    "US",
                                                },
                                            },
                                        },
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                                        {
                                            ByteMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementByteMatchStatementArgs
                                            {
                                                PositionalConstraint = "CONTAINS",
                                                SearchString = "word",
                                                FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementByteMatchStatementFieldToMatchArgs
                                                {
                                                    AllQueryArguments = null,
                                                },
                                                TextTransformations = new[]
                                                {
                                                    new Aws.WafV2.Inputs.RuleGroupRuleStatementByteMatchStatementTextTransformationArgs
                                                    {
                                                        Priority = 5,
                                                        Type = "CMD_LINE",
                                                    },
                                                    new Aws.WafV2.Inputs.RuleGroupRuleStatementByteMatchStatementTextTransformationArgs
                                                    {
                                                        Priority = 2,
                                                        Type = "LOWERCASE",
                                                    },
                                                },
                                            },
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupRuleVisibilityConfigArgs
                {
                    CloudwatchMetricsEnabled = false,
                    MetricName = "rule-1",
                    SampledRequestsEnabled = false,
                },
            },
            new Aws.WafV2.Inputs.RuleGroupRuleArgs
            {
                Name = "rule-2",
                Priority = 2,
                Action = new Aws.WafV2.Inputs.RuleGroupRuleActionArgs
                {
                    Count = null,
                },
                Statement = new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                {
                    OrStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementOrStatementArgs
                    {
                        Statements = new[]
                        {
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                RegexMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexMatchStatementArgs
                                {
                                    RegexString = "a-z?",
                                    FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexMatchStatementFieldToMatchArgs
                                    {
                                        SingleHeader = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexMatchStatementFieldToMatchSingleHeaderArgs
                                        {
                                            Name = "user-agent",
                                        },
                                    },
                                    TextTransformations = new[]
                                    {
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexMatchStatementTextTransformationArgs
                                        {
                                            Priority = 6,
                                            Type = "NONE",
                                        },
                                    },
                                },
                            },
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                SqliMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementSqliMatchStatementArgs
                                {
                                    FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementSqliMatchStatementFieldToMatchArgs
                                    {
                                        Body = null,
                                    },
                                    TextTransformations = new[]
                                    {
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs
                                        {
                                            Priority = 5,
                                            Type = "URL_DECODE",
                                        },
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs
                                        {
                                            Priority = 4,
                                            Type = "HTML_ENTITY_DECODE",
                                        },
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs
                                        {
                                            Priority = 3,
                                            Type = "COMPRESS_WHITE_SPACE",
                                        },
                                    },
                                },
                            },
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                XssMatchStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementXssMatchStatementArgs
                                {
                                    FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementXssMatchStatementFieldToMatchArgs
                                    {
                                        Method = null,
                                    },
                                    TextTransformations = new[]
                                    {
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementXssMatchStatementTextTransformationArgs
                                        {
                                            Priority = 2,
                                            Type = "NONE",
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupRuleVisibilityConfigArgs
                {
                    CloudwatchMetricsEnabled = false,
                    MetricName = "rule-2",
                    SampledRequestsEnabled = false,
                },
                CaptchaConfig = new Aws.WafV2.Inputs.RuleGroupRuleCaptchaConfigArgs
                {
                    ImmunityTimeProperty = new Aws.WafV2.Inputs.RuleGroupRuleCaptchaConfigImmunityTimePropertyArgs
                    {
                        ImmunityTime = 240,
                    },
                },
            },
            new Aws.WafV2.Inputs.RuleGroupRuleArgs
            {
                Name = "rule-3",
                Priority = 3,
                Action = new Aws.WafV2.Inputs.RuleGroupRuleActionArgs
                {
                    Block = null,
                },
                Statement = new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                {
                    SizeConstraintStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementSizeConstraintStatementArgs
                    {
                        ComparisonOperator = "GT",
                        Size = 100,
                        FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchArgs
                        {
                            SingleQueryArgument = new Aws.WafV2.Inputs.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchSingleQueryArgumentArgs
                            {
                                Name = "username",
                            },
                        },
                        TextTransformations = new[]
                        {
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementSizeConstraintStatementTextTransformationArgs
                            {
                                Priority = 5,
                                Type = "NONE",
                            },
                        },
                    },
                },
                VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupRuleVisibilityConfigArgs
                {
                    CloudwatchMetricsEnabled = false,
                    MetricName = "rule-3",
                    SampledRequestsEnabled = false,
                },
            },
            new Aws.WafV2.Inputs.RuleGroupRuleArgs
            {
                Name = "rule-4",
                Priority = 4,
                Action = new Aws.WafV2.Inputs.RuleGroupRuleActionArgs
                {
                    Block = null,
                },
                Statement = new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                {
                    OrStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementOrStatementArgs
                    {
                        Statements = new[]
                        {
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                IpSetReferenceStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementIpSetReferenceStatementArgs
                                {
                                    Arn = test.Arn,
                                },
                            },
                            new Aws.WafV2.Inputs.RuleGroupRuleStatementArgs
                            {
                                RegexPatternSetReferenceStatement = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexPatternSetReferenceStatementArgs
                                {
                                    Arn = testRegexPatternSet.Arn,
                                    FieldToMatch = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchArgs
                                    {
                                        SingleHeader = new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchSingleHeaderArgs
                                        {
                                            Name = "referer",
                                        },
                                    },
                                    TextTransformations = new[]
                                    {
                                        new Aws.WafV2.Inputs.RuleGroupRuleStatementRegexPatternSetReferenceStatementTextTransformationArgs
                                        {
                                            Priority = 2,
                                            Type = "NONE",
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
                VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupRuleVisibilityConfigArgs
                {
                    CloudwatchMetricsEnabled = false,
                    MetricName = "rule-4",
                    SampledRequestsEnabled = false,
                },
            },
        },
        VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupVisibilityConfigArgs
        {
            CloudwatchMetricsEnabled = false,
            MetricName = "friendly-metric-name",
            SampledRequestsEnabled = false,
        },
        CaptchaConfig = new[]
        {
            
            {
                { "immunityTimeProperty", new[]
                {
                    
                    {
                        { "immunityTime", 120 },
                    },
                } },
            },
        },
        Tags = 
        {
            { "Name", "example-and-statement" },
            { "Code", "123456" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.wafv2.IpSet;
import com.pulumi.aws.wafv2.IpSetArgs;
import com.pulumi.aws.wafv2.RegexPatternSet;
import com.pulumi.aws.wafv2.RegexPatternSetArgs;
import com.pulumi.aws.wafv2.inputs.RegexPatternSetRegularExpressionArgs;
import com.pulumi.aws.wafv2.RuleGroup;
import com.pulumi.aws.wafv2.RuleGroupArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleActionArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleActionBlockArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementNotStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleVisibilityConfigArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleActionCountArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementOrStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleCaptchaConfigArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleCaptchaConfigImmunityTimePropertyArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementSizeConstraintStatementArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupRuleStatementSizeConstraintStatementFieldToMatchSingleQueryArgumentArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupVisibilityConfigArgs;
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 test = new IpSet("test", IpSetArgs.builder()
            .name("test")
            .scope("REGIONAL")
            .ipAddressVersion("IPV4")
            .addresses(            
                "1.1.1.1/32",
                "2.2.2.2/32")
            .build());

        var testRegexPatternSet = new RegexPatternSet("testRegexPatternSet", RegexPatternSetArgs.builder()
            .name("test")
            .scope("REGIONAL")
            .regularExpressions(RegexPatternSetRegularExpressionArgs.builder()
                .regexString("one")
                .build())
            .build());

        var example = new RuleGroup("example", RuleGroupArgs.builder()
            .name("complex-example")
            .description("An rule group containing all statements")
            .scope("REGIONAL")
            .capacity(500)
            .rules(            
                RuleGroupRuleArgs.builder()
                    .name("rule-1")
                    .priority(1)
                    .action(RuleGroupRuleActionArgs.builder()
                        .block(RuleGroupRuleActionBlockArgs.builder()
                            .build())
                        .build())
                    .statement(RuleGroupRuleStatementArgs.builder()
                        .notStatement(Map.of("statements", Map.of("andStatement", Map.of("statements",                         
                            RuleGroupRuleStatementArgs.builder()
                                .geoMatchStatement(RuleGroupRuleStatementGeoMatchStatementArgs.builder()
                                    .countryCodes("US")
                                    .build())
                                .build(),
                            RuleGroupRuleStatementArgs.builder()
                                .byteMatchStatement(RuleGroupRuleStatementByteMatchStatementArgs.builder()
                                    .positionalConstraint("CONTAINS")
                                    .searchString("word")
                                    .fieldToMatch(RuleGroupRuleStatementByteMatchStatementFieldToMatchArgs.builder()
                                        .allQueryArguments(RuleGroupRuleStatementByteMatchStatementFieldToMatchAllQueryArgumentsArgs.builder()
                                            .build())
                                        .build())
                                    .textTransformations(                                    
                                        RuleGroupRuleStatementByteMatchStatementTextTransformationArgs.builder()
                                            .priority(5)
                                            .type("CMD_LINE")
                                            .build(),
                                        RuleGroupRuleStatementByteMatchStatementTextTransformationArgs.builder()
                                            .priority(2)
                                            .type("LOWERCASE")
                                            .build())
                                    .build())
                                .build()))))
                        .build())
                    .visibilityConfig(RuleGroupRuleVisibilityConfigArgs.builder()
                        .cloudwatchMetricsEnabled(false)
                        .metricName("rule-1")
                        .sampledRequestsEnabled(false)
                        .build())
                    .build(),
                RuleGroupRuleArgs.builder()
                    .name("rule-2")
                    .priority(2)
                    .action(RuleGroupRuleActionArgs.builder()
                        .count(RuleGroupRuleActionCountArgs.builder()
                            .build())
                        .build())
                    .statement(RuleGroupRuleStatementArgs.builder()
                        .orStatement(RuleGroupRuleStatementOrStatementArgs.builder()
                            .statements(                            
                                RuleGroupRuleStatementArgs.builder()
                                    .regexMatchStatement(RuleGroupRuleStatementRegexMatchStatementArgs.builder()
                                        .regexString("a-z?")
                                        .fieldToMatch(RuleGroupRuleStatementRegexMatchStatementFieldToMatchArgs.builder()
                                            .singleHeader(RuleGroupRuleStatementRegexMatchStatementFieldToMatchSingleHeaderArgs.builder()
                                                .name("user-agent")
                                                .build())
                                            .build())
                                        .textTransformations(RuleGroupRuleStatementRegexMatchStatementTextTransformationArgs.builder()
                                            .priority(6)
                                            .type("NONE")
                                            .build())
                                        .build())
                                    .build(),
                                RuleGroupRuleStatementArgs.builder()
                                    .sqliMatchStatement(RuleGroupRuleStatementSqliMatchStatementArgs.builder()
                                        .fieldToMatch(RuleGroupRuleStatementSqliMatchStatementFieldToMatchArgs.builder()
                                            .body(RuleGroupRuleStatementSqliMatchStatementFieldToMatchBodyArgs.builder()
                                                .build())
                                            .build())
                                        .textTransformations(                                        
                                            RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs.builder()
                                                .priority(5)
                                                .type("URL_DECODE")
                                                .build(),
                                            RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs.builder()
                                                .priority(4)
                                                .type("HTML_ENTITY_DECODE")
                                                .build(),
                                            RuleGroupRuleStatementSqliMatchStatementTextTransformationArgs.builder()
                                                .priority(3)
                                                .type("COMPRESS_WHITE_SPACE")
                                                .build())
                                        .build())
                                    .build(),
                                RuleGroupRuleStatementArgs.builder()
                                    .xssMatchStatement(RuleGroupRuleStatementXssMatchStatementArgs.builder()
                                        .fieldToMatch(RuleGroupRuleStatementXssMatchStatementFieldToMatchArgs.builder()
                                            .method(RuleGroupRuleStatementXssMatchStatementFieldToMatchMethodArgs.builder()
                                                .build())
                                            .build())
                                        .textTransformations(RuleGroupRuleStatementXssMatchStatementTextTransformationArgs.builder()
                                            .priority(2)
                                            .type("NONE")
                                            .build())
                                        .build())
                                    .build())
                            .build())
                        .build())
                    .visibilityConfig(RuleGroupRuleVisibilityConfigArgs.builder()
                        .cloudwatchMetricsEnabled(false)
                        .metricName("rule-2")
                        .sampledRequestsEnabled(false)
                        .build())
                    .captchaConfig(RuleGroupRuleCaptchaConfigArgs.builder()
                        .immunityTimeProperty(RuleGroupRuleCaptchaConfigImmunityTimePropertyArgs.builder()
                            .immunityTime(240)
                            .build())
                        .build())
                    .build(),
                RuleGroupRuleArgs.builder()
                    .name("rule-3")
                    .priority(3)
                    .action(RuleGroupRuleActionArgs.builder()
                        .block(RuleGroupRuleActionBlockArgs.builder()
                            .build())
                        .build())
                    .statement(RuleGroupRuleStatementArgs.builder()
                        .sizeConstraintStatement(RuleGroupRuleStatementSizeConstraintStatementArgs.builder()
                            .comparisonOperator("GT")
                            .size(100)
                            .fieldToMatch(RuleGroupRuleStatementSizeConstraintStatementFieldToMatchArgs.builder()
                                .singleQueryArgument(RuleGroupRuleStatementSizeConstraintStatementFieldToMatchSingleQueryArgumentArgs.builder()
                                    .name("username")
                                    .build())
                                .build())
                            .textTransformations(RuleGroupRuleStatementSizeConstraintStatementTextTransformationArgs.builder()
                                .priority(5)
                                .type("NONE")
                                .build())
                            .build())
                        .build())
                    .visibilityConfig(RuleGroupRuleVisibilityConfigArgs.builder()
                        .cloudwatchMetricsEnabled(false)
                        .metricName("rule-3")
                        .sampledRequestsEnabled(false)
                        .build())
                    .build(),
                RuleGroupRuleArgs.builder()
                    .name("rule-4")
                    .priority(4)
                    .action(RuleGroupRuleActionArgs.builder()
                        .block(RuleGroupRuleActionBlockArgs.builder()
                            .build())
                        .build())
                    .statement(RuleGroupRuleStatementArgs.builder()
                        .orStatement(Map.of("statements",                         
                            RuleGroupRuleStatementArgs.builder()
                                .ipSetReferenceStatement(RuleGroupRuleStatementIpSetReferenceStatementArgs.builder()
                                    .arn(test.arn())
                                    .build())
                                .build(),
                            RuleGroupRuleStatementArgs.builder()
                                .regexPatternSetReferenceStatement(RuleGroupRuleStatementRegexPatternSetReferenceStatementArgs.builder()
                                    .arn(testRegexPatternSet.arn())
                                    .fieldToMatch(RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchArgs.builder()
                                        .singleHeader(RuleGroupRuleStatementRegexPatternSetReferenceStatementFieldToMatchSingleHeaderArgs.builder()
                                            .name("referer")
                                            .build())
                                        .build())
                                    .textTransformations(RuleGroupRuleStatementRegexPatternSetReferenceStatementTextTransformationArgs.builder()
                                        .priority(2)
                                        .type("NONE")
                                        .build())
                                    .build())
                                .build()))
                        .build())
                    .visibilityConfig(RuleGroupRuleVisibilityConfigArgs.builder()
                        .cloudwatchMetricsEnabled(false)
                        .metricName("rule-4")
                        .sampledRequestsEnabled(false)
                        .build())
                    .build())
            .visibilityConfig(RuleGroupVisibilityConfigArgs.builder()
                .cloudwatchMetricsEnabled(false)
                .metricName("friendly-metric-name")
                .sampledRequestsEnabled(false)
                .build())
            .captchaConfig(List.of(Map.of("immunityTimeProperty", List.of(Map.of("immunityTime", 120)))))
            .tags(Map.ofEntries(
                Map.entry("Name", "example-and-statement"),
                Map.entry("Code", "123456")
            ))
            .build());

    }
}
resources:
  test:
    type: aws:wafv2:IpSet
    properties:
      name: test
      scope: REGIONAL
      ipAddressVersion: IPV4
      addresses:
        - 1.1.1.1/32
        - 2.2.2.2/32
  testRegexPatternSet:
    type: aws:wafv2:RegexPatternSet
    name: test
    properties:
      name: test
      scope: REGIONAL
      regularExpressions:
        - regexString: one
  example:
    type: aws:wafv2:RuleGroup
    properties:
      name: complex-example
      description: An rule group containing all statements
      scope: REGIONAL
      capacity: 500
      rules:
        - name: rule-1
          priority: 1
          action:
            block: {}
          statement:
            notStatement:
              statements:
                - andStatement:
                    statements:
                      - geoMatchStatement:
                          countryCodes:
                            - US
                      - byteMatchStatement:
                          positionalConstraint: CONTAINS
                          searchString: word
                          fieldToMatch:
                            allQueryArguments: {}
                          textTransformations:
                            - priority: 5
                              type: CMD_LINE
                            - priority: 2
                              type: LOWERCASE
          visibilityConfig:
            cloudwatchMetricsEnabled: false
            metricName: rule-1
            sampledRequestsEnabled: false
        - name: rule-2
          priority: 2
          action:
            count: {}
          statement:
            orStatement:
              statements:
                - regexMatchStatement:
                    regexString: a-z?
                    fieldToMatch:
                      singleHeader:
                        name: user-agent
                    textTransformations:
                      - priority: 6
                        type: NONE
                - sqliMatchStatement:
                    fieldToMatch:
                      body: {}
                    textTransformations:
                      - priority: 5
                        type: URL_DECODE
                      - priority: 4
                        type: HTML_ENTITY_DECODE
                      - priority: 3
                        type: COMPRESS_WHITE_SPACE
                - xssMatchStatement:
                    fieldToMatch:
                      method: {}
                    textTransformations:
                      - priority: 2
                        type: NONE
          visibilityConfig:
            cloudwatchMetricsEnabled: false
            metricName: rule-2
            sampledRequestsEnabled: false
          captchaConfig:
            immunityTimeProperty:
              immunityTime: 240
        - name: rule-3
          priority: 3
          action:
            block: {}
          statement:
            sizeConstraintStatement:
              comparisonOperator: GT
              size: 100
              fieldToMatch:
                singleQueryArgument:
                  name: username
              textTransformations:
                - priority: 5
                  type: NONE
          visibilityConfig:
            cloudwatchMetricsEnabled: false
            metricName: rule-3
            sampledRequestsEnabled: false
        - name: rule-4
          priority: 4
          action:
            block: {}
          statement:
            orStatement:
              statements:
                - ipSetReferenceStatement:
                    arn: ${test.arn}
                - regexPatternSetReferenceStatement:
                    arn: ${testRegexPatternSet.arn}
                    fieldToMatch:
                      singleHeader:
                        name: referer
                    textTransformations:
                      - priority: 2
                        type: NONE
          visibilityConfig:
            cloudwatchMetricsEnabled: false
            metricName: rule-4
            sampledRequestsEnabled: false
      visibilityConfig:
        cloudwatchMetricsEnabled: false
        metricName: friendly-metric-name
        sampledRequestsEnabled: false
      captchaConfig:
        - immunityTimeProperty:
            - immunityTime: 120
      tags:
        Name: example-and-statement
        Code: '123456'

Logical operators nest statements to build complex conditions. The andStatement requires all nested conditions to match; orStatement matches if any condition is true; notStatement inverts the result. This example shows byteMatchStatement for string matching, ipSetReferenceStatement for IP-based filtering, and regexPatternSetReferenceStatement for pattern matching. The textTransformations array normalizes request data before evaluation, applying operations like URL decoding or lowercasing in priority order.

Define deeply nested rules with raw JSON

WAFv2’s structured rule format has a three-level nesting limit. When you need more complex logic, the rulesJson property accepts raw JSON that bypasses this constraint.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.wafv2.RuleGroup("example", {
    name: "example-rule-group",
    scope: "REGIONAL",
    capacity: 100,
    rulesJson: JSON.stringify([{
        Name: "rule-1",
        Priority: 1,
        Action: {
            Count: {},
        },
        Statement: {
            ByteMatchStatement: {
                SearchString: "badbot",
                FieldToMatch: {
                    UriPath: {},
                },
                TextTransformations: [{
                    Priority: 1,
                    Type: "NONE",
                }],
                PositionalConstraint: "CONTAINS",
            },
        },
        VisibilityConfig: {
            CloudwatchMetricsEnabled: false,
            MetricName: "friendly-rule-metric-name",
            SampledRequestsEnabled: false,
        },
    }]),
    visibilityConfig: {
        cloudwatchMetricsEnabled: false,
        metricName: "friendly-metric-name",
        sampledRequestsEnabled: false,
    },
});
import pulumi
import json
import pulumi_aws as aws

example = aws.wafv2.RuleGroup("example",
    name="example-rule-group",
    scope="REGIONAL",
    capacity=100,
    rules_json=json.dumps([{
        "Name": "rule-1",
        "Priority": 1,
        "Action": {
            "Count": {},
        },
        "Statement": {
            "ByteMatchStatement": {
                "SearchString": "badbot",
                "FieldToMatch": {
                    "UriPath": {},
                },
                "TextTransformations": [{
                    "Priority": 1,
                    "Type": "NONE",
                }],
                "PositionalConstraint": "CONTAINS",
            },
        },
        "VisibilityConfig": {
            "CloudwatchMetricsEnabled": False,
            "MetricName": "friendly-rule-metric-name",
            "SampledRequestsEnabled": False,
        },
    }]),
    visibility_config={
        "cloudwatch_metrics_enabled": False,
        "metric_name": "friendly-metric-name",
        "sampled_requests_enabled": False,
    })
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/wafv2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		tmpJSON0, err := json.Marshal([]map[string]interface{}{
			map[string]interface{}{
				"Name":     "rule-1",
				"Priority": 1,
				"Action": map[string]interface{}{
					"Count": map[string]interface{}{},
				},
				"Statement": map[string]interface{}{
					"ByteMatchStatement": map[string]interface{}{
						"SearchString": "badbot",
						"FieldToMatch": map[string]interface{}{
							"UriPath": map[string]interface{}{},
						},
						"TextTransformations": []map[string]interface{}{
							map[string]interface{}{
								"Priority": 1,
								"Type":     "NONE",
							},
						},
						"PositionalConstraint": "CONTAINS",
					},
				},
				"VisibilityConfig": map[string]interface{}{
					"CloudwatchMetricsEnabled": false,
					"MetricName":               "friendly-rule-metric-name",
					"SampledRequestsEnabled":   false,
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = wafv2.NewRuleGroup(ctx, "example", &wafv2.RuleGroupArgs{
			Name:      pulumi.String("example-rule-group"),
			Scope:     pulumi.String("REGIONAL"),
			Capacity:  pulumi.Int(100),
			RulesJson: pulumi.String(json0),
			VisibilityConfig: &wafv2.RuleGroupVisibilityConfigArgs{
				CloudwatchMetricsEnabled: pulumi.Bool(false),
				MetricName:               pulumi.String("friendly-metric-name"),
				SampledRequestsEnabled:   pulumi.Bool(false),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.WafV2.RuleGroup("example", new()
    {
        Name = "example-rule-group",
        Scope = "REGIONAL",
        Capacity = 100,
        RulesJson = JsonSerializer.Serialize(new[]
        {
            new Dictionary<string, object?>
            {
                ["Name"] = "rule-1",
                ["Priority"] = 1,
                ["Action"] = new Dictionary<string, object?>
                {
                    ["Count"] = new Dictionary<string, object?>
                    {
                    },
                },
                ["Statement"] = new Dictionary<string, object?>
                {
                    ["ByteMatchStatement"] = new Dictionary<string, object?>
                    {
                        ["SearchString"] = "badbot",
                        ["FieldToMatch"] = new Dictionary<string, object?>
                        {
                            ["UriPath"] = new Dictionary<string, object?>
                            {
                            },
                        },
                        ["TextTransformations"] = new[]
                        {
                            new Dictionary<string, object?>
                            {
                                ["Priority"] = 1,
                                ["Type"] = "NONE",
                            },
                        },
                        ["PositionalConstraint"] = "CONTAINS",
                    },
                },
                ["VisibilityConfig"] = new Dictionary<string, object?>
                {
                    ["CloudwatchMetricsEnabled"] = false,
                    ["MetricName"] = "friendly-rule-metric-name",
                    ["SampledRequestsEnabled"] = false,
                },
            },
        }),
        VisibilityConfig = new Aws.WafV2.Inputs.RuleGroupVisibilityConfigArgs
        {
            CloudwatchMetricsEnabled = false,
            MetricName = "friendly-metric-name",
            SampledRequestsEnabled = false,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.wafv2.RuleGroup;
import com.pulumi.aws.wafv2.RuleGroupArgs;
import com.pulumi.aws.wafv2.inputs.RuleGroupVisibilityConfigArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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 RuleGroup("example", RuleGroupArgs.builder()
            .name("example-rule-group")
            .scope("REGIONAL")
            .capacity(100)
            .rulesJson(serializeJson(
                jsonArray(jsonObject(
                    jsonProperty("Name", "rule-1"),
                    jsonProperty("Priority", 1),
                    jsonProperty("Action", jsonObject(
                        jsonProperty("Count", jsonObject(

                        ))
                    )),
                    jsonProperty("Statement", jsonObject(
                        jsonProperty("ByteMatchStatement", jsonObject(
                            jsonProperty("SearchString", "badbot"),
                            jsonProperty("FieldToMatch", jsonObject(
                                jsonProperty("UriPath", jsonObject(

                                ))
                            )),
                            jsonProperty("TextTransformations", jsonArray(jsonObject(
                                jsonProperty("Priority", 1),
                                jsonProperty("Type", "NONE")
                            ))),
                            jsonProperty("PositionalConstraint", "CONTAINS")
                        ))
                    )),
                    jsonProperty("VisibilityConfig", jsonObject(
                        jsonProperty("CloudwatchMetricsEnabled", false),
                        jsonProperty("MetricName", "friendly-rule-metric-name"),
                        jsonProperty("SampledRequestsEnabled", false)
                    ))
                ))))
            .visibilityConfig(RuleGroupVisibilityConfigArgs.builder()
                .cloudwatchMetricsEnabled(false)
                .metricName("friendly-metric-name")
                .sampledRequestsEnabled(false)
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:wafv2:RuleGroup
    properties:
      name: example-rule-group
      scope: REGIONAL
      capacity: 100
      rulesJson:
        fn::toJSON:
          - Name: rule-1
            Priority: 1
            Action:
              Count: {}
            Statement:
              ByteMatchStatement:
                SearchString: badbot
                FieldToMatch:
                  UriPath: {}
                TextTransformations:
                  - Priority: 1
                    Type: NONE
                PositionalConstraint: CONTAINS
            VisibilityConfig:
              CloudwatchMetricsEnabled: false
              MetricName: friendly-rule-metric-name
              SampledRequestsEnabled: false
      visibilityConfig:
        cloudwatchMetricsEnabled: false
        metricName: friendly-metric-name
        sampledRequestsEnabled: false

The rulesJson property takes a JSON string that follows the AWS WAFv2 API format. This approach trades drift detection for flexibility: Pulumi won’t detect changes made outside your configuration. Use this only when the three-level nesting limit blocks your requirements.

Beyond these examples

These snippets focus on specific rule group features: geographic and pattern-based filtering, logical operators, and IP sets and regex pattern references. They’re intentionally minimal rather than full WAF configurations.

The examples may reference pre-existing infrastructure such as IpSet and RegexPatternSet resources. They focus on rule group configuration rather than provisioning the complete WAF stack.

To keep things focused, common rule group patterns are omitted, including:

  • Custom response bodies for blocked requests
  • CAPTCHA configuration and immunity periods
  • Rate-based rules and request throttling
  • Managed rule group references

These omissions are intentional: the goal is to illustrate how each rule group feature is wired, not provide drop-in WAF modules. See the WAFv2 RuleGroup resource reference for all available configuration options.

Let's create AWS WAFv2 Rule Groups

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Immutability
What properties can't I change after creating a rule group?
The capacity, name, namePrefix, and scope properties are immutable. Changing any of these requires replacing the resource.
Can I use both name and namePrefix?
No, name and namePrefix conflict with each other. Use namePrefix to auto-generate unique names with a specified prefix.
Rules Definition
When should I use rulesJson instead of rules?
Use rulesJson only when you need more than 3 levels of nested statements. The tradeoff is that Pulumi won’t detect configuration drift between your code and AWS when using rulesJson.
Can I use both rules and rulesJson?
No, rules and rulesJson conflict with each other. Choose one based on your statement nesting requirements.
What happens when I import an existing rule group with rulesJson configured?
Importing with rulesJson set triggers a one-time in-place update as the remote rule configuration is initially written to the rule attribute. Subsequent applies should be stable.
CloudFront & Regional Deployment
How do I deploy a rule group for CloudFront?
Set scope to CLOUDFRONT and configure your AWS provider with region: us-east-1 (N. Virginia), as CloudFront requires this specific region.
What's the difference between CLOUDFRONT and REGIONAL scope?
CLOUDFRONT scope is for AWS CloudFront distributions and requires the us-east-1 region. REGIONAL scope is for regional applications and uses your provider’s configured region.

Using a different cloud?

Explore security guides for other cloud providers: