--- AWSTemplateFormatVersion: '2010-09-09' Description: CodePipeline for Config Rules, EventBridge Rules, and Lambda Parameters: S3ComplianceResourceId: Description: S3 Bucket Name to exclude from Config Rule. Type: String EmailAddress: Description: Email Address for sending SNS notifications for CodeCommit Type: String Default: fake-email@fake-fake-fake-email.com RepositoryBranch: Description: The name of the branch for the CodeCommit repo Type: String Default: main AllowedPattern: "[\\x20-\\x7E]*" ConstraintDescription: Can contain only ASCII characters. CodeCommitS3Bucket: Description: S3 bucket that holds zip of source code for CodeCommit Repo Type: String CodeCommitS3Key: Description: zipfile key located in CodeCommitS3Bucket Type: String ConfigRuleName: Type: String Default: s3-bucket-server-side-encryption-enabled Description: The name that you assign to the AWS Config rule. MinLength: '1' ConstraintDescription: This parameter is required. MaximumExecutionFrequency: Type: String Default: Six_Hours Description: The frequency that you want AWS Config to run evaluations for the rule. MinLength: '1' ConstraintDescription: This parameter is required. AllowedValues: - One_Hour - Three_Hours - Six_Hours - Twelve_Hours - TwentyFour_Hours Resources: ConfigBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: AccessControl: BucketOwnerFullControl ConfigTopic: Type: AWS::SNS::Topic DeliveryChannel: Type: AWS::Config::DeliveryChannel Properties: ConfigSnapshotDeliveryProperties: DeliveryFrequency: !Ref MaximumExecutionFrequency S3BucketName: Ref: ConfigBucket SnsTopicARN: Ref: ConfigTopic ConfigBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref 'ConfigBucket' PolicyDocument: Version: '2012-10-17' Id: PutObjPolicy Statement: - Sid: DenyUnEncryptedObjects Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Sub arn:aws:s3:::${ConfigBucket}/* Condition: StringNotEquals: s3:x-amz-server-side-encryption: AES256 ConfigRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - config.amazonaws.com Version: '2012-10-17' Path: / Policies: - PolicyDocument: Statement: - Effect: Allow Action: sns:Publish Resource: !Ref 'ConfigTopic' - Effect: Allow Action: - s3:PutObject Resource: !Sub arn:aws:s3:::${ConfigBucket}/AWSLogs/${AWS::AccountId}/* Condition: StringLike: s3:x-amz-acl: bucket-owner-full-control - Effect: Allow Action: - s3:GetBucketAcl Resource: !Sub arn:aws:s3:::${ConfigBucket} PolicyName: root ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSConfigRole ConfigRecorder: Type: AWS::Config::ConfigurationRecorder Properties: RecordingGroup: AllSupported: true IncludeGlobalResourceTypes: true RoleARN: !GetAtt 'ConfigRole.Arn' AWSConfigRule: DependsOn: - DeliveryChannel - ConfigRecorder Type: AWS::Config::ConfigRule Properties: ConfigRuleName: Ref: ConfigRuleName Description: 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. InputParameters: {} Scope: ComplianceResourceId: !Ref 'S3ComplianceResourceId' ComplianceResourceTypes: - AWS::S3::Bucket Source: Owner: AWS SourceIdentifier: S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED ArtifactBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain MyLambdaTrustRole: Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Path: "/" Policies: - PolicyDocument: Statement: - Action: - s3:PutEncryptionConfiguration - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - lambda:GetFunction Effect: Allow Resource: "*" Version: '2012-10-17' PolicyName: MyLambdaWorkerPolicy Type: AWS::IAM::Role CodeBuildRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: codebuild-service PolicyDocument: Statement: - Action: - logs:* - lambda:* - cloudwatch:* - codebuild:* - s3:* Effect: Allow Resource: "*" Version: '2012-10-17' CodeBuildLambdaTrigger: Type: AWS::CodeBuild::Project Properties: Description: Build application ServiceRole: Fn::GetAtt: - CodeBuildRole - Arn Artifacts: Type: NO_ARTIFACTS Environment: EnvironmentVariables: - Name: S3_BUCKET Value: Ref: ArtifactBucket Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: "aws/codebuild/amazonlinux2-x86_64-standard:4.0" Source: BuildSpec: buildspec-lambda.yml Location: !Sub https://git-codecommit.${AWS::Region}.amazonaws.com/v1/repos/${AWS::StackName}/ Type: CODECOMMIT TimeoutInMinutes: 10 Tags: - Key: Owner Value: MyCodeBuildProject MySNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: Ref: EmailAddress Protocol: email CodeCommitRepo: Type: AWS::CodeCommit::Repository Properties: RepositoryName: Ref: PipelineBucket RepositoryDescription: CodeCommit Repository for Config Rule solution Code: S3: Bucket: !Ref CodeCommitS3Bucket Key: !Ref CodeCommitS3Key Triggers: - Name: MasterTrigger CustomData: Ref: AWS::StackName DestinationArn: Ref: MySNSTopic Events: - all CloudFormationTrustRole: Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: - cloudformation.amazonaws.com Path: "/" Policies: - PolicyDocument: Statement: - Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion Effect: Allow Resource: - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: ArtifactBucket - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: ArtifactBucket - "/*" - Action: - lambda:CreateFunction - lambda:DeleteFunction - lambda:AddPermission - lambda:UpdateFunction - lambda:UpdateFunctionCode - lambda:GetFunctionConfiguration - lambda:UpdateFunctionConfiguration - lambda:RemovePermission - lambda:TagResource - lambda:ListTags - lambda:UntagResource - lambda:InvokeFunction - sns:CreateTopic - sns:DeleteTopic - sns:ListTopics - sns:GetTopicAttributes - sns:SetTopicAttributes - s3:CreateBucket - s3:DeleteBucket - events:* Effect: Allow Resource: "*" - Action: - iam:PassRole Effect: Allow Resource: - Fn::GetAtt: - MyLambdaTrustRole - Arn - Action: - cloudformation:CreateChangeSet Effect: Allow Resource: "*" PolicyName: CloudFormationRolePolicy Type: AWS::IAM::Role CodePipelineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: codepipeline-service PolicyDocument: Statement: - Action: - s3:GetObject - s3:GetObjectVersion - s3:GetBucketVersioning Resource: "*" Effect: Allow - Action: - s3:PutObject Resource: - arn:aws:s3:::codepipeline* Effect: Allow - Action: - s3:GetObject - s3:GetObjectVersion - s3:GetBucketVersioning - s3:PutObject - iam:PassRole Resource: "*" Effect: Allow - Action: - codecommit:* - codebuild:* - cloudformation:* Resource: "*" Effect: Allow Version: '2012-10-17' CodeBuildCfnAnalysis: Type: AWS::CodeBuild::Project Properties: Description: Build application ServiceRole: Fn::GetAtt: - CodeBuildRole - Arn Artifacts: Type: NO_ARTIFACTS Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: "aws/codebuild/amazonlinux2-x86_64-standard:4.0" Source: BuildSpec: buildspec.yml Location: !Sub https://git-codecommit.${AWS::Region}.amazonaws.com/v1/repos/${AWS::StackName}/ Type: CODECOMMIT TimeoutInMinutes: 10 Tags: - Key: Owner Value: MyCodeBuildProject PipelineBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain Pipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt CodePipelineRole.Arn Stages: - Name: Source Actions: - InputArtifacts: [] Name: Source ActionTypeId: Category: Source Owner: AWS Version: '1' Provider: CodeCommit OutputArtifacts: - Name: MyApp Configuration: BranchName: Ref: RepositoryBranch RepositoryName: Ref: PipelineBucket RunOrder: 1 - Name: Build Actions: - InputArtifacts: - Name: MyApp Name: cfn_nag ActionTypeId: Category: Test Owner: AWS Version: '1' Provider: CodeBuild OutputArtifacts: [] Configuration: ProjectName: Ref: CodeBuildCfnAnalysis RunOrder: 1 - InputArtifacts: - Name: MyApp Name: BuildLambdaFunctions ActionTypeId: Category: Build Owner: AWS Version: '1' Provider: CodeBuild OutputArtifacts: - Name: lambdatrigger-BuildArtifact Configuration: ProjectName: Ref: CodeBuildLambdaTrigger RunOrder: 1 - Name: Deploy Actions: - InputArtifacts: - Name: lambdatrigger-BuildArtifact Name: GenerateChangeSetLambdaFunction ActionTypeId: Category: Deploy Owner: AWS Version: '1' Provider: CloudFormation OutputArtifacts: [] Configuration: ActionMode: CHANGE_SET_REPLACE ChangeSetName: pipeline-changeset RoleArn: Fn::GetAtt: - CloudFormationTrustRole - Arn Capabilities: CAPABILITY_IAM StackName: !Sub ${AWS::StackName}-${AWS::Region} TemplatePath: lambdatrigger-BuildArtifact::template-export.json RunOrder: 1 - ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: "1" Configuration: ActionMode: CHANGE_SET_EXECUTE ChangeSetName: pipeline-changeset StackName: !Sub ${AWS::StackName}-${AWS::Region} InputArtifacts: [] Name: ExecuteChangeSetLambdaFunction OutputArtifacts: [] RunOrder: 2 ArtifactStore: Type: S3 Location: !Ref PipelineBucket Outputs: PipelineUrl: Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline} Description: CodePipeline URL S3ComplianceResourceId: Value: !Ref S3ComplianceResourceId Description: Generated S3 bucket name LambdaTrustRole: Description: IAM role for AWS Lambda used for passRole to Lambda functions. Export: Name: !Sub ${AWS::StackName}-${AWS::Region}-LambdaTrustRole Value: Fn::GetAtt: - MyLambdaTrustRole - Arn