A configuration package to deploy AWS config rules to validate compliance with the Government of Canada’s Enterprise Guardrails for AWS. The configuration package includes the following resources:
AWSTemplateFormatVersion: '2010-09-09'
Description: ''
Resources:
S3SharedBucket:
Type: 'AWS::S3::Bucket'
Properties:
LoggingConfiguration: {}
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Suspended
AccessControl: LogDeliveryWrite
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: config.amazonaws.com
Action:
- 's3:GetBucketAcl'
Resource:
- 'Fn::GetAtt':
- S3SharedBucket
- Arn
Effect: Allow
Condition: {}
- Principal:
Service: 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
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/AWS_ConfigRole'
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
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
ConfigRule1:
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
ConfigRule2:
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-password-policy
Scope:
ComplianceResourceTypes: []
Description: A Config rule that checks whether the account password policy for IAM users meets the specified requirements.
InputParameters:
RequireUppercaseCharacters: 'true'
RequireLowercaseCharacters: 'true'
RequireSymbols: 'true'
RequireNumbers: 'true'
MinimumPasswordLength: '14'
PasswordReusePrevention: '24'
MaxPasswordAge: '90'
Source:
Owner: AWS
SourceIdentifier: IAM_PASSWORD_POLICY
MaximumExecutionFrequency: TwentyFour_Hours
DependsOn:
- ConfigurationRecorder
ConfigRule4:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: mfa-enabled-for-iam-console-access
Scope:
ComplianceResourceTypes: []
Description: A Config rule that checks whether AWS Multi-Factor Authentication (MFA) is enabled for all AWS Identity and Access Management (IAM) users that use a console password. The rule is COMPLIANT if MFA is enabled.
Source:
Owner: AWS
SourceIdentifier: MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS
MaximumExecutionFrequency: TwentyFour_Hours
DependsOn:
- ConfigurationRecorder
ConfigRule5:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: encrypted-volumes
Scope:
ComplianceResourceTypes:
- 'AWS::EC2::Volume'
Description: 'A Config rule that checks whether the EBS volumes that are in an attached state are encrypted. If you specify the ID of a KMS key for encryption using the kmsId parameter, the rule checks if the EBS volumes in an attached state are encrypted with that ...'
Source:
Owner: AWS
SourceIdentifier: ENCRYPTED_VOLUMES
DependsOn:
- ConfigurationRecorder
ConfigRule6:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: s3-bucket-server-side-encryption-enabled
Scope:
ComplianceResourceTypes:
- 'AWS::S3::Bucket'
Description: A Config rule that checks that your Amazon S3 bucket either has Amazon S3 default encryption enabled or that the S3 bucket policy explicitly denies put-object requests without server side encryption.
Source:
Owner: AWS
SourceIdentifier: S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED
DependsOn:
- ConfigurationRecorder
ConfigRule7:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: rds-storage-encrypted
Scope:
ComplianceResourceTypes:
- 'AWS::RDS::DBInstance'
Description: A Config rule that checks whether storage encryption is enabled for your RDS DB instances.
Source:
Owner: AWS
SourceIdentifier: RDS_STORAGE_ENCRYPTED
DependsOn:
- ConfigurationRecorder
ConfigRule8:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: elb-tls-https-listeners-only
Scope:
ComplianceResourceTypes:
- 'AWS::ElasticLoadBalancing::LoadBalancer'
Description: A Config rule that checks whether your Classic Load Balancer is configured with SSL or HTTPS listeners. The rule is applicable if a Classic Load Balancer has listeners.
Source:
Owner: AWS
SourceIdentifier: ELB_TLS_HTTPS_LISTENERS_ONLY
DependsOn:
- ConfigurationRecorder
ConfigRule9:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: alb-http-to-https-redirection-check
Scope:
ComplianceResourceTypes: []
Description: A Config rule that checks whether HTTP to HTTPS redirection is configured on all HTTP listeners of Application Load Balancers. The rule is NON_COMPLIANT if one or more HTTP listeners of Application Load Balancers do not have HTTP to HTTPS redirection c...
Source:
Owner: AWS
SourceIdentifier: ALB_HTTP_TO_HTTPS_REDIRECTION_CHECK
MaximumExecutionFrequency: TwentyFour_Hours
DependsOn:
- ConfigurationRecorder
ConfigRule10:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: internet-gateway-authorized-vpc-only
Scope:
ComplianceResourceTypes:
- 'AWS::EC2::InternetGateway'
Description: A config rule that checks that Internet gateways (IGWs) are only attached to an authorized Amazon Virtual Private Cloud (VPCs). The rule is NON_COMPLIANT if IGWs are not attached to an authorized VPC.
Source:
Owner: AWS
SourceIdentifier: INTERNET_GATEWAY_AUTHORIZED_VPC_ONLY
DependsOn:
- ConfigurationRecorder
ConfigRule11:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: cloudtrail-enabled
Scope:
ComplianceResourceTypes: []
Description: 'A config rule that checks whether AWS CloudTrail is enabled in your AWS account. Optionally, you can specify which S3 bucket, SNS topic, and Amazon CloudWatch Logs ARN to use.'
Source:
Owner: AWS
SourceIdentifier: CLOUD_TRAIL_ENABLED
MaximumExecutionFrequency: TwentyFour_Hours
DependsOn:
- ConfigurationRecorder
ConfigRule12:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: guardduty-enabled-centralized
Scope:
ComplianceResourceTypes: []
Description: 'A Config rule that checks whether Amazon GuardDuty is enabled in your AWS account and region. If you provide an AWS account for centralization, the rule evaluates the Amazon GuardDuty results in the centralized account. The rule is compliant when Amazo...'
Source:
Owner: AWS
SourceIdentifier: GUARDDUTY_ENABLED_CENTRALIZED
MaximumExecutionFrequency: TwentyFour_Hours
DependsOn:
- ConfigurationRecorder
ConfigRule13:
Type: 'AWS::Config::ConfigRule'
Properties:
ConfigRuleName: cloudtrail_s3_access_logging
Scope:
ComplianceResourceTypes:
- 'AWS::CloudTrail::Trail'
- 'AWS::S3::Bucket'
Description: A config rule that evaluates whether access logging is enabled on the CloudTrail S3 bucket and the S3 bucket is not publicly accessible.
Source:
Owner: CUSTOM_LAMBDA
SourceIdentifier:
'Fn::GetAtt':
- LambdaFunctionForConfigRule13
- Arn
SourceDetails:
- EventSource: aws.config
MessageType: ConfigurationItemChangeNotification
- EventSource: aws.config
MessageType: OversizedConfigurationItemChangeNotification
DependsOn:
- ConfigurationRecorder
LambdaInvokePermissionsConfigRule13:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName:
'Fn::GetAtt':
- LambdaFunctionForConfigRule13
- Arn
Action: 'lambda:InvokeFunction'
Principal: config.amazonaws.com
LambdaFunctionForConfigRule13:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: LambdaForcloudtrail_s3_access_logging
Handler: index.lambda_handler
Role:
'Fn::GetAtt':
- LambdaIamRoleConfigRule13
- Arn
Runtime: python2.7
Code:
ZipFile:
'Fn::Join':
- |+
- - ''
- import json
- import boto3
- import datetime
- import time
- from botocore.exceptions import ClientError
- 'def lambda_handler(event, context):'
- ' # get the trail for the current region'
- ' client_ct = boto3.client(''cloudtrail'')'
- ' for trail in client_ct.describe_trails(includeShadowTrails = False)[''trailList'']:'
- ' annotation = '''''
- ' is_publicly_accessible = False'
- ' s3_bucket_name = '''''
- ' is_compliant = True'
- ' # check if the cloudtrail s3 bucket is publicly accessible and logged'
- ' if trail[''S3BucketName'']:'
- ' s3_bucket_name = trail[''S3BucketName'']'
- ' client_s=boto3.client(''s3'')'
- ' try:'
- ' for grant in client_s.get_bucket_acl(Bucket = s3_bucket_name)[''Grants'']:'
- ' # verify cloudtrail s3 bucket ACL'
- ' if grant[''Permission''] in [''READ'',''FULL_CONTROL''] and (''URI'' in grant[''Grantee''] and (''AuthenticatedUsers'' in grant[''Grantee''][''URI''] or ''AllUsers'' in grant[''Grantee''][''URI''])):'
- ' is_publicly_accessible = True'
- ' if is_publicly_accessible:'
- ' is_compliant = False'
- ' annotation = annotation + '' The CloudTrail S3 bucket ''{}'' is publicly accessible.''.format(s3_bucket_name)'
- ' # verify cloudtrail s3 bucket logging'
- ' response = client_s.get_bucket_logging(Bucket = s3_bucket_name)'
- ' if ''LoggingEnabled'' not in response:'
- ' is_compliant=False'
- ' annotation = annotation + '' The CloudTrail S3 bucket ''{}'' does not have logging enabled.''.format(s3_bucket_name)'
- ' except Exception as ex:'
- ' print ex'
- ' is_compliant = False'
- ' annotation = annotation + '' There was an error looking up CloudTrail S3 bucket ''{}''.''.format(s3_bucket_name)'
- ' else:'
- ' annotation = annotation + '' CloudTrail is not integrated with S3.'''
- ' result_token = ''No token found.'''
- ' if ''resultToken'' in event: result_token = event[''resultToken'']'
- ' evaluations = ['
- ' {'
- ' ''ComplianceResourceType'': ''AWS::S3::Bucket'','
- ' ''ComplianceResourceId'': s3_bucket_name,'
- ' ''ComplianceType'': ''COMPLIANT'' if is_compliant else ''NON_COMPLIANT'','
- ' ''OrderingTimestamp'': datetime.datetime.now()'
- ' }'
- ' ]'
- ' if is_compliant: annotation = ''Acces logging is enabled on the CloudTrail S3 bucket ''{}'' and the S3 bucket is not publicly accessible''.format(s3_bucket_name)'
- ' if annotation: evaluations[0][''Annotation''] = annotation'
- ' config = boto3.client(''config'')'
- ' config.put_evaluations('
- ' Evaluations = evaluations,'
- ' ResultToken = result_token'
- ' )'
- ''
Timeout: 300
DependsOn: LambdaIamRoleConfigRule13
LambdaIamRoleConfigRule13:
Type: 'AWS::IAM::Role'
Properties:
RoleName: IAMRoleForcloudtrail_s3_access_loggingUdB
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSCloudTrailReadOnlyAccess'
- 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess'
- 'arn:aws:iam::aws:policy/service-role/AWSConfigRulesExecutionRole'
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Parameters: {}
Metadata: {}
Conditions: {}