Skip to content

Commit

Permalink
Support rules for dns-firewall-rule-group module (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
posquit0 authored May 22, 2022
1 parent a4222d0 commit 8d24b91
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 14 deletions.
8 changes: 8 additions & 0 deletions modules/dns-firewall-domain-list/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ variable "domains" {
description = "(Optional) A list of domains for the firewall domain list."
type = list(string)
default = []

validation {
condition = alltrue([
for domain in var.domains :
substr(domain, -1, 1) == "."
])
error_message = "Each domain should have a dot at the end by following the definition of FQDN(Fully Qualified Domain Name)."
}
}

variable "tags" {
Expand Down
3 changes: 3 additions & 0 deletions modules/dns-firewall-rule-group/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ No modules.
| Name | Type |
|------|------|
| [aws_resourcegroups_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/resourcegroups_group) | resource |
| [aws_route53_resolver_firewall_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_resolver_firewall_rule) | resource |
| [aws_route53_resolver_firewall_rule_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_resolver_firewall_rule_group) | resource |

## Inputs
Expand All @@ -40,6 +41,7 @@ No modules.
| <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_rules"></a> [rules](#input\_rules) | (Optional) The rules that you define for the firewall rule group determine the filtering behavior. Each rule consists of a priority, a domain list, and action. Each item of `rules` block as defined below.<br> (Required) `priority` - Determine the processing order of the rule in the rule group. DNS Firewall processes the rules in a rule group by order of priority, starting from the lowest priority.<br> (Required) `name` - A name that lets you identify the rule.<br> (Optional) `description` - The description of the rule.<br> (Required) `domain_list` - The ID of the domain list that you want to use in the rule.<br> (Required) `action` - The action that DNS Firewall should take on a DNS query when it matches one of the domains in the rule's domain list. Valid values are `ALLOW`, `BLOCK`, `ALERT`.<br> (Optional) `action_parameters` - The configuration block for the parameters of the rule action. Only required with `BLOCK` action. `action_parameters` block as defined below.<br> (Required) `response` - The way that you want DNS Firewall to block the request. Valid values are `NODATA`, `NXDOMAIN`, `OVERRIDE`. `NODATA` indicates that this query was successful, but there is no response available for the query. `NXDOMAIN` indicates that the domain name that's in the query doesn't exist. `OVERRIDE` provides a custom override response to the query.<br> (Optional) `override` - The configuration for a custom override response to the query. Only required with `OVERRIDE` block response.<br> (Required) `type` - The DNS record's type. This determines the format of the record value that you provided in BlockOverrideDomain. Value values are `CNAME`.<br> (Required) `value` - The custom DNS record to send back in response to the query.<br> (Required) `ttl` - The recommended amount of time, in seconds, for the DNS resolver or web browser to cache the provided override record. Minimum value of `0`. Maximum value of `604800`. | `any` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |

## Outputs
Expand All @@ -50,5 +52,6 @@ No modules.
| <a name="output_id"></a> [id](#output\_id) | The ID of the firewall rule group. |
| <a name="output_name"></a> [name](#output\_name) | The name of the firewall rule group. |
| <a name="output_owner_id"></a> [owner\_id](#output\_owner\_id) | The AWS Account ID for the account that created the rule group. |
| <a name="output_rules"></a> [rules](#output\_rules) | The rules of the firewall rule group. |
| <a name="output_share_status"></a> [share\_status](#output\_share\_status) | Whether the rule group is shared with other AWS accounts, or was shared with the current account by another AWS account. Sharing is configured through AWS Resource Access Manager (AWS RAM). Valid values: `NOT_SHARED`, `SHARED_BY_ME`, `SHARED_WITH_ME`. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
43 changes: 29 additions & 14 deletions modules/dns-firewall-rule-group/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,32 @@ resource "aws_route53_resolver_firewall_rule_group" "this" {
# Rules for DNS Firewall Rule Group
###################################################

# resource "aws_route53_resolver_firewall_rule" "this" {
# count = var.value != null ? 1 : 0
#
# firewall_arn = aws_route53_resolver_firewall_rule_group.this.arn
#
# logging_configuration {
# log_destination_config {
# log_destination = {
# deliveryStream = aws_kinesis_firehose_delivery_stream.example.name
# }
# log_destination_type = "KinesisDataFirehose"
# log_type = "ALERT"
# }
# }
resource "aws_route53_resolver_firewall_rule" "this" {
for_each = {
for rule in var.rules :
rule.priority => rule
}

firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.this.id

priority = each.key
name = each.value.name
# description = try(each.value.description, null)
firewall_domain_list_id = each.value.domain_list

action = each.value.action
block_response = (each.value.action == "BLOCK"
? each.value.action_parameters.response
: null)
block_override_domain = (each.value.action_parameters.response == "OVERRIDE"
? each.value.action_parameters.override.value
: null)
block_override_dns_type = (each.value.action_parameters.response == "OVERRIDE"
? each.value.action_parameters.override.type
: null)

block_override_ttl = (each.value.action_parameters.response == "OVERRIDE"
? each.value.action_parameters.override.ttl
: null)

}
25 changes: 25 additions & 0 deletions modules/dns-firewall-rule-group/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,28 @@ output "name" {
# description = "The description of the firewall rule group."
# value = aws_route53_resolver_firewall_rule_group.this.description
# }

output "rules" {
description = "The rules of the firewall rule group."
value = {
for priority, rule in aws_route53_resolver_firewall_rule.this :
priority => {
name = rule.name
# description = rule.description
domain_list = rule.firewall_domain_list_id
action = rule.action
action_parameters = try({
"BLOCK" = {
response = rule.block_response
override = (rule.block_response == "OVERRIDE"
? {
type = rule.block_override_dns_type
value = rule.block_override_domain
ttl = rule.block_override_ttl
}
: null)
}
}[rule.action], {})
}
}
}
59 changes: 59 additions & 0 deletions modules/dns-firewall-rule-group/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,65 @@ variable "description" {
default = "Managed by Terraform."
}

variable "rules" {
description = <<EOF
(Optional) The rules that you define for the firewall rule group determine the filtering behavior. Each rule consists of a priority, a domain list, and action. Each item of `rules` block as defined below.
(Required) `priority` - Determine the processing order of the rule in the rule group. DNS Firewall processes the rules in a rule group by order of priority, starting from the lowest priority.
(Required) `name` - A name that lets you identify the rule.
(Optional) `description` - The description of the rule.
(Required) `domain_list` - The ID of the domain list that you want to use in the rule.
(Required) `action` - The action that DNS Firewall should take on a DNS query when it matches one of the domains in the rule's domain list. Valid values are `ALLOW`, `BLOCK`, `ALERT`.
(Optional) `action_parameters` - The configuration block for the parameters of the rule action. Only required with `BLOCK` action. `action_parameters` block as defined below.
(Required) `response` - The way that you want DNS Firewall to block the request. Valid values are `NODATA`, `NXDOMAIN`, `OVERRIDE`. `NODATA` indicates that this query was successful, but there is no response available for the query. `NXDOMAIN` indicates that the domain name that's in the query doesn't exist. `OVERRIDE` provides a custom override response to the query.
(Optional) `override` - The configuration for a custom override response to the query. Only required with `OVERRIDE` block response.
(Required) `type` - The DNS record's type. This determines the format of the record value that you provided in BlockOverrideDomain. Value values are `CNAME`.
(Required) `value` - The custom DNS record to send back in response to the query.
(Required) `ttl` - The recommended amount of time, in seconds, for the DNS resolver or web browser to cache the provided override record. Minimum value of `0`. Maximum value of `604800`.
EOF
type = any
default = []

validation {
condition = alltrue([
for rule in var.rules :
alltrue([
rule.priority >= 0,
rule.priority <= 10000,
])
])
error_message = "Valid value for `rule.priority` from `rules` is between 0 and 10000."
}

validation {
condition = alltrue([
for rule in var.rules :
contains(["ALLOW", "BLOCK", "ALERT"], rule.action)
])
error_message = "Valid values for `rule.action` from `rules` are `ALLOW`, `BLOCK`, `ALERT`."
}

validation {
condition = alltrue([
for rule in var.rules :
contains(["NODATA", "NXDOMAIN", "OVERRIDE"], rule.action_parameters.response)
if rule.action == "BLOCK"
])
error_message = "Valid values for `rule.action_parameters.response` from `rules` are `NODATA`, `NXDOMAIN`, `OVERRIDE`."
}

validation {
condition = alltrue([
for rule in var.rules :
alltrue([
for key in ["type", "value", "ttl"] :
contains(try(keys(rule.action_parameters.override), []), key)
])
if rule.action_parameters.response == "OVERRIDE"
])
error_message = "`rule.action_parameters.override` from `rules` should have `type`, `value`, `ttl`."
}
}

variable "tags" {
description = "(Optional) A map of tags to add to all resources."
type = map(string)
Expand Down

0 comments on commit 8d24b91

Please sign in to comment.