# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with # the License. A copy of the License is located at # http://aws.amazon.com/apache2.0/ # or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and # limitations under the License. AWSTemplateFormatVersion: '2010-09-09' Description: CodePipeline for the Sample Lambda Function (uksb-1qfmusbr5) Parameters: ProjectName: Description: Name of the Project Type: String Default: sample-lambda S3Bucket: Description: S3 Bucket, which will hold the artifacts Type: String DevAccount: Description: AWS AccountNumber for dev Type: Number TestAccount: Description: AWS AccountNumber for test Type: Number ProductionAccount: Description: AWS AccountNumber for production Type: Number CMKARN: Description: ARN of the KMS CMK creates in Tools account Type: String CrossAccountCondition: Description: Conditionally creates the resources for cross account access Type: String Default: false Conditions: AddCodeBuildResource: !Equals [ !Ref CrossAccountCondition, true ] Resources: BuildProjectRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ProjectName}-CodeBuildRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - sts:AssumeRole Path: / BuildProjectPolicy: Type: AWS::IAM::Policy DependsOn: S3BucketPolicy Properties: PolicyName: !Sub ${ProjectName}-CodeBuildPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:PutObject - s3:GetBucketPolicy - s3:GetObject - s3:ListBucket Resource: - !Join ['',['arn:aws:s3:::',!Ref S3Bucket, '/*']] - !Join ['',['arn:aws:s3:::',!Ref S3Bucket]] - Effect: Allow Action: - kms:* Resource: !Ref CMKARN - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:* - Effect: Allow Action: - iam:SimulateCustomPolicy - iam:SimulatePrincipalPolicy Resource: "*" Roles: - !Ref BuildProjectRole BuildProject: Type: AWS::CodeBuild::Project Properties: Description: !Sub - '${Project}/BuildCBProject' - { Project: !Ref ProjectName } EncryptionKey: !Ref CMKARN ServiceRole: !GetAtt BuildProjectRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:2.0 EnvironmentVariables: - Name: S3Bucket Value: !Ref S3Bucket - Name: KMSKey Value: !Ref CMKARN Source: Type: CODEPIPELINE BuildSpec: | version: 0.2 phases: install: runtime-versions: python: 3.7 commands: - printenv - ls -R - pip install -r scripts/requirements.txt -t "$PWD" build: commands: - aws cloudformation package --template-file lambda-cloudformation.yaml --s3-bucket $S3Bucket --s3-prefix sample-lambda/codebuild --output-template-file samtemplate.yaml artifacts: files: - samtemplate.yaml - scripts/* discard-paths: yes TimeoutInMinutes: 10 Tags: - Key: Name Value: !Ref ProjectName TestProject: Type: AWS::CodeBuild::Project Properties: Description: !Sub - '${Project}/TestCBProject' - { Project: !Ref ProjectName } EncryptionKey: !Ref CMKARN ServiceRole: !GetAtt BuildProjectRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:2.0 Source: Type: CODEPIPELINE BuildSpec: | version: 0.2 phases: install: runtime-versions: python: 3.7 commands: - printenv - ls -R - pip install -r requirements.txt -t "$PWD" build: commands: - python -m unittest test_module.py TimeoutInMinutes: 10 Tags: - Key: Name Value: !Ref ProjectName PipeLineRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ProjectName}-codepipeline-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: - sts:AssumeRole Path: / PipelinePolicy: Type: AWS::IAM::Policy DependsOn: S3BucketPolicy Properties: PolicyName: !Sub ${ProjectName}-codepipeline-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codepipeline:* - iam:ListRoles - cloudformation:Describe* - cloudFormation:List* - codecommit:List* - codecommit:Get* - codecommit:GitPull - codecommit:UploadArchive - codecommit:CancelUploadArchive - codebuild:BatchGetBuilds - codebuild:StartBuild - cloudformation:CreateStack - cloudformation:DeleteStack - cloudformation:DescribeStacks - cloudformation:UpdateStack - cloudformation:CreateChangeSet - cloudformation:DeleteChangeSet - cloudformation:DescribeChangeSet - cloudformation:ExecuteChangeSet - cloudformation:SetStackPolicy - cloudformation:ValidateTemplate - iam:PassRole - s3:ListAllMyBuckets - s3:GetBucketLocation Resource: - "*" - Effect: Allow Action: - kms:Decrypt Resource: !Ref CMKARN - Effect: Allow Action: - s3:PutObject - s3:GetBucketPolicy - s3:GetObject - s3:ListBucket Resource: - !Join ['',['arn:aws:s3:::',!Ref S3Bucket, '/*']] - !Join ['',['arn:aws:s3:::',!Ref S3Bucket]] - Effect: Allow Action: - sts:AssumeRole Resource: - !Sub arn:aws:iam::${DevAccount}:role/ToolsAcctCodePipelineCodeCommitRole - !Sub arn:aws:iam::${ProductionAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole Roles: - !Ref PipeLineRole Pipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt PipeLineRole.Arn Name: !Ref AWS::StackName Stages: - Name: Source Actions: - Name: App ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !Ref ProjectName BranchName: master OutputArtifacts: - Name: SCCheckoutArtifact RunOrder: 1 RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${DevAccount}:role/ToolsAcctCodePipelineCodeCommitRole - !Ref AWS::NoValue - Name: Build Actions: - Name: Build ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref BuildProject RunOrder: 1 InputArtifacts: - Name: SCCheckoutArtifact OutputArtifacts: - Name: BuildOutput - Name: Test Actions: - Name: RunUnitTests ActionTypeId: Category: Test Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref TestProject InputArtifacts: - Name: BuildOutput - Name: DeployToTest Actions: - Name: CreateChangeSetTest ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: ChangeSetName: sample-lambda-dev ActionMode: CHANGE_SET_REPLACE StackName: sample-lambda-dev Capabilities: CAPABILITY_NAMED_IAM TemplatePath: BuildOutput::samtemplate.yaml RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role - !Ref AWS::NoValue InputArtifacts: - Name: BuildOutput RunOrder: 1 RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Ref AWS::NoValue - Name: DeployChangeSetTest ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: ChangeSetName: sample-lambda-dev ActionMode: CHANGE_SET_EXECUTE StackName: sample-lambda-dev RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role - !Ref AWS::NoValue InputArtifacts: - Name: BuildOutput RunOrder: 2 RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Ref AWS::NoValue - Name: DeployToProduction Actions: - Name: CreateChangeSetProd ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: ChangeSetName: sample-lambda-test ActionMode: CHANGE_SET_REPLACE StackName: sample-lambda-test Capabilities: CAPABILITY_NAMED_IAM TemplatePath: BuildOutput::samtemplate.yaml RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${ProductionAccount}:role/cloudformationdeployer-role - !Ref AWS::NoValue InputArtifacts: - Name: BuildOutput RunOrder: 1 RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${ProductionAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Ref AWS::NoValue - Name: DeployChangeSetProd ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: ChangeSetName: sample-lambda-test ActionMode: CHANGE_SET_EXECUTE StackName: sample-lambda-test RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${ProductionAccount}:role/cloudformationdeployer-role - !Ref AWS::NoValue InputArtifacts: - Name: BuildOutput RunOrder: 2 RoleArn: Fn::If: - AddCodeBuildResource - !Sub arn:aws:iam::${ProductionAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Ref AWS::NoValue ArtifactStore: Type: S3 Location: !Ref S3Bucket EncryptionKey: Id: !Ref CMKARN Type: KMS S3BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref S3Bucket PolicyDocument: Statement: - Action: - s3:* Effect: Allow Resource: - !Sub arn:aws:s3:::${S3Bucket} - !Sub arn:aws:s3:::${S3Bucket}/* Principal: AWS: - !Sub arn:aws:iam::${DevAccount}:role/ToolsAcctCodePipelineCodeCommitRole - !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role - !Sub arn:aws:iam::${ProductionAccount}:role/ToolsAcctCodePipelineCloudFormationRole - !Sub arn:aws:iam::${ProductionAccount}:role/cloudformationdeployer-role - !GetAtt [BuildProjectRole,Arn]