Skip to content

Commit

Permalink
add logging and monitoring resources to module and define custom rule…
Browse files Browse the repository at this point in the history
…s/domains via locals as needed
  • Loading branch information
richgreen-moj committed Jan 13, 2025
1 parent b45aa88 commit be33173
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 76 deletions.
111 changes: 46 additions & 65 deletions terraform/environments/core-vpc/vpc.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,44 @@ locals {

modernisation-platform-domain = "modernisation-platform.service.justice.gov.uk"
modernisation-platform-internal-domain = "modernisation-platform.internal"

r53_dns_firewall_rules = {
default_rule = [
{
action = "ALERT"
domain_list_id = "rslvr-fdl-4e96d4ce77f466b" # AWSManagedDomainsAggregateThreatList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
priority = 1
name = "Alert_AWSManagedDomainsAggregateThreatList"
}
]

additional_rules = {
core-vpc-production = []
core-vpc-preproduction = []
core-vpc-test = []
core-vpc-development = []
core-vpc-sandbox = {
garden-sandbox = [
{
action = "BLOCK"
domain_list_id = "" # This will use the custom domain list created in the module
priority = 2
name = "Block_CustomDomainList_GardenSandbox"
}
]
}
}

custom_domain_lists = {
core-vpc-production = []
core-vpc-preproduction = []
core-vpc-test = []
core-vpc-development = []
core-vpc-sandbox = {
garden-sandbox = ["garden-example.com", "garden-malicious.com"]
}
}
}
}

module "vpc" {
Expand Down Expand Up @@ -356,73 +394,16 @@ module "r53_dns_firewall" {
for_each = local.vpcs["core-vpc-sandbox"]
source = "../../modules/r53-dns-firewall"

name = each.key
vpc_id = module.vpc["each.key"].vpc_id
log_group_arn = aws_cloudwatch_log_group.dns_firewall_log_group.arn


custom_domain_list_enabled = true
custom_domain_list_name = "${each.key}-custom-domain-list"
custom_domain_list_domains = ["example.com", "malicious.com"]

rules = [
{
action = "ALERT"
domain_list_id = "rslvr-fdl-4e96d4ce77f466b" # AWSManagedDomainsAggregateThreatList - see https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
priority = 1
name = "Block_AWSManagedDomainsAggregateThreatList"
},
{
action = "ALERT"
domain_list_id = "" # This will use the custom domain list created in the module
priority = 2
name = "Block_CustomDomainList"
}
]
}

# R53 Resolver DNS Firewall CloudWatch Logging Resources
resource "aws_cloudwatch_log_group" "dns_firewall_log_group" {
name = "/aws/route53resolver/dns_firewall"
}

resource "aws_cloudwatch_log_metric_filter" "dns_firewall_metric_filter" {
name = "DNSFirewallMatches"
log_group_name = aws_cloudwatch_log_group.dns_firewall_log_group.name

pattern = "{ ($.action = \"ALERT\") }"
name = each.key
vpc_id = module.vpc[each.key].vpc_id

metric_transformation {
name = "DNSFirewallMatches"
namespace = "DNSFirewall"
value = "1"
}
}

resource "aws_cloudwatch_metric_alarm" "dns_firewall_alarm" {
alarm_name = "DNSFirewallMatchesAlarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = aws_cloudwatch_log_metric_filter.dns_firewall_metric_filter.metric_transformation[0].name
namespace = aws_cloudwatch_log_metric_filter.dns_firewall_metric_filter.metric_transformation[0].namespace
period = "60"
statistic = "Sum"
threshold = "1"

alarm_actions = [aws_sns_topic.dns_firewall_sns_topic.arn]
}

# R53 Resolver DNS Firewall SNS Topic and Subscription

resource "aws_sns_topic" "dns_firewall_sns_topic" {
name = "DNSFirewallMatchesTopic"
}
rules = concat(
local.r53_dns_firewall_rules.default_rule,
lookup(local.r53_dns_firewall_rules.additional_rules, each.key, [])
)

# Subscribe the sns topic to the pagerduty service
custom_domain_list_domains = lookup(local.r53_dns_firewall_rules.custom_domain_lists[terraform.workspace], each.key, [])
custom_domain_list_enabled = length(lookup(local.r53_dns_firewall_rules.custom_domain_lists[terraform.workspace], each.key, [])) > 0

module "pagerduty_r53_dns_firewall" {
depends_on = [aws_sns_topic.dns_firewall_sns_topic]
source = "github.com/ministryofjustice/modernisation-platform-terraform-pagerduty-integration?ref=0179859e6fafc567843cd55c0b05d325d5012dc4" # v2.0.0
sns_topics = [aws_sns_topic.dns_firewall_sns_topic.name]
pagerduty_integration_key = local.pagerduty_integration_keys["core_alerts_cloudwatch"]
}
48 changes: 45 additions & 3 deletions terraform/modules/r53-dns-firewall/main.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# R53 Resolver DNS Firewall Resources
resource "aws_route53_resolver_firewall_rule_group" "this" {
name = "${var.name}-rule-group"
name = "${var.name}-r53-dns-firewall-rule-group"
}

resource "aws_route53_resolver_firewall_domain_list" "custom" {
count = var.custom_domain_list_enabled ? 1 : 0

name = var.custom_domain_list_name
name = "${var.name}-custom-domain-list"
domains = var.custom_domain_list_domains
}

Expand All @@ -29,5 +30,46 @@ resource "aws_route53_resolver_firewall_rule_group_association" "this" {

resource "aws_route53_resolver_query_log_config" "dns_firewall_log_config" {
name = "${var.name}-rqlc-cloudwatch"
destination_arn = var.log_group_arn
destination_arn = aws_cloudwatch_log_group.dns_firewall_log_group.arn
}

resource "aws_cloudwatch_log_group" "dns_firewall_log_group" {
name = "/aws/route53resolver/dns_firewall/${var.name}"
}

resource "aws_cloudwatch_log_metric_filter" "dns_firewall_metric_filter" {
name = "DNSFirewallMatches"
log_group_name = aws_cloudwatch_log_group.dns_firewall_log_group.name

pattern = "{ ($.action = \"ALERT\") }"

metric_transformation {
name = "DNSFirewallMatches"
namespace = "DNSFirewall"
value = "1"
}
}

resource "aws_cloudwatch_metric_alarm" "dns_firewall_alarm" {
alarm_name = "DNSFirewallMatchesAlarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = aws_cloudwatch_log_metric_filter.dns_firewall_metric_filter.metric_transformation[0].name
namespace = aws_cloudwatch_log_metric_filter.dns_firewall_metric_filter.metric_transformation[0].namespace
period = "60"
statistic = "Sum"
threshold = "1"

alarm_actions = [aws_sns_topic.dns_firewall_sns_topic.arn]
}

resource "aws_sns_topic" "dns_firewall_sns_topic" {
name = "DNSFirewallMatchesTopic"
}

module "pagerduty_r53_dns_firewall" {
depends_on = [aws_sns_topic.dns_firewall_sns_topic]
source = "github.com/ministryofjustice/modernisation-platform-terraform-pagerduty-integration?ref=0179859e6fafc567843cd55c0b05d325d5012dc4" # v2.0.0
sns_topics = [aws_sns_topic.dns_firewall_sns_topic.name]
pagerduty_integration_key = var.pagerduty_integration_key
}
10 changes: 2 additions & 8 deletions terraform/modules/r53-dns-firewall/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,13 @@ variable "custom_domain_list_enabled" {
default = false
}

variable "custom_domain_list_name" {
description = "The name of the custom domain list"
type = string
default = ""
}

variable "custom_domain_list_domains" {
description = "List of custom domains"
type = list(string)
default = []
}

variable "log_group_arn" {
description = "The ARN of the CloudWatch Log Group for DNS Firewall logs"
variable "pagerduty_integration_key" {
description = "The PagerDuty integration key"
type = string
}

0 comments on commit be33173

Please sign in to comment.