Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/labeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
- modules/dns-firewall-rule-group/**/*
":floppy_disk: dns-firewall":
- modules/dns-firewall/**/*
":floppy_disk: fms-dns-firewall-policy":
- modules/fms-dns-firewall-policy/**/*
":floppy_disk: network-firewall":
- modules/network-firewall/**/*
4 changes: 3 additions & 1 deletion .github/labels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
- color: "0e8a16"
description: "Extra attention is needed."
name: ":fire: help wanted"

# Cancel
- color: "b60205"
description: "This issue or pull request already exists."
Expand Down Expand Up @@ -49,6 +48,9 @@
- color: "fbca04"
description: "This issue or pull request is related to dns-firewall module."
name: ":floppy_disk: dns-firewall"
- color: "fbca04"
description: "This issue or pull request is related to fms-dns-firewall-policy module."
name: ":floppy_disk: fms-dns-firewall-policy"
- color: "fbca04"
description: "This issue or pull request is related to network-firewall module."
name: ":floppy_disk: network-firewall"
145 changes: 145 additions & 0 deletions examples/fms-dns-firewall-policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
provider "aws" {
region = "us-east-1"
}


###################################################
# DNS Firewall Domain List
###################################################

module "domain_list_blacklist" {
source = "../../modules/dns-firewall-domain-list"
# source = "tedilabs/firewall/aws//modules/dns-firewall-domain-list"
# version = "~> 0.1.0"

name = "example-blacklist"
domains = [
"example1.blacklist.com.",
"example2.blacklist.com.",
"example3.blacklist.com.",
]

tags = {
"project" = "terraform-aws-firewall-examples"
}
}

module "domain_list_whitelist" {
source = "../../modules/dns-firewall-domain-list"
# source = "tedilabs/firewall/aws//modules/dns-firewall-domain-list"
# version = "~> 0.1.0"

name = "example-whitelist"
domains = [
"example1.whitelist.com.",
"example2.whitelist.com.",
"example3.whitelist.com.",
]

tags = {
"project" = "terraform-aws-firewall-examples"
}
}



###################################################
# DNS Firewall Rule Group
###################################################

module "rule_group_1" {
source = "../../modules/dns-firewall-rule-group"
# source = "tedilabs/firewall/aws//modules/dns-firewall-rule-group"
# version = "~> 0.1.0"

name = "block-blacklist"
rules = [
{
priority = 10
name = "block-example"
domain_list = module.domain_list_blacklist.id
action = "BLOCK"
action_parameters = {
response = "OVERRIDE"
override = {
type = "CNAME"
value = "404.mycompany.com."
ttl = 60
}
}
},
]

tags = {
"project" = "terraform-aws-firewall-examples"
}
}

module "rule_group_2" {
source = "../../modules/dns-firewall-rule-group"
# source = "tedilabs/firewall/aws//modules/dns-firewall-rule-group"
# version = "~> 0.1.0"

name = "allow-whitelist"
rules = [
{
priority = 10
name = "allow-example"
domain_list = module.domain_list_whitelist.id
action = "ALLOW"
},
]

tags = {
"project" = "terraform-aws-firewall-examples"
}
}


###################################################
# DNS Firewall
###################################################

module "policy" {
source = "../../modules/fms-dns-firewall-policy"
# source = "tedilabs/firewall/aws//modules/fms-dns-firewall-policy"
# version = "~> 0.1.0"

name = "dns-firewall-example"

## Policy
pre_rule_groups = [
{
priority = 10
rule_group = module.rule_group_2.id,
}
]
post_rule_groups = [
{
priority = 10000
rule_group = module.rule_group_1.id,
}
]

## Scope
resource_types = ["AWS::EC2::VPC"]
resource_tags_filter = {
type = "BLACKLIST"
tags = {
"Team" = "security"
}
}
organization_filter = {
type = "WHITELIST"
accounts = ["911145092815"]
}

## Attributes
auto_remediation_enabled = true
resource_cleanup_on_leave_enabled = true
cascade_deletion_enabled = true

tags = {
"project" = "terraform-aws-firewall-examples"
}
}
17 changes: 17 additions & 0 deletions examples/fms-dns-firewall-policy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
output "domain_lists" {
value = {
blacklist = module.domain_list_blacklist
whitelist = module.domain_list_whitelist
}
}

output "rule_group" {
value = [
module.rule_group_1,
module.rule_group_2,
]
}

output "policy" {
value = module.policy
}
10 changes: 10 additions & 0 deletions examples/fms-dns-firewall-policy/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = "~> 1.3"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
62 changes: 62 additions & 0 deletions modules/fms-dns-firewall-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# fms-policy

This module creates following resources.

- `aws_fms_policy`

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.36 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.33.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_resource_group"></a> [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 |

## Resources

| Name | Type |
|------|------|
| [aws_fms_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/fms_policy) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | (Required) The friendly name of the AWS Firewall Manager Policy. | `string` | n/a | yes |
| <a name="input_pre_rule_groups"></a> [pre\_rule\_groups](#input\_pre\_rule\_groups) | (Required) A list of rule groups to process first. Each item of `pre_rule_groups` block as defined below.<br> (Required) `priority` - The setting that determines the processing order of the rule group among the rule groups that you associate with the specified VPC. DNS Firewall filters VPC traffic starting from the rule group with the lowest numeric priority setting. Valid values for `priority` are between 1 and 99.<br> (Required) `rule_group` - The ID of the firewall rule group. | <pre>list(object({<br> priority = number<br> rule_group = string<br> }))</pre> | n/a | yes |
| <a name="input_auto_remediation_enabled"></a> [auto\_remediation\_enabled](#input\_auto\_remediation\_enabled) | (Optional) Indicate if the policy should be automatically applied to new resources. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_cascade_deletion_enabled"></a> [cascade\_deletion\_enabled](#input\_cascade\_deletion\_enabled) | (Optional) Whether to cleanup resources which is managed by the policy on deletion. Defaults to `true`.<br><br> If `true`, the request performs cleanup according to the policy type.<br><br> For AWS WAF and Shield Advanced policies, the cleanup does the following:<br> - Deletes rule groups created by AWS Firewall Manager<br> - Removes web ACLs from in-scope resources<br> - Deletes web ACLs that contain no rules or rule groups<br><br> For security group policies, the cleanup does the following for each security group in the policy:<br> - Disassociates the security group from in-scope resources<br> - Deletes the security group if it was created through Firewall Manager and if it's no longer associated with any resources through another policy<br><br> After the cleanup, in-scope resources are no longer protected by web ACLs in this policy. Protection of out-of-scope resources remains unchanged. | `bool` | `true` | no |
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
| <a name="input_organization_filter"></a> [organization\_filter](#input\_organization\_filter) | (Optional) A filter configuration to decide protections on resources based on the accounts and organization units. `organization_filter` block as defined below.<br> (Optional) `type` - Whether to include or exclude resources that contain `accounts` or `organization_units` from protections by this policy. Valid values are `WHITELIST` and `BLACKLIST`.<br> (Optional) `accounts` - A list of AWS Organization member accounts that you want to include or to exclude for this AWS FMS Policy.<br> (Optional) `organization_units` - A list of AWS Organization Units that you want to include or to exclude for this AWS FMS Policy. | <pre>object({<br> type = optional(string, "WHITELIST")<br> accounts = optional(set(string), [])<br> organization_units = optional(set(string), [])<br> })</pre> | `{}` | no |
| <a name="input_post_rule_groups"></a> [post\_rule\_groups](#input\_post\_rule\_groups) | (Optional) A list of rule groups to process first. Each item of `post_rule_groups` block as defined below.<br> (Required) `priority` - The setting that determines the processing order of the rule group among the rule groups that you associate with the specified VPC. DNS Firewall filters VPC traffic starting from the rule group with the lowest numeric priority setting. Valid values for `priority` are between 9901 and 10000.<br> (Required) `rule_group` - The ID of the firewall rule group. | <pre>list(object({<br> priority = number<br> rule_group = string<br> }))</pre> | `[]` | no |
| <a name="input_resource_cleanup_on_leave_enabled"></a> [resource\_cleanup\_on\_leave\_enabled](#input\_resource\_cleanup\_on\_leave\_enabled) | (Optional) Whether Firewall Manager will automatically remove protections from resources that leave the policy scope and clean up resources that Firewall Manager is managing for accounts when those accounts leave policy scope. For example, Firewall Manager will disassociate a Firewall Manager managed web ACL from a protected customer resource when the customer resource leaves policy scope. Defaults to `false`. This option is not available for Shield Advanced or AWS WAF Classic policies. | `bool` | `false` | no |
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
| <a name="input_resource_group_enabled"></a> [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 |
| <a name="input_resource_group_name"></a> [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 |
| <a name="input_resource_tags_filter"></a> [resource\_tags\_filter](#input\_resource\_tags\_filter) | (Optional) A filter configuration to decide protections on resources based on the resource tags. `resourcee_tags_filter` block as defined below.<br> (Optional) `type` - Whether to include or exclude resources that contain `tags` from protections by this policy. Valid values are `WHITELIST` and `BLACKLIST`.<br> (Optional) `tags` - A map of resource tags to filter resources. | <pre>object({<br> type = optional(string, "WHITELIST")<br> tags = optional(map(string), {})<br> })</pre> | `{}` | no |
| <a name="input_resource_types"></a> [resource\_types](#input\_resource\_types) | (Optional) A list of resource types to protect. | `list(string)` | <pre>[<br> "AWS::EC2::VPC"<br>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the AWS Firewall Manager Policy. |
| <a name="output_attributes"></a> [attributes](#output\_attributes) | A set of attributes that applied to the AWS Firewall Manager Policy. |
| <a name="output_id"></a> [id](#output\_id) | The ID of the AWS Firewall Manager Policy. |
| <a name="output_name"></a> [name](#output\_name) | The name of the AWS Firewall Manager Policy. |
| <a name="output_policy"></a> [policy](#output\_policy) | The configuration of this policy. |
| <a name="output_scope"></a> [scope](#output\_scope) | The configuration of this policy scope. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
92 changes: 92 additions & 0 deletions modules/fms-dns-firewall-policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
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
} : {}
}

locals {
organization_filter_enabled = length(setunion(
var.organization_filter.accounts,
var.organization_filter.organization_units
)) > 0
}


###################################################
# Security Policy for FMS (Firewall Manager)
###################################################

# INFO: Not supported attributes
resource "aws_fms_policy" "this" {
name = var.name

## Policy
security_service_policy_data {
type = "DNS_FIREWALL"

managed_service_data = jsonencode({
type = "DNS_FIREWALL"

preProcessRuleGroups = [
for item in var.pre_rule_groups : {
priority = item.priority
ruleGroupId = item.rule_group
}
]
postProcessRuleGroups = [
for item in var.post_rule_groups : {
priority = item.priority
ruleGroupId = item.rule_group
}
]
})
}


## Scope
resource_type = length(var.resource_types) == 1 ? var.resource_types[0] : null
resource_type_list = length(var.resource_types) > 1 ? var.resource_types : null
resource_tags = var.resource_tags_filter.tags
exclude_resource_tags = var.resource_tags_filter.type == "BLACKLIST"

dynamic "include_map" {
for_each = (var.organization_filter.type == "WHITELIST" && local.organization_filter_enabled) ? ["go"] : []

content {
account = var.organization_filter.accounts
orgunit = var.organization_filter.organization_units
}
}
dynamic "exclude_map" {
for_each = (var.organization_filter.type == "BLACKLIST" && local.organization_filter_enabled) ? ["go"] : []

content {
account = var.organization_filter.accounts
orgunit = var.organization_filter.organization_units
}
}


## Attributes
remediation_enabled = var.auto_remediation_enabled
delete_unused_fm_managed_resources = var.resource_cleanup_on_leave_enabled
delete_all_policy_resources = var.cascade_deletion_enabled

tags = merge(
{
"Name" = local.metadata.name
},
local.module_tags,
var.tags,
)
}
Loading