A configuration package to monitor Root Account activity as well as configuration compliance rules to ensure the Root Account's security configuration. The package includes:
AWSTemplateFormatVersion: "2010-09-09"
Description: ""
Resources:
S3SharedBucket:
Type: "AWS::S3::Bucket"
Properties:
LoggingConfiguration: {}
AccessControl: "LogDeliveryWrite"
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket:
Ref: "S3SharedBucket"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Principal:
Service:
- "cloudtrail.amazonaws.com"
- "config.amazonaws.com"
Action:
- "s3:GetBucketAcl"
Resource:
- Fn::GetAtt:
- "S3SharedBucket"
- "Arn"
Effect: "Allow"
Condition: {}
- Principal:
Service:
- "cloudtrail.amazonaws.com"
- "config.amazonaws.com"
Action:
- "s3:PutObject"
Resource:
- Fn::Join:
- ""
-
- ""
- Fn::GetAtt:
- "S3SharedBucket"
- "Arn"
- "/*"
Effect: "Allow"
Condition:
StringEquals:
s3:x-amz-acl: "bucket-owner-full-control"
DependsOn: "S3SharedBucket"
CloudTrail:
Type: "AWS::CloudTrail::Trail"
Properties:
TrailName: "ManagementEventsTrail"
IsLogging: true
EnableLogFileValidation: true
EventSelectors:
- IncludeManagementEvents: true
ReadWriteType: "All"
IsMultiRegionTrail: true
IncludeGlobalServiceEvents: true
S3BucketName:
Ref: "S3SharedBucket"
CloudWatchLogsLogGroupArn: "CloudTrailLogs"
CloudWatchLogsRoleArn:
Fn::GetAtt:
- "IamRoleForCwLogsCloudTrail"
- "Arn"
DependsOn:
- "BucketPolicy"
IamRoleForCwLogsCloudTrail:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: ""
Effect: "Allow"
Principal:
Service: "cloudtrail.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "allow-access-to-cw-logs"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
CWLogGroupForCloudTrail:
Type: "AWS::Logs::LogGroup"
Properties:
LogGroupName: "CloudTrailLogs"
RetentionInDays: 90
ConfigurationRecorder:
Type: "AWS::Config::ConfigurationRecorder"
Properties:
RoleARN:
Fn::GetAtt:
- "IamRoleForAwsConfig"
- "Arn"
RecordingGroup:
AllSupported: true
IncludeGlobalResourceTypes: true
DeliveryChannel:
Type: "AWS::Config::DeliveryChannel"
Properties:
S3BucketName:
Ref: "S3SharedBucket"
IamRoleForAwsConfig:
Type: "AWS::IAM::Role"
Properties:
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSConfigRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: ""
Effect: "Allow"
Principal:
Service: "config.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "allow-access-to-config-s3-bucket"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "s3:PutObject"
Resource:
- Fn::Join:
- ""
-
- Fn::GetAtt:
- "S3SharedBucket"
- "Arn"
- "/*"
Condition:
StringLike:
s3:x-amz-acl: "bucket-owner-full-control"
- Effect: "Allow"
Action:
- "s3:GetBucketAcl"
Resource:
Fn::GetAtt:
- "S3SharedBucket"
- "Arn"
RoleName: "iamRoleForAWSConfig"
SnsTopic1:
Type: "AWS::SNS::Topic"
Properties:
Subscription:
- Endpoint: "email@example.com"
Protocol: "email"
TopicName: "sns-topic"
ConfigRule1:
Type: "AWS::Config::ConfigRule"
Properties:
ConfigRuleName: "root-account-mfa-enabled"
Scope:
ComplianceResourceTypes: []
Description: "A Config rule that checks whether users of your AWS account require a multi-factor authentication (MFA) device to sign in with root credentials."
Source:
Owner: "AWS"
SourceIdentifier: "ROOT_ACCOUNT_MFA_ENABLED"
MaximumExecutionFrequency: "TwentyFour_Hours"
DependsOn:
- "ConfigurationRecorder"
ConfigRule3:
Type: "AWS::Config::ConfigRule"
Properties:
ConfigRuleName: "iam-root-access-key-check"
Scope:
ComplianceResourceTypes: []
Description: "A config rule that checks whether the root user access key is available. The rule is COMPLIANT if the user access key does not exist."
Source:
Owner: "AWS"
SourceIdentifier: "IAM_ROOT_ACCESS_KEY_CHECK"
MaximumExecutionFrequency: "TwentyFour_Hours"
DependsOn:
- "ConfigurationRecorder"
CwEvent1:
Type: "AWS::Events::Rule"
Properties:
Name: "detect-config-rule-compliance-changes"
Description: "A CloudWatch Event Rule that detects changes to AWS Config Rule compliance status and publishes change events to an SNS topic for notification."
State: "ENABLED"
Targets:
- Arn:
Ref: "SnsTopic1"
Id: "target-id1"
EventPattern:
detail-type:
- "Config Rules Compliance Change"
source:
- "aws.config"
SnsTopicPolicyCwEvent1:
Type: "AWS::SNS::TopicPolicy"
Properties:
PolicyDocument:
Statement:
- Sid: "__default_statement_ID"
Effect: "Allow"
Principal:
AWS: "*"
Action:
- "SNS:GetTopicAttributes"
- "SNS:SetTopicAttributes"
- "SNS:AddPermission"
- "SNS:RemovePermission"
- "SNS:DeleteTopic"
- "SNS:Subscribe"
- "SNS:ListSubscriptionsByTopic"
- "SNS:Publish"
- "SNS:Receive"
Resource:
Ref: "SnsTopic1"
Condition:
StringEquals:
AWS:SourceOwner:
Ref: "AWS::AccountId"
- Sid: "TrustCWEToPublishEventsToMyTopic"
Effect: "Allow"
Principal:
Service: "events.amazonaws.com"
Action: "sns:Publish"
Resource:
Ref: "SnsTopic1"
Topics:
- Ref: "SnsTopic1"
CwAlarm1:
Type: "AWS::CloudWatch::Alarm"
Properties:
AlarmName: "root_account_login"
AlarmDescription: "A CloudWatch Alarm that triggers if a root user uses the account."
MetricName: "RootUserEventCount"
Namespace: "CloudTrailMetrics"
Statistic: "Sum"
Period: "60"
EvaluationPeriods: "1"
Threshold: "1"
ComparisonOperator: "GreaterThanOrEqualToThreshold"
AlarmActions:
- Ref: "SnsTopic1"
TreatMissingData: "notBreaching"
MetricFilter1:
Type: "AWS::Logs::MetricFilter"
Properties:
LogGroupName:
Ref: "CWLogGroupForCloudTrail"
FilterPattern: "{ ($.userIdentity.type = \"Root\") && ($.userIdentity.invokedBy NOT EXISTS) && ($.eventType != \"AwsServiceEvent\") }"
MetricTransformations:
- MetricValue: "1"
MetricNamespace: "CloudTrailMetrics"
MetricName: "RootUserEventCount"
Parameters: {}
Metadata: {}
Conditions: {}