Permalink
Switch branches/tags
Find file Copy path
f00a6df Jul 6, 2017
1 contributor

Users who have contributed to this file

422 lines (397 sloc) 12.7 KB
Description: >
Create CodePipeline and CodeBuild resources for Blue/Green Deployment on ECS. For further reference, please review BluegreenRepo ==> https://github.com/awslabs/ecs-blue-green-deployment
Parameters:
GitHubRepo:
Type: String
GitHubBranch:
Type: String
GitHubToken:
Type: String
GitHubUser:
Type: String
TemplateBucket:
Type: String
Subnet1:
Type: AWS::EC2::Subnet::Id
Subnet2:
Type: AWS::EC2::Subnet::Id
VpcId:
Type: AWS::EC2::VPC::Id
VpcCIDR:
Type: String
Resources:
BlueGreenFlipLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub lambda-${GitHubRepo}-blue-green-swap
Handler: blue_green_flip.handler
Runtime: python2.7
Description: !Sub lambda-${GitHubRepo}-blue-green-swap
Code:
S3Bucket: !Ref TemplateBucket
S3Key: scripts.zip
MemorySize: 128
Timeout: 60
Role: !GetAtt BlueGreenFlipLambdaRole.Arn
BlueGreenFlipLambdaRole:
Type: AWS::IAM::Role
Properties:
#RoleName: !Sub lambda-${GitHubRepo}-blue-green-swap-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
BlueGreenFlipLambdaPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub lambda-${GitHubRepo}-blue-green-swap-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- elasticloadbalancing:*
- codepipeline:PutJobFailureResult
- codepipeline:PutJobSuccessResult
Resource: "*"
-
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
Roles:
-
!Ref BlueGreenFlipLambdaRole
Repository:
Type: AWS::ECR::Repository
DeletionPolicy: Retain
CloudFormationExecutionRole:
Type: AWS::IAM::Role
DeletionPolicy: Retain
Properties:
#RoleName: !Sub cfn-${AWS::StackName}
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "cloudformation.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- ecs:*
- ecr:*
- iam:*
- ec2:*
- elasticloadbalancing:*
- autoscaling:*
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
#RoleName: !Sub cb-${AWS::StackName}
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "codebuild.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ecr:GetAuthorizationToken
- cloudformation:Describe*
- elasticloadbalancing:Describe*
- codepipeline:Get*
- codebuild:BatchGetBuilds
- Resource: !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:GetObjectVersion
- Resource: !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${Repository}
Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
#RoleName: !Sub cp-${AWS::StackName}
Path: /
AssumeRolePolicyDocument: |
{
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": [ "codepipeline.amazonaws.com" ]},
"Action": [ "sts:AssumeRole" ]
}]
}
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
- !Sub arn:aws:s3:::${TemplateBucket}
- !Sub arn:aws:s3:::${TemplateBucket}/*
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- Resource: "*"
Effect: Allow
Action:
- codebuild:StartBuild
- codebuild:BatchGetBuilds
- cloudformation:*
- lambda:*
- iam:PassRole
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.1
phases:
install:
commands:
- apt-get update && apt-get -y install python-pip
- pip install --upgrade python
- pip install --upgrade awscli
pre_build:
commands:
- printenv
- echo -n "$CODEBUILD_LOG_PATH" > /tmp/build_id.out
- printf "%s:%s" "$REPOSITORY_URI" "$(cat /tmp/build_id.out)" > /tmp/build_tag.out
- printf '{"tag":"%s"}' "$(cat /tmp/build_id.out)" > /tmp/build.json
- $(aws ecr get-login)
build:
commands:
- docker build --tag "$(cat /tmp/build_tag.out)" .
post_build:
commands:
- docker push "$(cat /tmp/build_tag.out)"
artifacts:
files: /tmp/build.json
discard-paths: yes
Environment:
ComputeType: "BUILD_GENERAL1_SMALL"
Image: "aws/codebuild/docker:1.12.1"
Type: "LINUX_CONTAINER"
EnvironmentVariables:
- Name: AWS_DEFAULT_REGION
Value: !Ref AWS::Region
- Name: REPOSITORY_URI
Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository}
Name: !Sub ${AWS::StackName}-codebuildproject
ServiceRole: !Ref CodeBuildServiceRole
BlueGreenElbDiscovery:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.1
phases:
install:
commands:
- pip install --upgrade python
- pip install --upgrade awscli
- pip install --upgrade boto3
pre_build:
commands:
- printenv
- ls -ld $(find .)
- python deployer.py
artifacts:
files: cf_inputs.json
discard-paths: yes
Environment:
ComputeType: "BUILD_GENERAL1_SMALL"
Image: aws/codebuild/python:2.7.12
Type: "LINUX_CONTAINER"
EnvironmentVariables:
- Name: AWS_DEFAULT_REGION
Value: !Ref AWS::Region
- Name: ELB_NAME
Value: !Ref GitHubRepo
Name: !Sub ${AWS::StackName}-discoveryproject
ServiceRole: !Ref CodeBuildServiceRole
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: App
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: 1
Provider: GitHub
Configuration:
Owner: !Ref GitHubUser
Repo: !Ref GitHubRepo
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubToken
OutputArtifacts:
- Name: App
RunOrder: 1
- Name: Template
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: S3
OutputArtifacts:
- Name: Template
RunOrder: 1
Configuration:
S3Bucket: !Ref TemplateBucket
S3ObjectKey: templates.zip
- Name: Scripts
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: S3
OutputArtifacts:
- Name: Scripts
RunOrder: 1
Configuration:
S3Bucket: !Ref TemplateBucket
S3ObjectKey: scripts.zip
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: App
OutputArtifacts:
- Name: BuildOutput
RunOrder: 1
- Name: Discover
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref BlueGreenElbDiscovery
InputArtifacts:
- Name: Scripts
OutputArtifacts:
- Name: DiscoveryOutput
RunOrder: 2
- Name: Deploy-Approve-Swap
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ChangeSetName: Deploy
ActionMode: CREATE_UPDATE
StackName: !Sub "${AWS::StackName}-ecs-cluster"
Capabilities: CAPABILITY_NAMED_IAM
TemplatePath: Template::templates/ecs-cluster.yaml
RoleArn: !GetAtt CloudFormationExecutionRole.Arn
ParameterOverrides: !Sub |
{
"Subnet1": "${Subnet1}",
"Subnet2": "${Subnet2}",
"VpcId": "${VpcId}",
"VpcCIDR": "${VpcCIDR}",
"Code1" : { "Fn::GetParam" : [ "DiscoveryOutput", "cf_inputs.json", "Code1" ] },
"Code2" : { "Fn::GetParam" : [ "DiscoveryOutput", "cf_inputs.json", "Code2" ] },
"Repository": "${Repository}",
"GitHubRepo": "${GitHubRepo}",
"TemplateBucket": "${TemplateBucket}"
}
InputArtifacts:
- Name: Template
- Name: DiscoveryOutput
RunOrder: 1
- Name: approve-blue-green-swap
ActionTypeId:
Category: Approval
Owner: AWS
Version: 1
Provider: Manual
Configuration:
CustomData: "Continue with blue-green swap ?"
RunOrder: 2
- Name: swap-target-group
ActionTypeId:
Category: Invoke
Owner: AWS
Version: 1
Provider: Lambda
Configuration:
FunctionName: !Ref BlueGreenFlipLambda
UserParameters: !Sub |
{
"ElbName": "${GitHubRepo}"
}
RunOrder: 3
Outputs:
PipelineUrl:
Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}