# Copyright 2017 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 microservice deployment Parameters: Cluster: Description: param value for dev and prod stack JSON configuration files under service/ Type : 'AWS::SSM::Parameter::Value' Default: Cluster BetaPort: Description: param value for dev and prod stack JSON configuration files under service/ Type : 'AWS::SSM::Parameter::Value' Default: BetaPort LivePort: Description: param value for dev and prod stack JSON configuration files under service/ Type : 'AWS::SSM::Parameter::Value' Default: LivePort DevLoadBalancerArn: Type : 'AWS::SSM::Parameter::Value' Default: DevLoadBalancerArn DevBetaListenerArn: Type : 'AWS::SSM::Parameter::Value' Default: DevBetaListenerArn DevLiveListenerArn: Type : 'AWS::SSM::Parameter::Value' Default: DevLiveListenerArn ProdLoadBalancerArn: Type : 'AWS::SSM::Parameter::Value' Default: ProdLoadBalancerArn ProdBetaListenerArn: Type : 'AWS::SSM::Parameter::Value' Default: ProdBetaListenerArn ProdLiveListenerArn: Type : 'AWS::SSM::Parameter::Value' Default: ProdLiveListenerArn DevSubnet1: Type : 'AWS::SSM::Parameter::Value' Default: DevSubnet1 DevSubnet2: Type : 'AWS::SSM::Parameter::Value' Default: DevSubnet2 DevVPC: Type : 'AWS::SSM::Parameter::Value' Default: DevVPC ProdSubnet1: Type : 'AWS::SSM::Parameter::Value' Default: ProdSubnet1 ProdSubnet2: Type : 'AWS::SSM::Parameter::Value' Default: ProdSubnet2 ProdVPC: Type : 'AWS::SSM::Parameter::Value' Default: ProdVPC VPCCIDR: Type : 'AWS::SSM::Parameter::Value' Default: VPCCIDR InfrastructureTemplateBucket: Type : String Description: Name of S3 bucket that hosts the microservice infrastructure templates InfrastructureTemplateArchive: Type: String Description: Name of S3 object that contains the microservice infrastructure templates TemplateBucket: Type: String EcsCfnStackName: Type: String EcrRepository: Type: String ServiceName: Description: Name of the Project Type: String ArtifactBucket: Description: S3 Bucket, which will hold the artifacts Type: String 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 DevStackConfig: Default: dev-stack-configuration.json Description: The configuration file name for the dev stack Type: String ProdStackConfig: Default: prod-stack-configuration.json Description: The configuration file name for the prod stack Type: String Resources: SecOpsCodeBuildProject: Type: AWS::CodeBuild::Project Properties: Description: Compliance and Security checks for application EncryptionKey: !Ref CMKARN ServiceRole: !Sub ${ServiceName}-cb-role Artifacts: Type: CODEPIPELINE Environment: Type: linuxContainer ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/docker:1.12.1 EnvironmentVariables: - Name: AWS_DEFAULT_REGION Value: !Ref AWS::Region - Name: ServiceName Value: !Ref ServiceName - Name: TestAccount Value: !Ref TestAccount - Name: ArtifactBucket Value: !Ref ArtifactBucket - Name: TemplateBucket Value: !Ref TemplateBucket - Name: InfrastructureTemplateBucket Value: !Ref InfrastructureTemplateBucket - Name: ProductionAccount Value: !Ref ProductionAccount Name: !Sub ${ServiceName}-secopscodebuildproject Source: Type: CODEPIPELINE BuildSpec: | version: 0.2 phases: install: commands: - apt-get update && apt-get -y install python-pip - pip install --upgrade python - pip install --upgrade awscli - pip install boto3 TimeoutInMinutes: 10 Tags: - Key: Name Value: !Ref ServiceName CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Description: !Ref ServiceName EncryptionKey: !Ref CMKARN ServiceRole: !Sub "${ServiceName}-cb-role" Artifacts: Type: CODEPIPELINE Environment: Type: linuxContainer ComputeType: BUILD_GENERAL1_LARGE Image: aws/codebuild/docker:17.09.0 EnvironmentVariables: - Name: SERVICE_NAME Value: !Ref ServiceName - Name: AWS_DEFAULT_REGION Value: !Ref AWS::Region - Name: REPOSITORY_URI Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrRepository} - Name: CONFIG Value: !Ref DevStackConfig - Name: PRODCONFIG Value: !Ref ProdStackConfig Name: !Sub ${ServiceName}-codebuildproject Source: Type: CODEPIPELINE TimeoutInMinutes: 60 Tags: - Key: Name Value: !Ref ServiceName Pipeline: DependsOn: CodeBuildProject Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/${ServiceName}-pipeline-role" Name: !Sub ${ServiceName}-ecs-pipeline Stages: - Name: Source Actions: - Name: App ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !Ref ServiceName BranchName: master OutputArtifacts: - Name: SCCheckoutArtifact RunOrder: 1 RoleArn: !Sub arn:aws:iam::${TestAccount}:role/${ServiceName}-codecommit-role - Name: ContainerInfraTemplates ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 Configuration: S3Bucket: !Ref TemplateBucket S3ObjectKey: templates.zip OutputArtifacts: - Name: TemplateArtifact RunOrder: 1 - Name: MicroserviceInfraTemplates ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 Configuration: S3Bucket: !Ref InfrastructureTemplateBucket S3ObjectKey: !Ref InfrastructureTemplateArchive OutputArtifacts: - Name: InfraTemplateArtifact RunOrder: 1 - Name: Build Actions: - Name: Build ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProject InputArtifacts: - Name: SCCheckoutArtifact OutputArtifacts: - Name: BuildOutput RunOrder: 1 - Name: SecurityComplianceCodeCheck ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref SecOpsCodeBuildProject InputArtifacts: - Name: SCCheckoutArtifact RunOrder: 1 - Name: SecurityComplianceTemplatesCheck ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref SecOpsCodeBuildProject InputArtifacts: - Name: InfraTemplateArtifact RunOrder: 1 - Name: DeployToTestAccount Actions: - Name: DeployTestInfrastructure ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${ServiceName}-${EcsCfnStackName}-infrastructure" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: InfraTemplateArtifact::main.yaml TemplateConfiguration: InfraTemplateArtifact::test-stack-configuration.json ChangeSetName: !Sub ${ServiceName}-infrastructure ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${TestAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: InfraTemplateArtifact RunOrder: 1 - Name: DeployBeta ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${EcsCfnStackName}-${ServiceName}-ecs-beta" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: TemplateArtifact::ecs-cluster.yaml TemplateConfiguration: !Sub "BuildOutput::${DevStackConfig}" ParameterOverrides: !Sub | { "Tag" : { "Fn::GetParam" : [ "BuildOutput", "build.json", "tag" ] }, "Account": "${TestAccount}", "Repository": "${EcrRepository}", "Listener": "${DevBetaListenerArn}", "Port": "${BetaPort}", "LoadBalancerArn": "${DevLoadBalancerArn}", "Cluster": "${Cluster}", "Subnet1": "${DevSubnet1}", "Subnet2": "${DevSubnet2}", "VpcId": "${DevVPC}", "VpcCIDR": "${VPCCIDR}", "TemplateBucket": "${TemplateBucket}" } ChangeSetName: !Sub ${ServiceName}-ecs-dev ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${TestAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: BuildOutput - Name: TemplateArtifact RunOrder: 2 #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole - Name: DeployLive ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${EcsCfnStackName}-${ServiceName}-ecs-live" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: TemplateArtifact::ecs-cluster.yaml TemplateConfiguration: !Sub "BuildOutput::${DevStackConfig}" ParameterOverrides: !Sub | { "Tag" : { "Fn::GetParam" : [ "BuildOutput", "build.json", "tag" ] }, "Repository": "${EcrRepository}", "Account": "${TestAccount}", "Listener": "${DevLiveListenerArn}", "Port": "${LivePort}", "LoadBalancerArn": "${DevLoadBalancerArn}", "Cluster": "${Cluster}", "Subnet1": "${DevSubnet1}", "Subnet2": "${DevSubnet2}", "VpcId": "${DevVPC}", "VpcCIDR": "${VPCCIDR}", "TemplateBucket": "${TemplateBucket}" } ChangeSetName: !Sub ${ServiceName}-ecs-dev ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${TestAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: BuildOutput - Name: TemplateArtifact RunOrder: 3 #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/ToolsAcctCodePipelineCloudFormationRole - Name: approve-publish ActionTypeId: Category: Approval Owner: AWS Version: 1 Provider: Manual Configuration: CustomData: "Continue with app publish?" RunOrder: 4 - Name: DeployToProductionAccount Actions: - Name: DeployProdInfrastructure ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${EcsCfnStackName}-${ServiceName}-infrastructure" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: InfraTemplateArtifact::main.yaml TemplateConfiguration: InfraTemplateArtifact::test-stack-configuration.json ChangeSetName: !Sub ${ServiceName}-infrastructure ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: InfraTemplateArtifact RunOrder: 1 RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cc-role - Name: DeployBeta ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${EcsCfnStackName}-${ServiceName}-ecs-beta" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: TemplateArtifact::ecs-cluster.yaml TemplateConfiguration: !Sub "BuildOutput::${ProdStackConfig}" ParameterOverrides: !Sub | { "Tag" : { "Fn::GetParam" : [ "BuildOutput", "build.json", "tag" ] }, "Repository": "${EcrRepository}", "Account": "${TestAccount}", "Listener": "${ProdBetaListenerArn}", "Port": "${BetaPort}", "LoadBalancerArn": "${ProdLoadBalancerArn}", "Cluster": "${Cluster}", "Subnet1": "${ProdSubnet1}", "Subnet2": "${ProdSubnet2}", "VpcId": "${ProdVPC}", "VpcCIDR": "${VPCCIDR}", "TemplateBucket": "${TemplateBucket}" } ChangeSetName: !Sub ${ServiceName}-ecs-prod ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: BuildOutput - Name: TemplateArtifact RunOrder: 2 RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cc-role - Name: approve-publish ActionTypeId: Category: Approval Owner: AWS Version: 1 Provider: Manual Configuration: CustomData: "Continue with app publish to Production?" RunOrder: 3 - Name: Publish ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Sub "${EcsCfnStackName}-${ServiceName}-ecs-live" Capabilities: CAPABILITY_NAMED_IAM TemplatePath: TemplateArtifact::ecs-cluster.yaml TemplateConfiguration: !Sub "BuildOutput::${ProdStackConfig}" ParameterOverrides: !Sub | { "Tag" : { "Fn::GetParam" : [ "BuildOutput", "build.json", "tag" ] }, "Repository": "${EcrRepository}", "Account": "${TestAccount}", "Listener": "${ProdLiveListenerArn}", "Port": "${LivePort}", "LoadBalancerArn": "${ProdLoadBalancerArn}", "Cluster": "${Cluster}", "Subnet1": "${ProdSubnet1}", "Subnet2": "${ProdSubnet2}", "VpcId": "${ProdVPC}", "VpcCIDR": "${VPCCIDR}", "TemplateBucket": "${TemplateBucket}" } ChangeSetName: !Sub ${ServiceName}-ecs-prod ActionMode: CREATE_UPDATE #RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/cloudformationdeployer-role RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cfdeployer-role InputArtifacts: - Name: BuildOutput - Name: TemplateArtifact RunOrder: 4 RoleArn: !Sub arn:aws:iam::${ProductionAccount}:role/${ServiceName}-cc-role ArtifactStore: Type: S3 Location: !Ref ArtifactBucket EncryptionKey: Id: !Ref CMKARN Type: KMS