データアナリティクス事業本部のueharaです。
今回は、CodePipeline (Github version 2接続) とCodeDeployを利用したパイプラインをCloudFromationで作成してみたいと思います。
はじめに
今回作成するパイプラインは以下の通り、SourceとなるGithubへのコミットをトリガーに、EC2へのデプロイを行うようなパイプラインを想定します。
前提
本記事では、デプロイ対象のEC2が既に準備されていることを前提としています。
簡単に概要だけ説明すると、以下の作業が必要になります。
- IAMロールの設定(AWSCodeDeployRoleポリシーのアタッチ)
- CodeDeploy Agentのインストール(参考)
- デプロイ対象として特定するためのタグの設定
なお、CodeDeployで利用できるサンプルアプリケーションはAWS公式にて公開されており、こちらを参考にダウンロード可能です。
Githubとの接続
CodePipelineとGithubとの接続については、従来のOAuthトークンを使用したversion 1と、CodeStarSourceConnectionを使ったversion 2があります。
現在、version 1の接続方法は非推奨となっており(参考)、version 2の利用が推奨されていることから、今回はversion 2を利用したいと思います。
以下の記事を参考に、接続を作成します。
CloudFromationテンプレート
codepipeline.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: My CodePipeline
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Github Information"
Parameters:
- FullRepositoryId
- ReleaseBranchName
- ConnectionArn
- Label:
default: "Deploy Parameters"
Parameters:
- Env
- ApplicationName
Parameters:
FullRepositoryId:
Description: "Github full repository id (ex. OwnerName/RepositoryName)"
Type: String
ReleaseBranchName:
Description: "Github release branch name"
Type: String
Default: main
ConnectionArn:
# 作成したCodeStar ConnectionsのARN
Description: "CodeStar connection arn (ex. arn:aws:codestar-connections:ap-northeast-1:xxxxx)"
Type: String
Env:
Description: "Choose the environment to create: 'dev' or 'prod'"
Type: String
Default: dev
AllowedValues:
- dev
- prod
ApplicationName:
Description: "Application Name"
Type: String
Default: my-application
Resources:
#-----------------------------------------------------------------------------
# S3
#-----------------------------------------------------------------------------
S3:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
BucketName: !Sub ${ApplicationName}-artifact-store-${Env}
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced
PublicAccessBlockConfiguration:
BlockPublicAcls: True
BlockPublicPolicy: True
IgnorePublicAcls: True
RestrictPublicBuckets: True
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-artifact-store-${Env}
#-----------------------------------------------------------------------------
# Role
#-----------------------------------------------------------------------------
CodeDeployIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- codedeploy.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
RoleName: !Sub ${ApplicationName}-codedeploy-iam-role-${Env}
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-codedeploy-iam-role-${Env}
CodePipelineIAMPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "codestar-connections:CreateConnection"
- "codestar-connections:DeleteConnection"
- "codestar-connections:UseConnection"
- "codestar-connections:GetConnection"
- "codestar-connections:ListConnections"
- "codestar-connections:TagResource"
- "codestar-connections:ListTagsForResource"
- "codestar-connections:UntagResource"
- "codedeploy:CreateDeployment"
- "codedeploy:GetApplication"
- "codedeploy:GetApplicationRevision"
- "codedeploy:GetDeployment"
- "codedeploy:GetDeploymentConfig"
- "codedeploy:RegisterApplicationRevision"
Resource:
- "*"
- Effect: Allow
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:ListBucket"
Resource:
- !Join
- ''
- - !GetAtt S3.Arn
- '/*'
- !GetAtt S3.Arn
ManagedPolicyName: !Sub ${ApplicationName}-codepipeline-iam-policy-${Env}
CodePipelineIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- !Ref CodePipelineIAMPolicy
RoleName: !Sub ${ApplicationName}-codepipeline-iam-role-${Env}
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-codepipeline-iam-role-${Env}
#-----------------------------------------------------------------------------
# CodeDeploy
#-----------------------------------------------------------------------------
CodeDeployApplication:
Type: AWS::CodeDeploy::Application
Properties:
ApplicationName: !Sub ${ApplicationName}-deploy-${Env}
ComputePlatform: Server
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-deploy-${Env}
CodeDeployGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
ApplicationName: !Ref CodeDeployApplication
AutoRollbackConfiguration:
Enabled: true
Events:
- DEPLOYMENT_FAILURE
DeploymentConfigName: CodeDeployDefault.AllAtOnce
DeploymentGroupName: !Sub ${ApplicationName}-deploy-group-${Env}
# Set tag filters
Ec2TagFilters:
- Key: "deploy"
Type: KEY_AND_VALUE
Value: "01"
ServiceRoleArn: !GetAtt CodeDeployIAMRole.Arn
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-deploy-group-${Env}
#-----------------------------------------------------------------------------
# CodePipeline
#-----------------------------------------------------------------------------
CodePipeline:
Type: 'AWS::CodePipeline::Pipeline'
Properties:
Name: !Sub ${ApplicationName}-pipeline-${Env}
ArtifactStore:
Type: S3
Location: !Ref S3
RoleArn: !GetAtt CodePipelineIAMRole.Arn
# パイプライン更新時に自動実行をしないようにする
RestartExecutionOnUpdate: false
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: CodeStarSourceConnection
Configuration:
FullRepositoryId: !Ref FullRepositoryId
ConnectionArn: !Ref ConnectionArn
BranchName: !Ref ReleaseBranchName
# ソースコード変更時にパイプラインを自動的に開始する
DetectChanges: "true"
OutputArtifacts:
- Name: SourceOutput
RunOrder: 1
- Name: Deploy
Actions:
- Name: DeployAction
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CodeDeploy
Configuration:
ApplicationName: !Ref CodeDeployApplication
DeploymentGroupName: !Ref CodeDeployGroup
InputArtifacts:
- Name: SourceOutput
RunOrder: 2
Outputs:
CodeDeployApplicationName:
Value: !Ref CodeDeployApplication
Export:
Name: !Sub ${ApplicationName}-codedeploy-application-name-${Env}
CodeDeployGroupName:
Value: !Ref CodeDeployGroup
Export:
Name: !Sub ${ApplicationName}-codedeploy-group-${Env}
CodePipelineName:
Value: !Ref CodePipeline
Export:
Name: !Sub ${ApplicationName}-codepipeline-name-${Env}
パラメータについて
パラメータとして、以下を設定しています。
パラメータ名 | 設定値 |
---|---|
FullRepositoryId | GithubのレポジトリIDを設定する |
ReleaseBranchName | リリース対象のブランチ名を設定する |
ConnectionArn | 作成したCodeStar ConnectionsのARNを設定する |
Env | 環境名を設定する(dev or prod) |
ApplicationName | 任意のアプリケーション名を設定する |
デプロイ対象のタグの設定
以下の部分で、デプロイ対象のEC2に設定しているタグを設定しています。
Ec2TagFilters:
- Key: "deploy"
Type: KEY_AND_VALUE
Value: "01"
この例では、"deploy"というタグ名に、値として"01"を設定しているEC2を対象としています。
最後に
今回は、CodePipeline (Github version 2接続) とCodeDeployを利用したパイプラインをCloudFromationで作成してみました。
参考になりましたら幸いです。