この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
おはようございます、もきゅりんです。
CFnを使用してGitHub CodePipelineを作成してみたので、まとめておきます。
テンプレートの再利用等で役立てば幸いです。
先日、CodeCommitで構築したFargate+RDS(MySQL5.7)+FlaskをCFnで構築してみるを使った、GitHubでのケースになります。
実際に確認したい場合は、先にこの環境を構築する必要があります。
なお、やってから気付きましたが、こんなのも2年以上前にありました。
そして、上記内容を弊社ブログ記事が丁寧に補足説明しています。
前提条件
- Fargate+RDS(MySQL5.7)+FlaskをCFnで構築してみるが構築済みであること
注意として、今回はCodeCommitではなく、利用するGitHubに今回使うファイルをPushしておくことが変更点となります。
やること
- GitHubの個人用のアクセストークンを取得する
- CFnテンプレートの作成とスタック作成
GitHubの個人用のアクセストークンを取得する
個人用のアクセストークンを使用するようにパイプラインを設定する (GitHub と CLI)に記載されているように、以下の手順でGitHub 個人用アクセストークンを作成します。
- GitHub で、プロフィール写真のドロップダウンオプションから、[Settings] を選択します。
- [Developer settings] を選択してから [Personal access tokens] を選択します。
- [Generate new token] を選択します。
- [Select scopes] で、[admin:repo_hook] および [repo] を選択します。
こんな感じですね。
[Generate token]をクリックすると、トークンが生成されてるので保持しておきます。
ドキュメントにも記載されていますが、下記注意です。
この時点で、生成されたトークンを確実にコピーしてください。このページを閉じた後でトークンを表示することはできません
※ 注 以下ではトークンをそのままテンプレート内でパラメータとして扱っています。後日トークンをSecretsManagerで秘匿するやり方をまとめていますので、必要あればご参照下さい。
[小ネタ] SecretsManagerを使ってCFnのGitHubTokenをシークレットにする
CFnテンプレートの作成とスタック作成
あとは適当なローカルでテンプレートを作成して実行するだけです。
# create-stackコマンドで作成
aws cloudformation create-stack --stack-name github-fargate-pipeline \
--template-body file://`pwd`/sample-pipeline.yml \
--parameters file://`pwd`/paramas.json \
--capabilities CAPABILITY_NAMED_IAM
# deployコマンドで作成
aws cloudformation deploy --template-file sample-pipeline.yml \
--stack-name github-fargate-pipeline \
--parameter-overrides $(jq -r '.[] | [.ParameterKey, .ParameterValue] | join("=")' paramas.json) \
--capabilities CAPABILITY_NAMED_IAM
テンプレートは下記です。
# sample-pipeline.yml
AWSTemplateFormatVersion: 2010-09-09
Description: CodePipeline For ECS Fargate with GitHub
Parameters:
Cluster:
Type: String
Service:
Type: String
ContainerName:
Type: String
ECRName:
Type: String
GitHubRepositoryName:
Type: String
GitHubAccountName:
Type: String
GitHubSecret:
Type: String
GitHubOAuthToken:
Type: String
Branch:
Type: String
PipelineName:
Type: String
Resources:
# CodeBuildに適用するIAMRole
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: SampleCodeBuildAccess
PolicyDocument:
Version: "2012-10-17"
Statement:
- Resource: "*"
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- Resource: !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:GetObjectVersion
- s3:GetBucketAcl
- s3:GetBucketLocation
- Resource: "*"
Effect: Allow
Action:
- ecr:GetAuthorizationToken
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:GetRepositoryPolicy
- ecr:DescribeRepositories
- ecr:ListImages
- ecr:DescribeImages
- ecr:BatchGetImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
- ecr:PutImage
# CodePipelineに適用するIAMRole
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: SamplePipeline
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- Resource: "*"
Effect: Allow
Action:
- codecommit:GetRepository
- codecommit:ListBranches
- codecommit:GetUploadArchiveStatus
- codecommit:UploadArchive
- codecommit:CancelUploadArchive
- codedeploy:CreateDeployment
- codedeploy:GetApplication
- codedeploy:GetApplicationRevision
- codedeploy:GetDeployment
- codedeploy:GetDeploymentConfig
- codedeploy:RegisterApplicationRevision
- codebuild:StartBuild
- codebuild:StopBuild
- codebuild:BatchGet*
- codebuild:Get*
- codebuild:List*
- codecommit:GetBranch
- codecommit:GetCommit
- s3:*
- ecs:*
- elasticloadbalancing:*
- autoscaling:*
- iam:PassRole
# S3Bucket
ArtifactBucket:
Type: AWS::S3::Bucket
# 外部イベント発生のwebhook
PipelineWebhook:
Type: "AWS::CodePipeline::Webhook"
Properties:
Authentication: GITHUB_HMAC
AuthenticationConfiguration:
SecretToken: !Ref GitHubSecret
Filters:
- JsonPath: "$.ref"
MatchEquals: 'refs/heads/{Branch}'
TargetPipeline: !Ref Pipeline
TargetAction: SourceAction
Name: GitHubPipelineWebhook
TargetPipelineVersion: !GetAtt Pipeline.Version
RegisterWithThirdParty: "true"
# CodeBuild
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email)
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- echo "[{\"name\":\"${ContainerName}\",\"imageUri\":\"${REPOSITORY_URI}:${IMAGE_TAG}\"}]" > imagedefinitions.json
artifacts:
files: imagedefinitions.json
Environment:
PrivilegedMode: true
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/docker:18.09.0-1.7.0
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/${ECRName}
- Name: ContainerName
Value: !Ref ContainerName
Name: !Ref AWS::StackName
ServiceRole: !Ref CodeBuildServiceRole
# CodePipeLine
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
Name: !Ref PipelineName
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: 1
Provider: GitHub
Configuration:
Owner: !Ref GitHubAccountName
Repo: !Ref GitHubRepositoryName
PollForSourceChanges: false
Branch: !Ref Branch
OAuthToken: !Ref GitHubOAuthToken
RunOrder: 1
OutputArtifacts:
- Name: App
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref CodeBuildProject
RunOrder: 1
InputArtifacts:
- Name: App
OutputArtifacts:
- Name: BuildOutput
- Name: Deploy
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: ECS
Configuration:
ClusterName: !Ref Cluster
ServiceName: !Ref Service
FileName: imagedefinitions.json
RunOrder: 1
InputArtifacts:
- Name: BuildOutput
# paramas.json
[
{
"ParameterKey": "Cluster",
"ParameterValue": "demo-flask-cluster"
},
{
"ParameterKey": "Service",
"ParameterValue": "demo-flask-service"
},
{
"ParameterKey": "ContainerName",
"ParameterValue": "demo-flask-container"
},
{
"ParameterKey": "ECRName",
"ParameterValue": "ECRName"
},
{
"ParameterKey": "GitHubRepositoryName",
"ParameterValue": "RepositoryName"
},
{
"ParameterKey": "GitHubAccountName",
"ParameterValue": "GitHubAccountName"
},
{
"ParameterKey": "GitHubSecret",
"ParameterValue": "secret"
},
{
"ParameterKey": "GitHubOAuthToken",
"ParameterValue": "xxxxxxxxxxxxxxxxxxxxxxxxx"
},
{
"ParameterKey": "Branch",
"ParameterValue": "master"
},
{
"ParameterKey": "PipelineName",
"ParameterValue": "cfn-github-pipeline"
}
]
ファイルを適当に変更してGitHubリポジトリにプッシュしてみます。
$ git add .
$ git commit -m "index changed"
$ git push
しばらくすると、変更が反映されました。
以上です、どなたかのお役に立てば幸いです。