diff --git a/aws_cloudtrail_eventbridge/cloudtrail-eventbridge.yaml b/aws_cloudtrail_eventbridge/cloudtrail-eventbridge.yaml new file mode 100644 index 00000000..710bb150 --- /dev/null +++ b/aws_cloudtrail_eventbridge/cloudtrail-eventbridge.yaml @@ -0,0 +1,178 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Datadog AWS Cloudtrail Eventbridge Logs Integration +Parameters: + ApiKey: + Description: >- + Your Datadog API Key + Type: String + AllowedPattern: .+ + ConstraintDescription: ApiKey is required + NoEcho: true + DatadogSite: + Description: >- + Define your Datadog Site to send data to. + Type: String + Default: 'datadoghq.com' + ConstraintDescription: DatadogSite is required + AllowedValues: + - datadoghq.com + - datadoghq.eu + - us3.datadoghq.com + - us5.datadoghq.com + - ddog-gov.com +Resources: + DatadogCloudtrailLogs: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: "datadog-eventbridge-cloudtrail-stream" + RetentionInDays: 14 + HTTPLogStream: + Type: AWS::Logs::LogStream + Properties: + LogGroupName: !Ref DatadogCloudtrailLogs + LogStreamName: "http_endpoint_delivery" + S3Backup: + Type: AWS::Logs::LogStream + Properties: + LogGroupName: !Ref DatadogCloudtrailLogs + LogStreamName: "s3_backup" + DatadogCloudtrailBackupBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub "datadog-aws-cloudtrail-backup-${AWS::AccountId}-${AWS::Region}" + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: "aws:kms" + PublicAccessBlockConfiguration: + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true + DatadogCloudtrailEventbridgeRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Sub "DatadogCloudtrailEventbridgeRole-${AWS::Region}" + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - events.amazonaws.com + Action: + - "sts:AssumeRole" + Path: / + Policies: + - PolicyName: "datadog_eventbridge_invoke_firehose_policy" + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - "firehose:PutRecord" + - "firehose:PutRecordBatch" + Resource: + - !Sub "arn:aws:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/datadog-eventbridge-cloudtrail-stream" + - PolicyName: "datadog_eventbridge_log_policy" + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - "logs:CreateLogGroup" + - "logs:CreateLogStream" + - "logs:PutLogEvents" + - "logs:DescribeLogStreams" + Resource: + - !Sub "arn:aws:firehose:${AWS::Region}:${AWS::AccountId}:deliverystream/datadog-eventbridge-cloudtrail-stream" + Description: A cloudtrail stream role + DatadogCloudtrailServiceRole: + Type: "AWS::IAM::Role" + Properties: + RoleName: !Sub "DatadogCloudtrailServiceRole-${AWS::Region}" + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: "Allow" + Principal: + Service: + - "firehose.amazonaws.com" + Action: + - 'sts:AssumeRole' + Path: / + Policies: + - PolicyName: "datadog_cloudtrail_stream_s3_policy" + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: "Allow" + Action: + - "s3:AbortMultipartUpload" + - "s3:GetBucketLocation" + - "s3:GetObject" + - "s3:ListBucket" + - "s3:ListBucketMultipartUploads" + - "s3:PutObject" + Resource: + - !Sub "arn:aws:s3:::datadog-aws-cloudtrail-backup-${AWS::AccountId}-${AWS::Region}" + - !Sub "arn:aws:s3:::datadog-aws-cloudtrail-backup-${AWS::AccountId}-${AWS::Region}/*" + DatadogCloudtrailKinesisFirehose: + Type: AWS::KinesisFirehose::DeliveryStream + Properties: + DeliveryStreamName: "datadog-eventbridge-cloudtrail-stream" + DeliveryStreamType: "DirectPut" + HttpEndpointDestinationConfiguration: + BufferingHints: + SizeInMBs: 4 + IntervalInSeconds: 60 + EndpointConfiguration: + Url: !Sub "https://aws-kinesis-http-intake.logs.${DatadogSite}/v1/input" + Name: "Kinesis intake" + AccessKey: !Ref ApiKey + CloudWatchLoggingOptions: + Enabled: True + LogGroupName: !Ref DatadogCloudtrailLogs + LogStreamName: "http_endpoint_delivery" + RoleARN: !GetAtt DatadogCloudtrailServiceRole.Arn + RetryOptions: + DurationInSeconds: 60 + S3BackupMode: "FailedDataOnly" + S3Configuration: + RoleARN: !GetAtt DatadogCloudtrailServiceRole.Arn + BucketARN: !GetAtt DatadogCloudtrailBackupBucket.Arn + ErrorOutputPrefix: "datadog_cloudtrail" + BufferingHints: + SizeInMBs: 4 + IntervalInSeconds: 60 + CompressionFormat: "GZIP" + CloudWatchLoggingOptions: + Enabled: True + LogGroupName: !Ref DatadogCloudtrailLogs + LogStreamName: "s3_backup" + Tags: + - Key: "Team" + Value: "aws-integration" + - Key: "StreamAccountID" + Value: !Ref "AWS::AccountId" + DatadogCloudtrailEventbridgeRule: + Type: AWS::Events::Rule + Properties: + Description: "Eventbridge Rule to Forward Cloudtrail Events to Datadog" + EventBusName: "default" + EventPattern: + detail-type: + - AWS API Call via CloudTrail + - AWS Insight via CloudTrail + - AWS Console Sign In via CloudTrail + - AWS Console Action via CloudTrail + - AWS Service Event via CloudTrail + Name: "datadog-eventbridge-cloudtrail" + RoleArn: !GetAtt DatadogCloudtrailEventbridgeRole.Arn + State: ENABLED + Targets: + - Arn: !GetAtt + - DatadogCloudtrailKinesisFirehose + - Arn + Id: Id123 + RoleArn: !GetAtt DatadogCloudtrailEventbridgeRole.Arn diff --git a/aws_cloudtrail_eventbridge/release.sh b/aws_cloudtrail_eventbridge/release.sh new file mode 100755 index 00000000..b56b2095 --- /dev/null +++ b/aws_cloudtrail_eventbridge/release.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Usage: ./release.sh + +set -e + +# Read the S3 bucket +if [ -z "$1" ]; then + echo "Must specify a S3 bucket to publish the template" + exit 1 +else + BUCKET=$1 +fi + +# Upload templates to a private bucket -- useful for testing +if [[ $# -eq 2 ]] && [[ $2 = "--private" ]]; then + PRIVATE_TEMPLATE=true +else + PRIVATE_TEMPLATE=false +fi + +# Confirm to proceed +for i in *.yaml; do + [ -f "$i" ] || break + echo "About to upload $i to s3://${BUCKET}/aws/$i" +done +read -p "Continue (y/n)?" CONT +if [ "$CONT" != "y" ]; then + echo "Exiting" + exit 1 +fi + +# Update bucket placeholder +# Use datadog-cloudformation-template as the s3 template for production +cp cloudtrail-eventbridge.yaml cloudtrail-eventbridge.yaml.bak +perl -pi -e "s//${BUCKET}/g" cloudtrail-eventbridge.yaml +trap 'mv cloudtrail-eventbridge.yaml.bak cloudtrail-eventbridge.yaml' EXIT + +# Upload +if [ "$PRIVATE_TEMPLATE" = true ] ; then + aws s3 cp . s3://${BUCKET}/aws --recursive --exclude "*" --include "*.yaml" +else + aws s3 cp . s3://${BUCKET}/aws --recursive --exclude "*" --include "*.yaml" \ + --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers +fi +echo "Done uploading the template, and here is the CloudFormation quick launch URL" +echo "https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?stackName=datadog-aws-cloudtrail-eventbridge&templateURL=https://${BUCKET}.s3.amazonaws.com/aws/cloudtrail-eventbridge.yaml" + +echo "Done!"