Skip to content

Commit

Permalink
add additional waf features (#791)
Browse files Browse the repository at this point in the history
Co-authored-by: Dan Miller <[email protected]>
Co-authored-by: Igor Rodionov <[email protected]>
  • Loading branch information
3 people authored Oct 1, 2024
1 parent 207fba8 commit e9f6568
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 1 deletion.
4 changes: 4 additions & 0 deletions modules/waf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ components:
| Name | Type |
|------|------|
| [aws_ssm_parameter.acl_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource |
| [aws_alb.alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/alb) | data source |
| [aws_lbs.alb_by_tags](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lbs) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_acl_name"></a> [acl\_name](#input\_acl\_name) | Friendly name of the ACL. The ACL ARN will be stored in SSM under {ssm\_path\_prefix}/{acl\_name}/arn | `string` | n/a | yes |
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.<br>This is for some rare cases where resources want additional configuration of tags<br>and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
| <a name="input_alb_names"></a> [alb\_names](#input\_alb\_names) | list of ALB names to associate with the web ACL. | `list(string)` | `[]` | no |
| <a name="input_alb_tags"></a> [alb\_tags](#input\_alb\_tags) | list of tags to match one or more ALBs to associate with the web ACL. | `list(map(string))` | `[]` | no |
| <a name="input_association_resource_arns"></a> [association\_resource\_arns](#input\_association\_resource\_arns) | A list of ARNs of the resources to associate with the web ACL.<br>This must be an ARN of an Application Load Balancer, Amazon API Gateway stage, or AWS AppSync.<br><br>Do not use this variable to associate a Cloudfront Distribution.<br>Instead, you should use the `web_acl_id` property on the `cloudfront_distribution` resource.<br>For more details, refer to https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html | `list(string)` | `[]` | no |
| <a name="input_association_resource_component_selectors"></a> [association\_resource\_component\_selectors](#input\_association\_resource\_component\_selectors) | A list of Atmos component selectors to get from the remote state and associate their ARNs with the web ACL.<br>The components must be Application Load Balancers, Amazon API Gateway stages, or AWS AppSync.<br><br>component:<br> Atmos component name<br>component\_arn\_output:<br> The component output that defines the component ARN<br><br>Set `tenant`, `environment` and `stage` if the components are in different OUs, regions or accounts.<br><br>Do not use this variable to select a Cloudfront Distribution component.<br>Instead, you should use the `web_acl_id` property on the `cloudfront_distribution` resource.<br>For more details, refer to https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html | <pre>list(object({<br> component = string<br> namespace = optional(string, null)<br> tenant = optional(string, null)<br> environment = optional(string, null)<br> stage = optional(string, null)<br> component_arn_output = string<br> }))</pre> | `[]` | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,<br>in the order they appear in the list. New attributes are appended to the<br>end of the list. The elements of the list are joined by the `delimiter`<br>and treated as a single ID element. | `list(string)` | `[]` | no |
Expand Down
15 changes: 15 additions & 0 deletions modules/waf/alb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
locals {
alb_arns = concat(local.alb_name_arns, local.alb_tag_arns)
alb_name_arns = [for alb_instance in data.aws_alb.alb : alb_instance.arn]
alb_tag_arns = flatten([for alb_instance in data.aws_lbs.alb_by_tags : alb_instance.arns])
}

data "aws_alb" "alb" {
for_each = toset(var.alb_names)
name = each.key
}

data "aws_lbs" "alb_by_tags" {
for_each = { for i, v in var.alb_tags : i => v }
tags = each.value
}
2 changes: 1 addition & 1 deletion modules/waf/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ locals {
if local.enabled
]

association_resource_arns = concat(var.association_resource_arns, local.association_resource_component_selectors_arns)
association_resource_arns = toset(concat(var.association_resource_arns, local.association_resource_component_selectors_arns, local.alb_arns))

log_destination_component_selectors = [
for i, v in var.log_destination_component_selectors : module.log_destination_components[i].outputs[v.component_output]
Expand Down
Empty file modified modules/waf/remote-state.tf
100644 → 100755
Empty file.
113 changes: 113 additions & 0 deletions modules/waf/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,119 @@ variable "token_domains" {
default = null
}

# Logging configuration
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl_logging_configuration.html
variable "log_destination_configs" {
type = list(string)
default = []
description = "The Amazon Kinesis Data Firehose, CloudWatch Log log group, or S3 bucket Amazon Resource Names (ARNs) that you want to associate with the web ACL"
}

variable "redacted_fields" {
type = map(object({
method = optional(bool, false)
uri_path = optional(bool, false)
query_string = optional(bool, false)
single_header = optional(list(string), null)
}))
default = {}
description = <<-DOC
The parts of the request that you want to keep out of the logs.
You can only specify one of the following: `method`, `query_string`, `single_header`, or `uri_path`
method:
Whether to enable redaction of the HTTP method.
The method indicates the type of operation that the request is asking the origin to perform.
uri_path:
Whether to enable redaction of the URI path.
This is the part of a web request that identifies a resource.
query_string:
Whether to enable redaction of the query string.
This is the part of a URL that appears after a `?` character, if any.
single_header:
The list of names of the query headers to redact.
DOC
nullable = false
}

variable "logging_filter" {
type = object({
default_behavior = string
filter = list(object({
behavior = string
requirement = string
condition = list(object({
action_condition = optional(object({
action = string
}), null)
label_name_condition = optional(object({
label_name = string
}), null)
}))
}))
})
default = null
description = <<-DOC
A configuration block that specifies which web requests are kept in the logs and which are dropped.
You can filter on the rule action and on the web request labels that were applied by matching rules during web ACL evaluation.
DOC
}

# Association resources
variable "association_resource_arns" {
type = list(string)
default = []
description = <<-DOC
A list of ARNs of the resources to associate with the web ACL.
This must be an ARN of an Application Load Balancer, Amazon API Gateway stage, or AWS AppSync.
Do not use this variable to associate a Cloudfront Distribution.
Instead, you should use the `web_acl_id` property on the `cloudfront_distribution` resource.
For more details, refer to https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html
DOC
nullable = false
}

variable "alb_names" {
description = "list of ALB names to associate with the web ACL."
type = list(string)
default = []
nullable = false
}

variable "alb_tags" {
description = "list of tags to match one or more ALBs to associate with the web ACL."
type = list(map(string))
default = []
nullable = false
}

variable "association_resource_component_selectors" {
type = list(object({
component = string
namespace = optional(string, null)
tenant = optional(string, null)
environment = optional(string, null)
stage = optional(string, null)
component_arn_output = string
}))
default = []
description = <<-DOC
A list of Atmos component selectors to get from the remote state and associate their ARNs with the web ACL.
The components must be Application Load Balancers, Amazon API Gateway stages, or AWS AppSync.
component:
Atmos component name
component_arn_output:
The component output that defines the component ARN
Do not use this variable to select a Cloudfront Distribution component.
Instead, you should use the `web_acl_id` property on the `cloudfront_distribution` resource.
For more details, refer to https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html
DOC
nullable = false
}

# Rules
variable "byte_match_statement_rules" {
type = list(object({
Expand Down

0 comments on commit e9f6568

Please sign in to comment.