From bf81d5ef4c68763fe3c442e88f90a7b4d6d3a8b2 Mon Sep 17 00:00:00 2001 From: Byungjin Park Date: Thu, 17 Nov 2022 02:20:50 +0900 Subject: [PATCH 1/3] Add waf-ip-set module --- modules/waf-ip-set/README.md | 59 +++++++++++++++++++++ modules/waf-ip-set/main.tf | 38 ++++++++++++++ modules/waf-ip-set/outputs.tf | 34 ++++++++++++ modules/waf-ip-set/resource-group.tf | 32 ++++++++++++ modules/waf-ip-set/variables.tf | 77 ++++++++++++++++++++++++++++ modules/waf-ip-set/versions.tf | 10 ++++ 6 files changed, 250 insertions(+) create mode 100644 modules/waf-ip-set/README.md create mode 100644 modules/waf-ip-set/main.tf create mode 100644 modules/waf-ip-set/outputs.tf create mode 100644 modules/waf-ip-set/resource-group.tf create mode 100644 modules/waf-ip-set/variables.tf create mode 100644 modules/waf-ip-set/versions.tf diff --git a/modules/waf-ip-set/README.md b/modules/waf-ip-set/README.md new file mode 100644 index 0000000..d089ce6 --- /dev/null +++ b/modules/waf-ip-set/README.md @@ -0,0 +1,59 @@ +# waf-ip-set + +This module creates following resources. + +- `aws_wafv2_ip_set` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [aws](#requirement\_aws) | >= 4.39 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 4.33.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_wafv2_ip_set.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [name](#input\_name) | (Required) A name of the IP set. | `string` | n/a | yes | +| [description](#input\_description) | (Optional) The description of the IP set. | `string` | `"Managed by Terraform."` | no | +| [ip\_address\_type](#input\_ip\_address\_type) | (Required) The type of IP addresses used by the IP set. Valid values are `IPV4` or `IPV6`. Defaults to `IPV4`. | `string` | `"IPV4"` | no | +| [ip\_addresses](#input\_ip\_addresses) | (Optional) A list of strings that specify one or more IP addresses or blocks of IP addresses in Classless Inter-Domain Routing (CIDR) notation. AWS WAF supports all address ranges for IP versions IPv4 and IPv6. | `list(string)` | `[]` | no | +| [is\_global](#input\_is\_global) | (Optional) Specify whether this is for a global application(AWS CloudFront distribution) or for a regional application. Defaults to `false`. To work with a global application, you must also specify the Region US East (N. Virginia). | `bool` | `false` | no | +| [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | +| [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | +| [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | +| [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | +| [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | The Amazon Resource Name (ARN) of the IP set. | +| [description](#output\_description) | The description of the IP set. | +| [id](#output\_id) | The ID of the IP set. | +| [ip\_address\_type](#output\_ip\_address\_type) | The type of IP addresses used by the IP set. | +| [ip\_addresses](#output\_ip\_addresses) | The list of domains from the firewall domain list. | +| [is\_global](#output\_is\_global) | Whether this is for a global application(AWS CloudFront distribution) or for a regional application. | +| [name](#output\_name) | The name of the IP set. | + diff --git a/modules/waf-ip-set/main.tf b/modules/waf-ip-set/main.tf new file mode 100644 index 0000000..95d8455 --- /dev/null +++ b/modules/waf-ip-set/main.tf @@ -0,0 +1,38 @@ +locals { + metadata = { + package = "terraform-aws-firewall" + version = trimspace(file("${path.module}/../../VERSION")) + module = basename(path.module) + name = var.name + } + module_tags = var.module_tags_enabled ? { + "module.terraform.io/package" = local.metadata.package + "module.terraform.io/version" = local.metadata.version + "module.terraform.io/name" = local.metadata.module + "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" + "module.terraform.io/instance" = local.metadata.name + } : {} +} + + +################################################### +# IP Set for WAF (Web Application Firewall) +################################################### + +resource "aws_wafv2_ip_set" "this" { + name = var.name + description = var.description + + scope = var.is_global ? "CLOUDFRONT" : "REGIONAL" + ip_address_version = var.ip_address_type + + addresses = var.ip_addresses + + tags = merge( + { + "Name" = local.metadata.name + }, + local.module_tags, + var.tags, + ) +} diff --git a/modules/waf-ip-set/outputs.tf b/modules/waf-ip-set/outputs.tf new file mode 100644 index 0000000..901ea14 --- /dev/null +++ b/modules/waf-ip-set/outputs.tf @@ -0,0 +1,34 @@ +output "arn" { + description = "The Amazon Resource Name (ARN) of the IP set." + value = aws_wafv2_ip_set.this.arn +} + +output "id" { + description = "The ID of the IP set." + value = aws_wafv2_ip_set.this.id +} + +output "name" { + description = "The name of the IP set." + value = aws_wafv2_ip_set.this.name +} + +output "description" { + description = "The description of the IP set." + value = aws_wafv2_ip_set.this.description +} + +output "is_global" { + description = "Whether this is for a global application(AWS CloudFront distribution) or for a regional application." + value = aws_wafv2_ip_set.this.scope == "CLOUDFRONT" +} + +output "ip_address_type" { + description = "The type of IP addresses used by the IP set." + value = aws_wafv2_ip_set.this.ip_address_version +} + +output "ip_addresses" { + description = "The list of domains from the firewall domain list." + value = aws_wafv2_ip_set.this.addresses +} diff --git a/modules/waf-ip-set/resource-group.tf b/modules/waf-ip-set/resource-group.tf new file mode 100644 index 0000000..94f07c1 --- /dev/null +++ b/modules/waf-ip-set/resource-group.tf @@ -0,0 +1,32 @@ +locals { + resource_group_name = (var.resource_group_name != "" + ? var.resource_group_name + : join(".", [ + local.metadata.package, + local.metadata.module, + var.is_global ? "global" : "regional", + replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), + ]) + ) +} + + +module "resource_group" { + source = "tedilabs/misc/aws//modules/resource-group" + version = "~> 0.10.0" + + count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 + + name = local.resource_group_name + description = var.resource_group_description + + query = { + resource_tags = local.module_tags + } + + module_tags_enabled = false + tags = merge( + local.module_tags, + var.tags, + ) +} diff --git a/modules/waf-ip-set/variables.tf b/modules/waf-ip-set/variables.tf new file mode 100644 index 0000000..9285b39 --- /dev/null +++ b/modules/waf-ip-set/variables.tf @@ -0,0 +1,77 @@ +variable "name" { + description = "(Required) A name of the IP set." + type = string +} + +variable "description" { + description = "(Optional) The description of the IP set." + type = string + default = "Managed by Terraform." + nullable = false +} + +variable "is_global" { + description = "(Optional) Specify whether this is for a global application(AWS CloudFront distribution) or for a regional application. Defaults to `false`. To work with a global application, you must also specify the Region US East (N. Virginia)." + type = bool + default = false + nullable = false +} + +variable "ip_address_type" { + description = "(Required) The type of IP addresses used by the IP set. Valid values are `IPV4` or `IPV6`. Defaults to `IPV4`." + type = string + default = "IPV4" + nullable = false + + validation { + condition = contains(["IPV4", "IPV6"], var.ip_address_type) + error_message = "Valid values are `IPV4` or `IPV6`." + } +} + +variable "ip_addresses" { + description = "(Optional) A list of strings that specify one or more IP addresses or blocks of IP addresses in Classless Inter-Domain Routing (CIDR) notation. AWS WAF supports all address ranges for IP versions IPv4 and IPv6." + type = list(string) + default = [] + nullable = false +} + +variable "tags" { + description = "(Optional) A map of tags to add to all resources." + type = map(string) + default = {} + nullable = false +} + +variable "module_tags_enabled" { + description = "(Optional) Whether to create AWS Resource Tags for the module informations." + type = bool + default = true + nullable = false +} + + +################################################### +# Resource Group +################################################### + +variable "resource_group_enabled" { + description = "(Optional) Whether to create Resource Group to find and group AWS resources which are created by this module." + type = bool + default = true + nullable = false +} + +variable "resource_group_name" { + description = "(Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`." + type = string + default = "" + nullable = false +} + +variable "resource_group_description" { + description = "(Optional) The description of Resource Group." + type = string + default = "Managed by Terraform." + nullable = false +} diff --git a/modules/waf-ip-set/versions.tf b/modules/waf-ip-set/versions.tf new file mode 100644 index 0000000..c0a4ec0 --- /dev/null +++ b/modules/waf-ip-set/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.39" + } + } +} From ef637fff84bdef0f021bae9a1437d4cc2b8956f6 Mon Sep 17 00:00:00 2001 From: Byungjin Park Date: Thu, 17 Nov 2022 02:21:04 +0900 Subject: [PATCH 2/3] Add waf-ip-set label --- .github/labeler.yaml | 2 ++ .github/labels.yaml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/.github/labeler.yaml b/.github/labeler.yaml index f1070a8..a00b900 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -9,3 +9,5 @@ - modules/fms-dns-firewall-policy/**/* ":floppy_disk: network-firewall": - modules/network-firewall/**/* +":floppy_disk: waf-ip-set": +- modules/waf-ip-set/**/* diff --git a/.github/labels.yaml b/.github/labels.yaml index 728850f..d2115e2 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -54,3 +54,6 @@ - color: "fbca04" description: "This issue or pull request is related to network-firewall module." name: ":floppy_disk: network-firewall" +- color: "fbca04" + description: "This issue or pull request is related to waf-ip-set module." + name: ":floppy_disk: waf-ip-set" From f37c65afb8beb1c8ffbcc96e46f15eb3a5fb9e55 Mon Sep 17 00:00:00 2001 From: Byungjin Park Date: Thu, 17 Nov 2022 02:21:09 +0900 Subject: [PATCH 3/3] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bbfbbf5..f5ee945 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Terraform module which creates firewall related resources on AWS. - [dns-firewall-rule-group](./modules/dns-firewall-rule-group) - [fms-dns-firewall-policy](./modules/fms-dns-firewall-policy) - [network-firewall](./modules/network-firewall) +- [waf-ip-set](./modules/waf-ip-set) ## Target AWS Services @@ -18,13 +19,15 @@ Terraform module which creates firewall related resources on AWS. Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws-firewall) were written to manage the following AWS Services with Terraform. - **AWS FMS (Firewall Manager)** - - Security Policy + - DNS Firewall Security Policy - **AWS Route53 DNS Firewall** - Firewall - Firewall Rule Group - Firewall Domain List - **AWS VPC Network Firewall** - Firewall +- **AWS WAF (Web Application Firewall)** + - IP Set ## Usage