# # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # AWSTemplateFormatVersion: 2010-09-09 Description: Security Controls Parameters: CreateSns: Type: String Description: "Create SNS Config" Default: false AllowedValues: - true - false CreateS3BucketConfig: Type: String Description: "Create S3 Bucket for AWS Config" Default: false AllowedValues: - true - false ConfigS3Bucket: Type: String Description: S3 Bucket name for AWS Config. Leave empty for default name config-bucket-{AccountId} Default: "" ConfigSns: Type: String Description: Name of the topic. Leave empty to create SNS Topic with name Config Default: "" SecurityAccount: Type: String Description: Security Account Id, like 012345678912 Default: "012345678912" S3BucketSources: Type: String Description: S3 bucket name MaxLength: 63 MinLength: 3 Default: awsiammedia S3SourcesPrefix: Type: String Description: S3 prefix with sources WITH ending slash or leave empty Default: public/sample/AutomatedIncidentResponse319/ EnableGuardDuty: Type: String Description: "If already enabled set to false" Default: false AllowedValues: - true - false EnableConfig: Type: String Description: "If already enabled set to false" Default: false AllowedValues: - true - false SecurityRole: Type: String Description: Security role for incident response(IR). IR-Actions will be executed with this role Default: Security-IR-Role Metadata: 'AWS::CloudFormation::Interface': ParameterGroups: - Label: default: General Parameters: - S3BucketSources - S3SourcesPrefix - Label: default: Security Parameters: - SecurityRole - SecurityAccount - Label: default: AWS Config Parameters: - EnableConfig - CreateSns - ConfigSns - CreateS3BucketConfig - ConfigS3Bucket - Label: default: Guard Duty Parameters: - EnableGuardDuty ParameterLabels: S3BucketSources: default: S3 Bucket with sources S3SourcesPrefix: default: Prefix for S3 bucket with sources SecurityAccount: default: Security Account Id EnableConfig: default: Enable AWS Config CreateSns: default: Create SNS Topic ConfigSns: default: SNS Topic Name CreateS3BucketConfig: default: Create S3 Bucket for AWS Config ConfigS3Bucket: default: Bucket Name for AWS Config EnableGuardDuty: default: Enable Guard Duty SecurityRole: default: IR-Security Role Conditions: EnableGuardDutyCondition: !Equals - !Ref EnableGuardDuty - 'true' EnableConfigCondition: !Equals - !Ref EnableConfig - 'true' CreateS3BucketConfig: !Equals - !Ref CreateS3BucketConfig - 'true' GenerateS3BucketName: !Equals - !Ref ConfigS3Bucket - '' CreateSns: !Equals - !Ref CreateSns - 'true' GenerateSnsName: !Equals - !Ref ConfigSns - '' Resources: NewSns: Condition: CreateSns Type: "AWS::SNS::Topic" Properties: TopicName: !If [GenerateSnsName, 'Config', !Ref ConfigSns] NewS3BucketConfig: Condition: CreateS3BucketConfig Type: AWS::S3::Bucket Properties: BucketName: !If [GenerateS3BucketName, !Sub "config-bucket-${AWS::AccountId}", !Ref ConfigS3Bucket] BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 DeletionPolicy: Delete EnableConfigStack: Condition: EnableConfigCondition Type: "AWS::CloudFormation::Stack" Properties: TemplateURL: !Sub "https://s3.amazonaws.com/${RegionalS3Objects.Outputs.RegionalS3Bucket}/${S3SourcesPrefix}aws-landing-zone-enable-config.template.yaml" Parameters: TopicArn: !If [CreateSns, !Ref NewSns, !Ref ConfigSns] BucketName: !If [CreateS3BucketConfig, !Ref NewS3BucketConfig, !If [GenerateS3BucketName, !Sub "config-bucket-${AWS::AccountId}", !Ref ConfigS3Bucket]] Tags: - Key: Name Value: !Sub '${AWS::StackName}-ConfigEnableNestedStack' # Copy the regional S3 lambda functions RegionalS3Objects: Type: "AWS::CloudFormation::Stack" Properties: TemplateURL: !Sub "https://s3.amazonaws.com/${S3BucketSources}/${S3SourcesPrefix}copy-s3obj-to-regional-s3bucket.yaml" Parameters: S3BucketSources: !Ref S3BucketSources S3SourcesPrefix: !Ref S3SourcesPrefix S3Objects: "service_lambda_functions.zip, copy-s3obj-to-regional-s3bucket.yaml, service-account-config.yaml, aws-landing-zone-enable-config.template.yaml" Tags: - Key: Name Value: !Sub '${AWS::StackName}-CopyRegionalS3Bucket-NestedStack' # Config Rules rConfigRulesStack: # - Fn::If: # - EnableConfigCondition # - DependsOn: # - EnableConfigStack # - !Ref AWS::NoValue Type: "AWS::CloudFormation::Stack" Properties: TemplateURL: !Sub "https://s3.amazonaws.com/${RegionalS3Objects.Outputs.RegionalS3Bucket}/${S3SourcesPrefix}service-account-config.yaml" # NotificationARNs: [ !Ref StackConfigSns ] Parameters: S3BucketSources: !GetAtt RegionalS3Objects.Outputs.RegionalS3Bucket S3SourcesPrefix: !Ref S3SourcesPrefix KMSId: "" Tags: - Key: Name Value: !Sub '${AWS::StackName}-Config-NestedStack' - Key: Depends Value: !If [ EnableConfigCondition, !Ref EnableConfigStack, !Ref S3BucketSources ] # Create Guard Duty GuardDuty: Condition: EnableGuardDutyCondition Type: "AWS::GuardDuty::Detector" Properties: Enable: true CondigEventForwarding: Type: "AWS::Events::Rule" Properties: Description: Forward AWS Config events to security account Name: !Sub "Config-Forward2SecurityAccount" EventPattern: detail-type: - Config Rules Compliance Change source: - aws.config Targets: - Arn: !Sub "arn:aws:events:${AWS::Region}:${SecurityAccount}:event-bus/default" Id: 'ConfigSecurity' RoleArn: !GetAtt EventRole.Arn EventRole: Type: 'AWS::IAM::Role' Properties: Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: Service: - "events.amazonaws.com" Action: "sts:AssumeRole" Policies: - PolicyName: send-events-to-diff-account PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - events:PutEvents Resource: - !Sub "arn:aws:events:${AWS::Region}:${SecurityAccount}:event-bus/default" GDEventForwarding: Type: "AWS::Events::Rule" Properties: Description: Forward events to security account Name: !Sub "GuardDuty-Forward2SecurityAccount" EventPattern: source: - aws.guardduty detail-type: - GuardDuty Finding Targets: - Arn: !Sub "arn:aws:events:${AWS::Region}:${SecurityAccount}:event-bus/default" Id: 'CDSecurity' RoleArn: !GetAtt EventRole.Arn # This policy the used for incident response actions and executes on all resurces actions depending on SSM automation and lambda functions. You need to adjust to your use cases IrManagedPolicy: Type: "AWS::IAM::ManagedPolicy" Properties: ManagedPolicyName: !Sub "${SecurityRole}" PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - tag:GetResources - tag:UntagResources - tag:GetTagValues - tag:GetTagKeys - tag:TagResources - tag:GetResources - s3:ListBucketVersions - s3:GetBucketTagging - s3:ListBucket - s3:GetBucketPolicy - s3:PutEncryptionConfiguration - s3:GetBucketObjectLockConfiguration - s3:GetObjectAcl - s3:GetEncryptionConfiguration - s3:PutBucketAcl - s3:HeadBucket - s3:PutObjectAcl - s3:GetBucketPolicyStatus - s3:GetBucketPublicAccessBlock - s3:GetBucketAcl - s3:DeleteBucketPolicy - s3:PutObjectVersionAcl - s3:PutBucketPolicy - s3:PutBucketPublicAccessBlock - iam:GetRole - iam:AttachRolePolicy - iam:GetPolicy - iam:AttachUserPolicy - iam:GetUser - guardduty:GetFindings - guardduty:ArchiveFindings - ec2:*SecurityGroup* - ec2:Describe* - ec2:TerminateInstances - ec2:ModifyNetworkInterfaceAttribute - ssm:StartAutomationExecution Resource: - "*" SecurityIRRole: Type: 'AWS::IAM::Role' Properties: RoleName: !Ref SecurityRole Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: AWS: - !Sub "arn:aws:iam::${SecurityAccount}:root" Action: "sts:AssumeRole" ManagedPolicyArns: - Ref: IrManagedPolicy AWSSystemsManagerAutomationExecutionRole: Type: AWS::IAM::Role Properties: RoleName: AWS-SystemsManager-AutomationExecutionRole AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: Ref: SecurityAccount Action: - sts:AssumeRole - Effect: Allow Principal: Service: ssm.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - Ref: IrManagedPolicy - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole Path: "/" Policies: - PolicyName: ExecutionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - resource-groups:ListGroupResources - tag:GetResources Resource: "*" - Effect: Allow Action: - iam:PassRole Resource: Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/AWS-SystemsManager-AutomationExecutionRole Outputs: SecurityRole: Description: Role for security response Value: !GetAtt SecurityIRRole.Arn