Ce produit n'est pas pris en charge par le site Datadog que vous avez sélectionné. ().
Cette page n'est pas encore disponible en français, sa traduction est en cours.
Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.

Metadata

Id: terraform-aws-cloudtrail-not-integrated-with-cloudwatch

Provider: AWS

Platform: Terraform

Severity: Low

Category: Observability

Learn More

Description

Integrating AWS CloudTrail with CloudWatch Logs is essential for real-time monitoring and alerting on account activity. If the cloud_watch_logs_group_arn and cloud_watch_logs_role_arn attributes are not set in the aws_cloudtrail resource, as in the following insecure configuration, CloudTrail events will only be stored in S3 with no efficient mechanism for real-time detection or automated response to suspicious activities:

resource "aws_cloudtrail" "example" {
  name = "tf-trail-foobar"
  s3_bucket_name = aws_s3_bucket.foo.id
  // cloud_watch_logs_group_arn and cloud_watch_logs_role_arn not set
}

Without CloudWatch integration, critical security or operational issues could go unnoticed, increasing the risk of unauthorized behavior persisting undetected in your AWS environment.

A secure Terraform configuration should explicitly connect CloudTrail to CloudWatch Logs. For example:

resource "aws_cloudtrail" "example" {
  name                          = "tf-trail-secure"
  s3_bucket_name                = aws_s3_bucket.foo.id
  cloud_watch_logs_group_arn    = aws_cloudwatch_log_group.cloudtrail_logs.arn
  cloud_watch_logs_role_arn     = aws_iam_role.cloudtrail_cloudwatch_role.arn
}

Compliant Code Examples

resource "aws_cloudwatch_log_group" "cloudtrail_log_group" {
  name = "aws-foundations-benchmark-1-4-0-terraform-3-4-remediated"
}


resource "aws_iam_role" "cloud_watch_logs_role" {
  name = "aws-foundations-benchmark-1-4-0-terraform-3-4-remediated"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy" "cloud_watch_policy" {
  name = "CloudWatch-policy"
  role = aws_iam_role.cloud_watch_logs_role.id

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream"
      ],
      "Resource": [
        "${aws_cloudwatch_log_group.cloudtrail_log_group.arn}:*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:PutLogEvents"
      ],
      "Resource": [
        "${aws_cloudwatch_log_group.cloudtrail_log_group.arn}:*"
      ]
    }
  ]
}
EOF
}


data "aws_caller_identity" "current" {}

resource "aws_cloudtrail" "negative1" {
  name                          = "tf-trail-foobar"
  s3_bucket_name                = aws_s3_bucket.foo.id
  s3_key_prefix                 = "prefix"
  include_global_service_events = false
  cloud_watch_logs_group_arn    = "${aws_cloudwatch_log_group.cloudtrail_log_group.arn}:*"
  cloud_watch_logs_role_arn     = aws_iam_role.cloud_watch_logs_role.arn
}

resource "aws_s3_bucket" "negative2" {
  bucket        = "tf-test-trail"
  force_destroy = true

  policy = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
              "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::tf-test-trail"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
              "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::tf-test-trail/prefix/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}
POLICY
}

Non-Compliant Code Examples

resource "aws_cloudtrail" "positive1" {
  name                          = "tf-trail-foobar"
  s3_bucket_name                = aws_s3_bucket.foo.id
  s3_key_prefix                 = "prefix"
  include_global_service_events = false
}

data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "positive4" {
  bucket        = "tf-test-trail"
  force_destroy = true

  policy = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
              "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::tf-test-trail"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
              "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::tf-test-trail/prefix/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}
POLICY
}