diff --git a/README.md b/README.md
index 9e595e3..4b95709 100644
--- a/README.md
+++ b/README.md
@@ -192,12 +192,14 @@ Available targets:
| Name | Source | Version |
|------|--------|---------|
+| [ip\_set\_label](#module\_ip\_set\_label) | cloudposse/label/null | 0.25.0 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
## Resources
| Name | Type |
|------|------|
+| [aws_wafv2_ip_set.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource |
| [aws_wafv2_web_acl.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl) | resource |
| [aws_wafv2_web_acl_association.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association) | resource |
| [aws_wafv2_web_acl_logging_configuration.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration) | resource |
@@ -221,7 +223,7 @@ Available targets:
| [geo\_allowlist\_statement\_rules](#input\_geo\_allowlist\_statement\_rules) | A rule statement used to identify a list of allowed countries which should not be blocked by the WAF.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
country\_codes:
A list of two-character country codes.
forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [geo\_match\_statement\_rules](#input\_geo\_match\_statement\_rules) | A rule statement used to identify web requests based on country of origin.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
country\_codes:
A list of two-character country codes.
forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no |
-| [ip\_set\_reference\_statement\_rules](#input\_ip\_set\_reference\_statement\_rules) | A rule statement used to detect web requests coming from particular IP addresses or address ranges.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
arn:
The ARN of the IP Set that this statement references.
ip\_set\_forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
position:
The position in the header to search for the IP address.
Possible values include: `FIRST`, `LAST`, or `ANY`.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
+| [ip\_set\_reference\_statement\_rules](#input\_ip\_set\_reference\_statement\_rules) | A rule statement used to detect web requests coming from particular IP addresses or address ranges.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
arn:
The ARN of the IP Set that this statement references.
ip\_set:
Defines a new IP Set
description:
A friendly description of the IP Set
addresses:
Contains an array of strings that specifies zero or more IP addresses or blocks of IP addresses.
All addresses must be specified using Classless Inter-Domain Routing (CIDR) notation.
ip\_address\_version:
Specify `IPV4` or `IPV6`
ip\_set\_forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
position:
The position in the header to search for the IP address.
Possible values include: `FIRST`, `LAST`, or `ANY`.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no |
| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no |
@@ -288,6 +290,7 @@ For additional context, refer to some of these links.
- [terraform-provider-aws](https://registry.terraform.io/providers/hashicorp/aws/latest) - Terraform AWS provider
- [aws_wafv2_web_acl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl.html) - Creates a WAFv2 Web ACL resource
- [aws_wafv2_web_acl_logging_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration.html) - Creates a WAFv2 Web ACL Logging Configuration
+- [aws_wafv2_ip_set](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) - Creates a WAFv2 Web ACL resource
## Help
diff --git a/README.yaml b/README.yaml
index b882ad6..4f8426b 100644
--- a/README.yaml
+++ b/README.yaml
@@ -67,6 +67,9 @@ references:
- name: aws_wafv2_web_acl_logging_configuration
description: Creates a WAFv2 Web ACL Logging Configuration
url: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration.html
+ - name: aws_wafv2_ip_set
+ description: Creates a WAFv2 Web ACL resource
+ url: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set
description: |-
Terraform module to create and manage AWS WAFv2 rules.
diff --git a/docs/terraform.md b/docs/terraform.md
index 60a922c..b8ad85f 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -16,12 +16,14 @@
| Name | Source | Version |
|------|--------|---------|
+| [ip\_set\_label](#module\_ip\_set\_label) | cloudposse/label/null | 0.25.0 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
## Resources
| Name | Type |
|------|------|
+| [aws_wafv2_ip_set.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource |
| [aws_wafv2_web_acl.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl) | resource |
| [aws_wafv2_web_acl_association.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_association) | resource |
| [aws_wafv2_web_acl_logging_configuration.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration) | resource |
@@ -45,7 +47,7 @@
| [geo\_allowlist\_statement\_rules](#input\_geo\_allowlist\_statement\_rules) | A rule statement used to identify a list of allowed countries which should not be blocked by the WAF.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
country\_codes:
A list of two-character country codes.
forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [geo\_match\_statement\_rules](#input\_geo\_match\_statement\_rules) | A rule statement used to identify web requests based on country of origin.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
country\_codes:
A list of two-character country codes.
forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no |
-| [ip\_set\_reference\_statement\_rules](#input\_ip\_set\_reference\_statement\_rules) | A rule statement used to detect web requests coming from particular IP addresses or address ranges.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
arn:
The ARN of the IP Set that this statement references.
ip\_set\_forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
position:
The position in the header to search for the IP address.
Possible values include: `FIRST`, `LAST`, or `ANY`.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
+| [ip\_set\_reference\_statement\_rules](#input\_ip\_set\_reference\_statement\_rules) | A rule statement used to detect web requests coming from particular IP addresses or address ranges.
action:
The action that AWS WAF should take on a web request when it matches the rule's statement.
name:
A friendly name of the rule.
priority:
If you define more than one Rule in a WebACL,
AWS WAF evaluates each request against the rules in order based on the value of priority.
AWS WAF processes rules with lower priority first.
captcha\_config:
Specifies how AWS WAF should handle CAPTCHA evaluations.
immunity\_time\_property:
Defines custom immunity time.
immunity\_time:
The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.
rule\_label:
A List of labels to apply to web requests that match the rule match statement
statement:
arn:
The ARN of the IP Set that this statement references.
ip\_set:
Defines a new IP Set
description:
A friendly description of the IP Set
addresses:
Contains an array of strings that specifies zero or more IP addresses or blocks of IP addresses.
All addresses must be specified using Classless Inter-Domain Routing (CIDR) notation.
ip\_address\_version:
Specify `IPV4` or `IPV6`
ip\_set\_forwarded\_ip\_config:
fallback\_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.
Possible values: `MATCH`, `NO_MATCH`
header\_name:
The name of the HTTP header to use for the IP address.
position:
The position in the header to search for the IP address.
Possible values include: `FIRST`, `LAST`, or `ANY`.
visibility\_config:
Defines and enables Amazon CloudWatch metrics and web request sample collection.
cloudwatch\_metrics\_enabled:
Whether the associated resource sends metrics to CloudWatch.
metric\_name:
A friendly name of the CloudWatch metric.
sampled\_requests\_enabled:
Whether AWS WAF should store a sampling of the web requests that match the rules. | `list(any)` | `null` | no |
| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no |
| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no |
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index f7877ce..56bec7e 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -254,5 +254,26 @@ module "waf" {
}
]
+ ip_set_reference_statement_rules = [
+ {
+ name = "rule-100"
+ priority = 100
+ action = "block"
+
+ statement = {
+ ip_set = {
+ ip_address_version = "IPV4"
+ addresses = ["17.0.0.0/8"]
+ }
+ }
+
+ visibility_config = {
+ cloudwatch_metrics_enabled = false
+ sampled_requests_enabled = false
+ metric_name = "rule-100-metric"
+ }
+ }
+ ]
+
context = module.this.context
}
diff --git a/ipset.tf b/ipset.tf
new file mode 100644
index 0000000..529876e
--- /dev/null
+++ b/ipset.tf
@@ -0,0 +1,34 @@
+locals {
+ ip_sets = local.enabled && var.ip_set_reference_statement_rules != null ? {
+ for indx, rule in flatten(var.ip_set_reference_statement_rules) :
+ lookup(rule, "name", null) != null ? format("%s-ip-set", rule.name) : format("ip-set-%d", rule.priority)
+ => rule.statement.ip_set if try(rule.statement.ip_set, null) != null && try(rule.statement.arn, null) == null
+ } : {}
+
+ ip_rule_to_ip_set = local.enabled && local.ip_set_reference_statement_rules != null ? {
+ for name, rule in local.ip_set_reference_statement_rules :
+ name => lookup(rule, "name", null) != null ? format("%s-ip-set", rule.name) : format("ip-set-%d", rule.priority)
+ } : {}
+}
+
+module "ip_set_label" {
+ for_each = local.ip_sets
+
+ source = "cloudposse/label/null"
+ version = "0.25.0"
+
+ attributes = [each.key]
+ context = module.this.context
+}
+
+resource "aws_wafv2_ip_set" "default" {
+ for_each = local.ip_sets
+
+ name = module.ip_set_label[each.key].id
+ description = lookup(each.value, "description", null)
+ scope = var.scope
+ ip_address_version = each.value.ip_address_version
+ addresses = each.value.addresses
+
+ tags = module.this.tags
+}
diff --git a/rules.tf b/rules.tf
index a7482bd..bf42f95 100644
--- a/rules.tf
+++ b/rules.tf
@@ -420,7 +420,7 @@ resource "aws_wafv2_web_acl" "default" {
for_each = lookup(rule.value, "statement", null) != null ? [rule.value.statement] : []
content {
- arn = ip_set_reference_statement.value.arn
+ arn = try(aws_wafv2_ip_set.default[local.ip_rule_to_ip_set[rule.key]], null) != null ? aws_wafv2_ip_set.default[local.ip_rule_to_ip_set[rule.key]].arn : ip_set_reference_statement.value.arn
dynamic "ip_set_forwarded_ip_config" {
for_each = lookup(ip_set_reference_statement.value, "ip_set_forwarded_ip_config", null) != null ? [ip_set_reference_statement.value.ip_set_forwarded_ip_config] : []
diff --git a/variables.tf b/variables.tf
index 4250e32..4cafb8d 100644
--- a/variables.tf
+++ b/variables.tf
@@ -329,6 +329,16 @@ variable "ip_set_reference_statement_rules" {
statement:
arn:
The ARN of the IP Set that this statement references.
+ ip_set:
+ Defines a new IP Set
+
+ description:
+ A friendly description of the IP Set
+ addresses:
+ Contains an array of strings that specifies zero or more IP addresses or blocks of IP addresses.
+ All addresses must be specified using Classless Inter-Domain Routing (CIDR) notation.
+ ip_address_version:
+ Specify `IPV4` or `IPV6`
ip_set_forwarded_ip_config:
fallback_behavior:
The match status to assign to the web request if the request doesn't have a valid IP address in the specified position.