import * as pulumi from "@pulumi/pulumi"; import * as inputs from "../types/input"; import * as outputs from "../types/output"; /** * Manages an individual rule within a WAFv2 Web ACL. This resource creates proper Terraform dependencies for safe deletion of referenced resources like IP sets, solving the `WAFAssociatedItemException` error that occurs when deleting IP sets that are still referenced by Web ACL rules. * * > **NOTE:** When using this resource, you must add `lifecycle { ignoreChanges = [rule] }` to your `aws.wafv2.WebAcl` resource to prevent conflicts. See the `aws.wafv2.WebAcl` documentation for a full description of the limitations of inline rules that this resource addresses. * * ## Example Usage * * ### Migrating from Inline Rules * * This resource supports a "create-or-adopt" pattern that allows seamless migration from inline Web ACL rules to separate `aws.wafv2.WebAclRule` resources without infrastructure changes. * * When you create an `aws.wafv2.WebAclRule` resource with the same name as an existing inline rule in the Web ACL, the resource will automatically adopt the existing rule instead of creating a duplicate. This enables zero-downtime migration from inline rules to separate resources. * * Starting with inline rules, update your configuration to use separate rule resources and apply: * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const example = new aws.wafv2.WebAcl("example", { * defaultAction: { * allow: {}, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: false, * metricName: "example", * sampledRequestsEnabled: false, * }, * name: "example", * scope: "REGIONAL", * }, { * ignoreChanges: ["rules"], * }); * // Separate rule resource with identical configuration * const blockCountries = new aws.wafv2.WebAclRule("block_countries", { * action: { * block: {}, * }, * statement: { * geoMatchStatement: { * countryCodes: [ * "CN", * "RU", * ], * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: false, * metricName: "block-countries", * sampledRequestsEnabled: false, * }, * name: "block-countries", * priority: 1, * webAclArn: example.arn, * }); * ``` * * Apply the configuration: * * The `aws.wafv2.WebAclRule` resource will adopt the existing inline rule without making any changes to the actual Web ACL infrastructure. The rule continues to function identically, but is now managed as a separate Terraform resource. * * - The rule name in the `aws.wafv2.WebAclRule` resource must exactly match the existing inline rule name * - Add `lifecycle { ignoreChanges = [rule] }` to your Web ACL resource to prevent conflicts * - The create-or-adopt behavior only applies when a rule with the same name already exists in the Web ACL * * ### Basic Geo Match Rule * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const example = new aws.wafv2.WebAcl("example", { * defaultAction: { * allow: {}, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: false, * metricName: "example", * sampledRequestsEnabled: false, * }, * name: "example", * scope: "REGIONAL", * }, { * ignoreChanges: ["rules"], * }); * const blockCountries = new aws.wafv2.WebAclRule("block_countries", { * action: { * block: {}, * }, * statement: { * geoMatchStatement: { * countryCodes: [ * "CN", * "RU", * ], * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: false, * metricName: "block-countries", * sampledRequestsEnabled: false, * }, * name: "block-countries", * priority: 1, * webAclArn: example.arn, * }); * ``` * * ### IP Set Reference (Solves Deletion Ordering) * * This example demonstrates the primary use case: referencing an IP set in a way that allows safe deletion. * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const blockedIps = new aws.wafv2.IpSet("blocked_ips", { * name: "blocked-ips", * scope: "REGIONAL", * ipAddressVersion: "IPV4", * addresses: [ * "1.2.3.4/32", * "5.6.7.8/32", * ], * }); * const example = new aws.wafv2.WebAcl("example", { * defaultAction: { * allow: {}, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "example", * sampledRequestsEnabled: true, * }, * name: "example", * scope: "REGIONAL", * }, { * ignoreChanges: ["rules"], * }); * const blockIps = new aws.wafv2.WebAclRule("block_ips", { * action: { * block: {}, * }, * statement: { * ipSetReferenceStatement: { * arn: blockedIps.arn, * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "block-bad-ips", * sampledRequestsEnabled: true, * }, * name: "block-bad-ips", * priority: 1, * webAclArn: example.arn, * }); * ``` * * ### Rate-Based Rule * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const rateLimit = new aws.wafv2.WebAclRule("rate_limit", { * action: { * block: {}, * }, * statement: { * rateBasedStatement: { * limit: 2000, * aggregateKeyType: "IP", * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "rate-limit", * sampledRequestsEnabled: true, * }, * name: "rate-limit", * priority: 2, * webAclArn: example.arn, * }); * ``` * * ### Managed Rule Group with Override Action * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const awsManagedRules = new aws.wafv2.WebAclRule("aws_managed_rules", { * overrideAction: { * none: {}, * }, * statement: { * managedRuleGroupStatement: { * name: "AWSManagedRulesCommonRuleSet", * vendorName: "AWS", * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "aws-managed-rules", * sampledRequestsEnabled: true, * }, * name: "aws-managed-rules", * priority: 3, * webAclArn: example.arn, * }); * ``` * * ### Custom Request Handling * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const captchaWithHeaders = new aws.wafv2.WebAclRule("captcha_with_headers", { * action: { * captcha: { * customRequestHandling: { * insertHeaders: [{ * name: "x-captcha-rule", * value: "triggered", * }], * }, * }, * }, * statement: { * geoMatchStatement: { * countryCodes: ["US"], * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "captcha-with-headers", * sampledRequestsEnabled: true, * }, * name: "captcha-with-headers", * priority: 4, * webAclArn: example.arn, * }); * ``` * * ### IP Set Reference * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const blockedIps = new aws.wafv2.WebAclRule("blocked_ips", { * action: { * block: {}, * }, * statement: { * ipSetReferenceStatement: { * arn: blockedIpsAwsWafv2IpSet.arn, * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "block-bad-ips", * sampledRequestsEnabled: true, * }, * name: "blocked-ips", * priority: 1, * webAclArn: example.arn, * }); * ``` * * With this configuration, when you remove both the `aws.wafv2.WebAclRule` and `aws.wafv2.IpSet` resources, Terraform will: * * 1. Delete the rule first (removing the reference from the Web ACL) * 2. Delete the IP set second (now safe because it's no longer referenced) * * This prevents the `WAFAssociatedItemException` error. * * ### Logical AND Statement * * Block requests that match multiple conditions (e.g., from a specific country AND containing a specific string): * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const blockSuspicious = new aws.wafv2.WebAclRule("block_suspicious", { * action: { * block: {}, * }, * statement: { * andStatement: { * statements: [ * { * geoMatchStatement: { * countryCodes: ["CN"], * }, * }, * { * byteMatchStatement: { * fieldToMatch: { * uriPath: {}, * }, * textTransformations: [{ * priority: 0, * type: "LOWERCASE", * }], * searchString: "admin", * positionalConstraint: "CONTAINS", * }, * }, * ], * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "block-suspicious", * sampledRequestsEnabled: true, * }, * name: "block-suspicious", * priority: 1, * webAclArn: example.arn, * }); * ``` * * ### Logical OR Statement * * Block requests that match any of multiple conditions: * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const blockCountries = new aws.wafv2.WebAclRule("block_countries", { * action: { * block: {}, * }, * statement: { * orStatement: { * statements: [ * { * geoMatchStatement: { * countryCodes: ["CN"], * }, * }, * { * geoMatchStatement: { * countryCodes: ["RU"], * }, * }, * ], * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "block-countries", * sampledRequestsEnabled: true, * }, * name: "block-countries", * priority: 2, * webAclArn: example.arn, * }); * ``` * * ### Logical NOT Statement * * Allow requests only from specific countries by negating a geo match: * * ```typescript * import * as pulumi from "@pulumi/pulumi"; * import * as aws from "@pulumi/aws"; * * const allowOnlyUs = new aws.wafv2.WebAclRule("allow_only_us", { * action: { * block: {}, * }, * statement: { * notStatement: { * statement: { * geoMatchStatement: { * countryCodes: [ * "US", * "CA", * ], * }, * }, * }, * }, * visibilityConfig: { * cloudwatchMetricsEnabled: true, * metricName: "allow-only-us", * sampledRequestsEnabled: true, * }, * name: "allow-only-us", * priority: 3, * webAclArn: example.arn, * }); * ``` * * ## Import * * ### Identity Schema * * #### Required * * * `name` (String) Rule name, unique within the Web ACL. * * `webAclArn` (String) ARN of the Web ACL. * * #### Optional * * * `accountId` (String) Account ID where this resource is managed. * * `region` (String) Region where this resource is managed. * * Using `pulumi import`, import WAFv2 Web ACL Rules using the `webAclArn` and `name` separated by a comma (`,`). For example: * * ```sh * $ pulumi import aws:wafv2/webAclRule:WebAclRule example arn:aws:wafv2:us-east-1:123456789012:regional/webacl/example/abc123def456,my-rule * ``` */ export declare class WebAclRule extends pulumi.CustomResource { /** * Get an existing WebAclRule resource's state with the given name, ID, and optional extra * properties used to qualify the lookup. * * @param name The _unique_ name of the resulting resource. * @param id The _unique_ provider ID of the resource to lookup. * @param state Any extra arguments used during the lookup. * @param opts Optional settings to control the behavior of the CustomResource. */ static get(name: string, id: pulumi.Input, state?: WebAclRuleState, opts?: pulumi.CustomResourceOptions): WebAclRule; /** * Returns true if the given object is an instance of WebAclRule. This is designed to work even * when multiple copies of the Pulumi SDK have been loaded into the same process. */ static isInstance(obj: any): obj is WebAclRule; /** * Action to take when the rule matches. See Action below. Conflicts with `overrideAction`. */ readonly action: pulumi.Output; /** * CAPTCHA configuration that overrides the web ACL level setting. See Captcha Config below. */ readonly captchaConfig: pulumi.Output; /** * Challenge configuration that overrides the web ACL level setting. See Challenge Config below. */ readonly challengeConfig: pulumi.Output; /** * Name of the rule. Must be unique within the Web ACL. */ readonly name: pulumi.Output; /** * Override action for managed rule groups. See Override Action below. Conflicts with `action`. */ readonly overrideAction: pulumi.Output; /** * Rule priority. Rules with lower priority are evaluated first. */ readonly priority: pulumi.Output; /** * Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the provider configuration. */ readonly region: pulumi.Output; /** * Labels to apply to matching web requests. See Rule Label below. */ readonly ruleLabels: pulumi.Output; /** * Rule statement. See Statement below. */ readonly statement: pulumi.Output; readonly timeouts: pulumi.Output; /** * CloudWatch metrics configuration. See Visibility Config below. */ readonly visibilityConfig: pulumi.Output; /** * ARN of the Web ACL to add the rule to. * * The following arguments are optional: */ readonly webAclArn: pulumi.Output; /** * Create a WebAclRule resource with the given unique name, arguments, and options. * * @param name The _unique_ name of the resource. * @param args The arguments to use to populate this resource's properties. * @param opts A bag of options that control this resource's behavior. */ constructor(name: string, args: WebAclRuleArgs, opts?: pulumi.CustomResourceOptions); } /** * Input properties used for looking up and filtering WebAclRule resources. */ export interface WebAclRuleState { /** * Action to take when the rule matches. See Action below. Conflicts with `overrideAction`. */ action?: pulumi.Input; /** * CAPTCHA configuration that overrides the web ACL level setting. See Captcha Config below. */ captchaConfig?: pulumi.Input; /** * Challenge configuration that overrides the web ACL level setting. See Challenge Config below. */ challengeConfig?: pulumi.Input; /** * Name of the rule. Must be unique within the Web ACL. */ name?: pulumi.Input; /** * Override action for managed rule groups. See Override Action below. Conflicts with `action`. */ overrideAction?: pulumi.Input; /** * Rule priority. Rules with lower priority are evaluated first. */ priority?: pulumi.Input; /** * Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the provider configuration. */ region?: pulumi.Input; /** * Labels to apply to matching web requests. See Rule Label below. */ ruleLabels?: pulumi.Input[] | undefined>; /** * Rule statement. See Statement below. */ statement?: pulumi.Input; timeouts?: pulumi.Input; /** * CloudWatch metrics configuration. See Visibility Config below. */ visibilityConfig?: pulumi.Input; /** * ARN of the Web ACL to add the rule to. * * The following arguments are optional: */ webAclArn?: pulumi.Input; } /** * The set of arguments for constructing a WebAclRule resource. */ export interface WebAclRuleArgs { /** * Action to take when the rule matches. See Action below. Conflicts with `overrideAction`. */ action?: pulumi.Input; /** * CAPTCHA configuration that overrides the web ACL level setting. See Captcha Config below. */ captchaConfig?: pulumi.Input; /** * Challenge configuration that overrides the web ACL level setting. See Challenge Config below. */ challengeConfig?: pulumi.Input; /** * Name of the rule. Must be unique within the Web ACL. */ name?: pulumi.Input; /** * Override action for managed rule groups. See Override Action below. Conflicts with `action`. */ overrideAction?: pulumi.Input; /** * Rule priority. Rules with lower priority are evaluated first. */ priority: pulumi.Input; /** * Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the provider configuration. */ region?: pulumi.Input; /** * Labels to apply to matching web requests. See Rule Label below. */ ruleLabels?: pulumi.Input[] | undefined>; /** * Rule statement. See Statement below. */ statement?: pulumi.Input; timeouts?: pulumi.Input; /** * CloudWatch metrics configuration. See Visibility Config below. */ visibilityConfig?: pulumi.Input; /** * ARN of the Web ACL to add the rule to. * * The following arguments are optional: */ webAclArn: pulumi.Input; } //# sourceMappingURL=webAclRule.d.ts.map