Overview

A configuration package to monitor Amazon Machine Images (AMIs) creation and modifications as well as ensure the compliance and security of AMIs available in the account. The package includes:

Configure & Deploy

Configuration Presets

  • Enables AWS CloudTrail with streaming to a CloudWatch Log Group: Required to configure CloudWatch Alarms based on CloudTrail metrics
  • Enables AWS Config: Required to enable AWS Config Rules for continuous compliance monitoring
  • A shared S3 bucket is configured to store logs from AWS CloudTrail and AWS Config
  • Enables selected AWS Config rules and CloudWatch Alarms for notifications on important API activity.
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
Items
23
Size
12.3 KB
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
  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:
        'Fn::GetAtt':
          - CWLogGroupForCloudTrail
          - Arn
      CloudWatchLogsRoleArn:
        'Fn::GetAtt':
          - IamRoleForCwLogs
          - Arn
    DependsOn:
      - BucketPolicy
  IamRoleForCwLogs:
    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: ami_outdated_check
      Description: >-
        A config rule that checks whether all private AMIs are not older than X
        days.
      Scope:
        ComplianceResourceTypes:
          - 'AWS::EC2::Instance'
      InputParameters:
        NumberOfDays: '90'
        WhitelistedAmis: ' '
        WhitelistedInstances: ' '
      Source:
        Owner: CUSTOM_LAMBDA
        SourceIdentifier:
          'Fn::GetAtt':
            - LambdaFunctionForConfigRule1
            - Arn
        SourceDetails:
          - EventSource: aws.config
            MessageType: ScheduledNotification
            MaximumExecutionFrequency: TwentyFour_Hours
    DependsOn:
      - ConfigurationRecorder
  LambdaInvokePermissionsConfigRule1:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName:
        'Fn::GetAtt':
          - LambdaFunctionForConfigRule1
          - Arn
      Action: 'lambda:InvokeFunction'
      Principal: config.amazonaws.com
  LambdaFunctionForConfigRule1:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: LambdaForami_outdated_check
      Handler: index.lambda_handler
      Role:
        'Fn::GetAtt':
          - LambdaIamRoleConfigRule1
          - Arn
      Runtime: python3.6
      Code:
        S3Bucket:
          'Fn::Sub':
            - 'asecure-cloud-cf-aux-${Region}'
            - Region:
                Ref: 'AWS::Region'
        S3Key: AMI_OUTDATED_CHECK.zip
      Timeout: 300
    DependsOn: LambdaIamRoleConfigRule1
  LambdaIamRoleConfigRule1:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/service-role/AWSConfigRulesExecutionRole'
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies: []
      RoleName: IAMRoleForami_outdated_checkuSm
  ConfigRule2:
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: ami_not_public
      Description: >-
        A config rule that checks whether the Amazon Machine Images are not
        publicly accessible. The rule is NON_COMPLIANT if one or more Amazon
        Machine Images are publicly accessible.
      Scope:
        ComplianceResourceTypes:
          - 'AWS::::Account'
      Source:
        Owner: CUSTOM_LAMBDA
        SourceIdentifier:
          'Fn::GetAtt':
            - LambdaFunctionForConfigRule2
            - Arn
        SourceDetails:
          - EventSource: aws.config
            MessageType: ScheduledNotification
            MaximumExecutionFrequency: TwentyFour_Hours
    DependsOn:
      - ConfigurationRecorder
  LambdaInvokePermissionsConfigRule2:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName:
        'Fn::GetAtt':
          - LambdaFunctionForConfigRule2
          - Arn
      Action: 'lambda:InvokeFunction'
      Principal: config.amazonaws.com
  LambdaFunctionForConfigRule2:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: LambdaForami_not_public
      Handler: index.lambda_handler
      Role:
        'Fn::GetAtt':
          - LambdaIamRoleConfigRule2
          - Arn
      Runtime: python3.6
      Code:
        S3Bucket:
          'Fn::Sub':
            - 'asecure-cloud-cf-aux-${Region}'
            - Region:
                Ref: 'AWS::Region'
        S3Key: AMI_NOT_PUBLIC_CHECK.zip
      Timeout: 300
    DependsOn: LambdaIamRoleConfigRule2
  LambdaIamRoleConfigRule2:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
        - 'arn:aws:iam::aws:policy/service-role/AWSConfigRulesExecutionRole'
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies: []
      RoleName: IAMRoleForami_not_publicCfA
  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
  SnsTopicPolicy:
    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: ami_create
      AlarmDescription: >-
        A CloudWatch Alarm that triggers when new AMIs (Amazon Machine Images)
        are created or registered in the account.
      MetricName: AmiCreateEventCount
      Namespace: CloudTrailMetrics
      Statistic: Sum
      Period: '300'
      EvaluationPeriods: '1'
      Threshold: '1'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - Ref: SnsTopic1
      TreatMissingData: notBreaching
  MetricFilter1:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      LogGroupName:
        Ref: CWLogGroupForCloudTrail
      FilterPattern: '{ ($.eventName = RegisterImage) || ($.eventName = CreateImage) }'
      MetricTransformations:
        - MetricValue: '1'
          MetricNamespace: CloudTrailMetrics
          MetricName: AmiCreateEventCount
  CwAlarm2:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      AlarmName: ami_modification
      AlarmDescription: >-
        A CloudWatch Alarm that triggers when existing AMIs (Amazon Machine
        Images) are modified, deleted, copied or shared with other AWS accounts.
      MetricName: AmiModificationEventCount
      Namespace: CloudTrailMetrics
      Statistic: Sum
      Period: '300'
      EvaluationPeriods: '1'
      Threshold: '1'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - Ref: SnsTopic1
      TreatMissingData: notBreaching
  MetricFilter2:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      LogGroupName:
        Ref: CWLogGroupForCloudTrail
      FilterPattern: >-
        { ($.eventName = DeregisterImage) || ($.eventName = CopyImage) ||
        ($.eventName = ModifyImageAttribute) }
      MetricTransformations:
        - MetricValue: '1'
          MetricNamespace: CloudTrailMetrics
          MetricName: AmiModificationEventCount
Parameters: {}
Metadata: {}
Conditions: {}

© 2020 asecurecloud Inc. All Rights Reserved.