Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/trussworks/terraform-aws-waf

Configures an AWS Web Application Firewall.
https://github.com/trussworks/terraform-aws-waf

aws aws-waf terraform terraform-modules

Last synced: 1 day ago
JSON representation

Configures an AWS Web Application Firewall.

Awesome Lists containing this project

README

        

Creates a WAF and associates it with an Application Load Balancer (ALB)

Creates the following resources:

- Web Application Firewall (WAF)
- Links F5-managed OWASP rules for WAF to block common attacks
- Creates rule for WAF to block requests by source IP Address (**Note**: the list of blocked IPs are not managed by this module)
- Creates rule for WAF to block requests by path (as found in URI)
- Creates rule for WAF to allow requests by host (as found in HTTP Header)
- Attaches WAF to Application Load Balancer (ALB)

## Usage

```hcl
resource "aws_wafregional_rate_based_rule" "ipratelimit" {
name = "app-global-ip-rate-limit"
metric_name = "wafAppGlobalIpRateLimit"
rate_key = "IP"
rate_limit = 2000
}

module "waf" {
source = "trussworks/waf/aws"

alb_arn = module.alb_web_containers.alb_arn
associate_alb = true
allowed_hosts = [var.domain_name]
blocked_path_prefixes = var.blocked_path_prefixes
ip_sets = var.ip_sets
rate_based_rules = [aws_wafregional_rate_based_rule.ipratelimit.id]
rules = var.rules
wafregional_rule_f5_id = var.wafregional_rule_id
web_acl_metric_name = "wafAppHelloWorld"
web_acl_name = "app-hello-world"
}
```

## Requirements

| Name | Version |
|------|---------|
| terraform | >= 1.0 |
| aws | >= 3.0 |

## Providers

| Name | Version |
|------|---------|
| aws | >= 3.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_wafregional_byte_match_set.allowed_hosts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_byte_match_set) | resource |
| [aws_wafregional_byte_match_set.blocked_path_prefixes](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_byte_match_set) | resource |
| [aws_wafregional_rule.allowed_hosts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_rule) | resource |
| [aws_wafregional_rule.blocked_path_prefixes](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_rule) | resource |
| [aws_wafregional_rule.ips](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_rule) | resource |
| [aws_wafregional_web_acl.wafacl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_web_acl) | resource |
| [aws_wafregional_web_acl_association.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafregional_web_acl_association) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| alb\_arn | ARN of the Application Load Balancer (ALB) to be associated with the Web Application Firewall (WAF) Access Control List (ACL). | `string` | n/a | yes |
| allowed\_hosts | The list of allowed host names as specified in HOST header. | `list(string)` | n/a | yes |
| associate\_alb | Whether to associate an Application Load Balancer (ALB) with an Web Application Firewall (WAF) Access Control List (ACL). | `bool` | `false` | no |
| blocked\_path\_prefixes | The list of URI path prefixes to block using the WAF. | `list(string)` | `[]` | no |
| ip\_sets | List of sets of IP addresses to block. | `list(string)` | `[]` | no |
| rate\_based\_rules | List of IDs of Rate-Based Rules to add to this WAF. Only use this variable for rate-based rules. Use the "rules" variable for regular rules. | `list(string)` | `[]` | no |
| rules | List of IDs of Rules to add to this WAF. Only use this variable for regular rules. Use the "rate\_based\_rules" variable for rate-based rules. | `list(string)` | `[]` | no |
| wafregional\_rule\_f5\_id | The ID of the F5 Rule Group to use for the WAF for the ALB. Find the id with "aws waf-regional list-subscribed-rule-groups". | `string` | `""` | no |
| web\_acl\_metric\_name | Metric name of the Web ACL | `string` | n/a | yes |
| web\_acl\_name | Name of the Web ACL | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| waf\_acl\_id | WAF ACL ID generated by the module |

## Upgrade Path

### 2.0.0 to 2.1.0

Version `2.1.0` removes the `ip_rate_limit` variables and replaces it with a `rate_based_rules` variable. The new variable accepts a list of `aws_wafregional_rate_based_rule` ids. This variables allows the Web ACL to use a global rate limit or provide custom rate limits for different paths.

```hcl
resource "aws_wafregional_rate_based_rule" "ipratelimit" {
name = "app-global-ip-rate-limit"
metric_name = "wafAppGlobalIpRateLimit"

rate_key = "IP"
rate_limit = 2000
}
```

Use `terraform state mv` to externalize the rate limit rule, e.g., `terraform state mv FOO.BAR.aws_wafregional_rate_based_rule.ipratelimit Foo.aws_wafregional_rate_based_rule.ipratelimit`.

Version `2.1.0` removes the `regex_host_allow_pattern_strings` variable and replaces it with a required `allowed_hosts` variable. That variable now takes a list of fully qualified domain names rather than regex strings. If you ALB supports multiple domain names, each domain name will need to be added to the list.

Version `2.1.0` removes the `regex_path_disallow_pattern_strings` variable and replaces it with an optional `blocked_path_prefixes` variable. That variable now takes a list of URI path prefixes rather than regex strings.

Version `2.1.0` adds the `rules` variable which accepts a list of rule ids, which will be appended to the internally-managed rules.

### 1.3.0 to 2.0.0

Version `2.0.0` removes the `environment` variable and adds `web_acl_metric_name` and `web_acl_name` variables to provide more control over naming. AWS WAF rules will be prefixed by the `web_acl_name` of their associated Web ACL to provide for easy visual sorting.

Version `2.0.0` replaces the `ip_set` variable with a `ip_sets` list variable, which accepts a list of `aws_wafregional_ipset` ids. This variable allows the Web ACL to pull from multiple lists of blocked ip addresses, such that you can combine a global blocked list, and application-specific lists. For example: `ip_sets = [resource.aws_wafregional_ipset.global.id, resource.aws_wafregional_ipset.helloworld.id]`.

During the initial upgrade to `2.0.0`, and if you add additional dynamic rules, you'll need to delete your web ACLs, as terraform cannot properly handle peer dependencies between Rules and Web ACLs. For convenience, you can use the `delete-web-acl` script in the scripts folder. For example: `scripts/delete-web-acl WEB_ACL_ID`. Once the Web ACL is deleted use terraform apply to recreate the Web ACL and associate with your resources as you had before. Deleting a Web ACL does not delete any associated resources, such as Application Load Balancers; however, it will leave the resources temporarily unprotected.

### 1.2.2 to 1.3.0

Version `1.3.0` removes the `aws_wafregional_ipset` `ips` resource from this module and requires a `ip_set` variable that accepts the id of an externally managed `aws_wafregional_ipset`. This allows for a common IP Set to be used by multiple Web Application Firewalls. If your IP Set does not contain any IP addresses, then no IP addresses are blocked. For example:

```hcl
resource "aws_wafregional_ipset" "global" {
name = "app-global-blocked-ips"

ip_set_descriptor {
type = "IPV4"
value = "1.2.3.4/32"
}

}
```

Use `terraform state mv` to externalize the IP Set, e.g., `terraform state mv FOO.BAR.aws_wafregional_ipset.ips Foo.aws_wafregional_ipset.ips`.

## Developer Setup

Install dependencies (macOS)

```shell
brew install pre-commit go terraform terraform-docs
```