I am working on a project to leverage the CIS foundations benchmark with terraform. I’ve already implemented the frame work in terraform. However, there are issues when trying to deal with multiple AWS accounts. My goal is to remove 9 AWS s3 buckets that are associated with cloudtrail logs. The benefit of removing these buckets is that it will reduce our AWS bill by roughly 10k.
My goal is to create a modular hierarchy like the one shown in the figure below.
My plan is to design a module that will conditionally provision s3 buckets and cloudtrails based on the aws environment. My method for approaching this has been to use a statement like so
for_each = var.environment == "billing" ? toset(["this"]) : []
For example,
resource "aws_cloudtrail" "nfcisbenchmark" {
for_each = var.environment == "billing" ? toset(["this"]) : []
name = "${var.name}"
s3_bucket_name = aws_s3_bucket.nfcisbenchmark_cloudtrail[each.key].id
enable_logging = true
# 3.2 Ensure CloudTrail log file validation is enabled (Automated)
enable_log_file_validation = true
# 3.1 Ensure CloudTrail is enabled in all regions (Automated)
is_multi_region_trail = true
# CIS Benchmark 3.1 Ensure CloudTrail is enabled in all regions
# ensuring that a multi-regions trail exists will ensure that Global Service Logging
# is enabled for a trail by default to capture recording of events generated on AWS
# global services
include_global_service_events = true
is_organization_trail = "${var.environment == "billing"? true : false}"
# 3.7 Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Automated)
kms_key_id = aws_kms_key.nfcisbenchmark.arn
depends_on = [aws_s3_bucket.nfcisbenchmark_cloudtrail]
cloud_watch_logs_role_arn = aws_iam_role.cloudwatch.arn
cloud_watch_logs_group_arn = "${aws_cloudwatch_log_group.nfcisbenchmark.arn}:*"
event_selector {
# 3.11 Ensure that Object-level logging for read events is enabled for S3 bucket (Automated)
read_write_type = "All"
include_management_events = true
}
// Tags
tags = {
Name = "${var.name}-cloudtrail"
cost_environment = "${var.environment == "production"? "production" : "non-production"}"
cost_category = "SEC"
cost_team_owner = "MOPRAV"
}
}
In this scenario the cloudtrail should only be created if the environment is “billing”. I am facing issues with creating the s3 buckets conditionally. Given,
resource aws_s3_bucket nfcisbenchmark_cloudtrail {
for_each = var.environment == "logging" ? toset(["this"]) : []
bucket = var.nf_logging_bucket_name
acl = "private"
force_destroy = true
# 3.6 Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Automated)
logging {
target_bucket = aws_s3_bucket.log_bucket_cloudtrail[each.key]
target_prefix = "log/"
}
}
Every single instance of aws_s3_bucket.log_bucket_cloudtrail
needs to use each.key
.
Expected:
run terraform apply
and the resources are provisioned
Actual:
on modules/nf_cis_benchmark/s3.tf line 45, in resource "aws_s3_bucket" "nfcisbenchmark_cloudtrail":
│ 45: target_bucket = aws_s3_bucket.log_bucket_cloudtrail[each.key]
│ ├────────────────
│ │ aws_s3_bucket.log_bucket_cloudtrail is object with 1 attribute "this"
│ │ each.key is "this"
Any advice on how to remedy this issue would be greatly appreciated.