11# Description: This file implements CloudTrail and WAF.
22# -------------------------------------------------------------
33
4+ # -------------------------------------------------------------
5+ # CloudTrail and CloudWatch Resources
6+ # -------------------------------------------------------------
7+
48# CloudTrail S3 Bucket for log storage
59resource "aws_s3_bucket" "cloudtrail_logs" {
610 # The bucket name must be globally unique across all of AWS
711 # We use the account ID to ensure uniqueness
812 bucket = " cloudtrail-logs-${ data . aws_caller_identity . current . account_id } "
913}
1014
15+ # S3 Bucket Public Access Block
16+ # This is a best practice to prevent the bucket from being publicly accessible.
17+ resource "aws_s3_bucket_public_access_block" "cloudtrail_logs" {
18+ bucket = aws_s3_bucket. cloudtrail_logs . id
19+
20+ block_public_acls = true
21+ block_public_policy = true
22+ ignore_public_acls = true
23+ restrict_public_buckets = true
24+ }
25+
1126# S3 Bucket Policy for CloudTrail logs
1227resource "aws_s3_bucket_policy" "cloudtrail_logs_policy" {
1328 bucket = aws_s3_bucket. cloudtrail_logs . id
@@ -17,30 +32,49 @@ resource "aws_s3_bucket_policy" "cloudtrail_logs_policy" {
1732 Version = " 2012-10-17"
1833 Statement = [
1934 {
20- Effect = " Allow"
35+ Effect = " Allow"
2136 Principal = {
2237 Service = " cloudtrail.amazonaws.com"
2338 }
24- Action = " s3:PutObject"
25- Resource = " ${ aws_s3_bucket . cloudtrail_logs . arn } /AWSLogs/${ data . aws_caller_identity . current . account_id } /*"
39+ Action = " s3:PutObject"
40+ Resource = " ${ aws_s3_bucket . cloudtrail_logs . arn } /AWSLogs/${ data . aws_caller_identity . current . account_id } /*"
2641 },
2742 {
28- Effect = " Allow"
43+ Effect = " Allow"
2944 Principal = {
3045 Service = " cloudtrail.amazonaws.com"
3146 }
32- Action = " s3:GetBucketAcl"
33- Resource = aws_s3_bucket.cloudtrail_logs.arn
47+ Action = " s3:GetBucketAcl"
48+ Resource = aws_s3_bucket.cloudtrail_logs.arn
3449 },
3550 ]
3651 })
3752}
3853
54+ # S3 Bucket Versioning
55+ resource "aws_s3_bucket_versioning" "cloudtrail_logs_versioning" {
56+ bucket = aws_s3_bucket. cloudtrail_logs . id
57+ versioning_configuration {
58+ status = " Enabled"
59+ }
60+ }
61+
62+ # S3 Bucket Server-Side Encryption
63+ resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_s3_bucket_sse" {
64+ bucket = aws_s3_bucket. cloudtrail_logs . id
65+ rule {
66+ apply_server_side_encryption_by_default {
67+ sse_algorithm = " aws:kms"
68+ # Use the ARN of the KMS key data source
69+ kms_master_key_id = aws_kms_key. secrets_key . arn
70+ }
71+ }
72+ }
73+
3974# CloudTrail CloudWatch Log Group
4075resource "aws_cloudwatch_log_group" "cloudtrail_log_group" {
4176 name = " CloudTrail-Log-Group"
4277 retention_in_days = 90
43- kms_key_id = aws_kms_key. secrets_key . arn
4478}
4579
4680# IAM Role for CloudTrail to publish logs to CloudWatch
@@ -50,11 +84,11 @@ resource "aws_iam_role" "cloudtrail_role" {
5084 Version = " 2012-10-17"
5185 Statement = [
5286 {
53- Effect = " Allow"
87+ Effect = " Allow"
5488 Principal = {
5589 Service = " cloudtrail.amazonaws.com"
5690 }
57- Action = " sts:AssumeRole"
91+ Action = " sts:AssumeRole"
5892 },
5993 ]
6094 })
@@ -68,49 +102,32 @@ resource "aws_iam_role_policy" "cloudtrail_policy" {
68102 Version = " 2012-10-17"
69103 Statement = [
70104 {
71- Effect = " Allow"
72- Action = [
105+ Effect = " Allow"
106+ # ADDED `logs:DescribeLogGroups` to fix the validation error
107+ Action = [
73108 " logs:CreateLogStream" ,
74- " logs:PutLogEvents"
109+ " logs:PutLogEvents" ,
110+ " logs:DescribeLogGroups"
75111 ]
76- Resource = aws_cloudwatch_log_group.cloudtrail_log_group.arn
112+ Resource = " ${ aws_cloudwatch_log_group . cloudtrail_log_group . arn } :* "
77113 },
78114 ]
79115 })
80116}
81117
82118# AWS CloudTrail Trail
83119resource "aws_cloudtrail" "trail" {
84- name = " management-events-trail"
85- s3_bucket_name = aws_s3_bucket. cloudtrail_logs . id
86- is_multi_region_trail = true
87- enable_log_file_validation = true # Ensures log integrity
88- # Corrected ARN - removed the trailing :*
89- cloud_watch_logs_group_arn = aws_cloudwatch_log_group. cloudtrail_log_group . arn
90- cloud_watch_logs_role_arn = aws_iam_role. cloudtrail_role . arn
91- }
92-
93- # S3 Bucket Versioning
94- # This enables versioning on the bucket, which helps protect against accidental
95- # deletion or modification of log files.
96- resource "aws_s3_bucket_versioning" "cloudtrail_logs_versioning" {
97- bucket = aws_s3_bucket. cloudtrail_logs . id
98- versioning_configuration {
99- status = " Enabled"
100- }
101- }
102-
103- # S3 Bucket Server-Side Encryption
104- # This enforces server-side encryption for all objects in the bucket,
105- # ensuring your logs are encrypted at rest.
106- resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_s3_bucket_sse" {
107- bucket = aws_s3_bucket. cloudtrail_logs . id
108- rule {
109- apply_server_side_encryption_by_default {
110- sse_algorithm = " aws:kms"
111- kms_master_key_id = aws_kms_key. secrets_key . arn
112- }
113- }
120+ depends_on = [
121+ aws_cloudwatch_log_group . cloudtrail_log_group ,
122+ aws_iam_role . cloudtrail_role ,
123+ aws_iam_role_policy . cloudtrail_policy
124+ ]
125+ name = " management-events-trail"
126+ s3_bucket_name = aws_s3_bucket. cloudtrail_logs . id
127+ is_multi_region_trail = true
128+ enable_log_file_validation = true
129+ cloud_watch_logs_group_arn = " ${ aws_cloudwatch_log_group . cloudtrail_log_group . arn } :*"
130+ cloud_watch_logs_role_arn = aws_iam_role. cloudtrail_role . arn
114131}
115132
116133# Web Application Firewall (WAF)
@@ -126,18 +143,16 @@ resource "aws_wafv2_web_acl" "web_acl" {
126143 # that protects against common exploits like SQLi and XSS.
127144 rule {
128145 # Use a unique name for this rule
129- name = " CommonRuleSet"
130- priority = 1
146+ name = " CommonRuleSet"
147+ priority = 1
131148 statement {
132149 managed_rule_group_statement {
133- vendor_name = " AWS"
134- # This is the correct managed rule group name from AWS
135150 name = " AWSManagedRulesCommonRuleSet"
151+ vendor_name = " AWS"
136152 }
137153 }
138- action {
139- # This action should be 'block' to protect against common exploits
140- block {}
154+ override_action {
155+ none {}
141156 }
142157 visibility_config {
143158 cloudwatch_metrics_enabled = true
@@ -146,20 +161,19 @@ resource "aws_wafv2_web_acl" "web_acl" {
146161 }
147162 }
148163
149- # Rule to protect against Log4j2 vulnerabilities and other bad inputs
164+ # Rule to protect against known bad inputs and scanners
150165 rule {
151166 # Use a unique name for this rule
152- name = " KnownBadInputs"
153- priority = 2
167+ name = " KnownBadInputs"
168+ priority = 2
154169 statement {
155170 managed_rule_group_statement {
171+ name = " AWSManagedRulesAmazonIpReputationList"
156172 vendor_name = " AWS"
157- # This is the correct managed rule group name from AWS
158- name = " AWSManagedRulesKnownBadInputsRuleSet"
159173 }
160174 }
161- action {
162- block {}
175+ override_action {
176+ none {}
163177 }
164178 visibility_config {
165179 cloudwatch_metrics_enabled = true
0 commit comments