Skip to content
Open
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
1 change: 1 addition & 0 deletions modules/asm-aws-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module "this" {
db_backup_retention_days = var.db_backup_retention_days
db_deletion_protection = var.db_deletion_protection
enable_customer_managed_key = var.enable_customer_managed_key
enable_flow_logs = var.enable_flow_logs
alb_idle_timeout_seconds = var.alb_idle_timeout_seconds
alb_min_tls_version = var.alb_min_tls_version
enable_management_access = var.enable_management_access
Expand Down
6 changes: 6 additions & 0 deletions modules/asm-aws-ha/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,9 @@ output "redis_mode" {
value = module.this.redis_mode
sensitive = false
}

output "flow_log_group_name" {
description = "CloudWatch log group name receiving VPC Flow Logs. Empty string when enable_flow_logs is false."
value = module.this.flow_log_group_name
sensitive = false
}
6 changes: 6 additions & 0 deletions modules/asm-aws-ha/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ variable "enable_customer_managed_key" {
default = false
}

variable "enable_flow_logs" {
description = "Enable VPC Flow Logs for the provided VPC, sending ALL traffic to a CloudWatch log group named /aws/vpc-flow-logs/<name_prefix>. Matches the default stated in SECURITY-DEFAULTS.md."
type = bool
default = true
}

variable "alb_idle_timeout_seconds" {
type = number
default = 120
Expand Down
70 changes: 70 additions & 0 deletions modules/ha-hot-hot/aws/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1199,3 +1199,73 @@ resource "aws_iam_role_policy_attachment" "rds_monitoring" {
role = aws_iam_role.rds_monitoring[0].name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
}

# ----- VPC Flow Logs -----

resource "aws_cloudwatch_log_group" "flow_logs" {
count = var.enable_flow_logs ? 1 : 0
name = "/aws/vpc-flow-logs/${local.name_prefix}"
retention_in_days = 30
kms_key_id = var.enable_customer_managed_key ? aws_kms_key.main[0].arn : null
tags = local.common_tags
}

resource "aws_iam_role" "flow_logs" {
count = var.enable_flow_logs ? 1 : 0
name = "${local.name_prefix}-flow-logs"
tags = local.common_tags

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "vpc-flow-logs.amazonaws.com" }
}]
})
}

# The flow-logs role's first statement is scoped to this module's single
# flow_logs log-group ARN. The second statement uses Resource = "*" only for
# logs:DescribeLogGroups, which the API itself requires — IAM rejects ARN
# scoping on that action. The role can still neither read nor write any other
# log group.
#tfsec:ignore:aws-iam-no-policy-wildcards
resource "aws_iam_role_policy" "flow_logs" {
count = var.enable_flow_logs ? 1 : 0
name = "${local.name_prefix}-flow-logs"
role = aws_iam_role.flow_logs[0].id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
]
Resource = [
aws_cloudwatch_log_group.flow_logs[0].arn,
"${aws_cloudwatch_log_group.flow_logs[0].arn}:*",
]
},
{
Effect = "Allow"
Action = ["logs:DescribeLogGroups"]
Resource = "*"
},
]
})
}

resource "aws_flow_log" "vpc" {
count = var.enable_flow_logs ? 1 : 0
iam_role_arn = aws_iam_role.flow_logs[0].arn
log_destination = aws_cloudwatch_log_group.flow_logs[0].arn
log_destination_type = "cloud-watch-logs"
traffic_type = "ALL"
vpc_id = var.vpc_id
tags = local.common_tags
}
5 changes: 5 additions & 0 deletions modules/ha-hot-hot/aws/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ output "redis_mode" {
description = "How Redis is wired: 'managed' (this module provisioned ElastiCache), 'override' (customer-supplied endpoint), or 'disabled' (HA is not actually safe)."
value = local.provision_managed_redis ? "managed" : (var.redis_endpoint_override == null ? "disabled" : "override")
}

output "flow_log_group_name" {
description = "CloudWatch log group name receiving VPC Flow Logs. Empty string when enable_flow_logs is false."
value = var.enable_flow_logs ? aws_cloudwatch_log_group.flow_logs[0].name : ""
}
10 changes: 10 additions & 0 deletions modules/ha-hot-hot/aws/tests/basic.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ mock_provider "aws" {
mock_resource "aws_sns_topic" {
defaults = { arn = "arn:aws:sns:us-east-1:123456789012:mock-topic" }
}
mock_resource "aws_cloudwatch_log_group" {
defaults = {
arn = "arn:aws:logs:us-east-1:123456789012:log-group:/aws/vpc-flow-logs/mock:*"
}
}
}

mock_provider "random" {}
Expand Down Expand Up @@ -70,4 +75,9 @@ run "minimal_inputs_apply" {
condition = output.redis_endpoint != ""
error_message = "redis_endpoint output must be non-empty when managed Redis is enabled (the default)"
}

assert {
condition = output.flow_log_group_name != ""
error_message = "flow_log_group_name output must be non-empty when enable_flow_logs is true (the default)"
}
}
32 changes: 32 additions & 0 deletions modules/ha-hot-hot/aws/tests/feature_flags.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,35 @@ run "redis_disabled_creates_nothing" {
error_message = "redis_mode must be 'disabled' when managed Redis is off and no override is supplied."
}
}

run "flow_logs_enabled_by_default" {
command = plan

assert {
condition = length(aws_flow_log.vpc) == 1
error_message = "enable_flow_logs defaults to true and must create exactly one VPC flow log."
}
}

run "flow_logs_disabled_creates_nothing" {
command = plan

variables {
enable_flow_logs = false
}

assert {
condition = length(aws_flow_log.vpc) == 0
error_message = "enable_flow_logs = false must create zero VPC flow logs."
}

assert {
condition = length(aws_cloudwatch_log_group.flow_logs) == 0
error_message = "enable_flow_logs = false must create zero flow-log CloudWatch log groups."
}

assert {
condition = output.flow_log_group_name == ""
error_message = "flow_log_group_name must be empty string when enable_flow_logs is false."
}
}
6 changes: 6 additions & 0 deletions modules/ha-hot-hot/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ variable "enable_customer_managed_key" {
default = false
}

variable "enable_flow_logs" {
description = "Enable VPC Flow Logs for the provided VPC, sending ALL traffic to a CloudWatch log group named /aws/vpc-flow-logs/<name_prefix>. Matches the default stated in SECURITY-DEFAULTS.md."
type = bool
default = true
}

variable "alb_idle_timeout_seconds" {
type = number
default = 120
Expand Down
1 change: 1 addition & 0 deletions modules/sat-aws-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module "this" {
db_backup_retention_days = var.db_backup_retention_days
db_deletion_protection = var.db_deletion_protection
enable_customer_managed_key = var.enable_customer_managed_key
enable_flow_logs = var.enable_flow_logs
alb_idle_timeout_seconds = var.alb_idle_timeout_seconds
alb_min_tls_version = var.alb_min_tls_version
enable_management_access = var.enable_management_access
Expand Down
6 changes: 6 additions & 0 deletions modules/sat-aws-ha/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,9 @@ output "redis_mode" {
value = module.this.redis_mode
sensitive = false
}

output "flow_log_group_name" {
description = "CloudWatch log group name receiving VPC Flow Logs. Empty string when enable_flow_logs is false."
value = module.this.flow_log_group_name
sensitive = false
}
6 changes: 6 additions & 0 deletions modules/sat-aws-ha/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ variable "enable_customer_managed_key" {
default = false
}

variable "enable_flow_logs" {
description = "Enable VPC Flow Logs for the provided VPC, sending ALL traffic to a CloudWatch log group named /aws/vpc-flow-logs/<name_prefix>. Matches the default stated in SECURITY-DEFAULTS.md."
type = bool
default = true
}

variable "alb_idle_timeout_seconds" {
type = number
default = 120
Expand Down
Loading