課題
- AWS上にDocker環境管理からデプロイまで行うこと。
解決方法
- AWS CodePipelineで自動ビルドとECSにrolling updateデプロイする。
構成

事前準備
- VPC作成
- Dockerfile(可能であれば、buildして問題ないもの)
構築順番
※今回はAWSマネージメントコンソールで作成します。
- ECR作成
- ECS作成
- CodePipeLine作成
ECR作成
Repostory name入力
View push commands確認
Repostory作成できたら、詳細に移動して「View push commands」をクリックすると、
下記のimgのように、ECRにpushする方法が表示されます。
補足
・ECRに上げる方法は上記のcommandsとCodeBuildがあります。
CodeBuildによるpushの方法は下記の'CodeBuild作成'のところを参考してください。
・今後ECS Service作成のために、ECRにあげておきましょう。
ECRにpush後一覧表示
補足
・imageURLに'************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest'の確認ができ、
このimageURLがECS Serviceのcontainer作成する時必要になります。
ECS作成
ECS作成手順
- TableDefinition作成
- ELB作成
- Cluster作成
- Service作成
TableDefinition作成
EC2 type選択
EC2 詳細設定
補足
・TaskRoleはCodeDeployする際、ECS実行のために必要です。
「ecsTaskExcutionRole」がなかったら、下記の手順で作成してください。
・ecsTaskExcutionRole作成方法
・IAM > Roles > Create Role
・Elastic Container Service選択 > Elastic Container Service Task選択 > Next:Permissions
・AmazonECSTaskExcutionRolePolicy検索後チェック > Next: Tags
・Add tagsスルーしてNext:Reviewに移動
・Role nameをecsTaskExcutionRoleにしてCreate role
Container Definitions設定
補足
・Container nameはCodeBuildの時使うので、覚えておいてください。
・Imageは先ほどECRのImageURLを入力してください。'************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest'
・Memory LimitsはContainerに重いAppが動くのであれば、Soft limitで設定してください。
・Port mappingsはContainer port設定だけでOKです。
ECSのDeployは基本ALBを使います。
Host portを設定してしまうと、Containerがすでに使っているportだとエラーが発生します。
- TableDefinition作成できたら、詳細画面で「Task Definition Name:Revision」の確認ができます。
ELB作成
- EC2コンソール > Load Balancers選択
- Create Load Balancer選択
- Application Load Balancer選択 > Create
- Configure Load Balancerページ
- NameにLoad Balancer名入力
- Schemaにinternet-facing設定
- Ip address typeでipv4選択
- Load Balancer ProtocolでHTTP選択してPortを80にする
- 前もって作ったVPCを選択後、2つのSubnetを選択
- Next: Configure Security Settings
- Configure Security Groupsページ
- なかったらnewを、あったらexistingを選択
- Next: Configure Routing
- Configure Routingページ
- Target groupでNew target group選択
- NameにTarget名入力
- Target typeでIPを選択
- ProtocolでHTTP選択
- portに80
- Next: Register Targets
- Reviewページ
- Create選択
補足
・Health check PathがAppに合わせて設定してください。
・ALB設定したので、ECSのSecurity GroupsにALBのSecurity GroupsをAll TCPで適用してください。
・rolling updateの場合Load Balancer Protocol1つで
Blue/Green Deployの場合Load Balancer Protocol2つになります。
Cluster作成
template選択(EC2Linux + Networking)
cluster設定1
補足
・EC2 instance typeは t2.medium以上をオススメします。
CodeDeployする時一時的にContainerが2つ立ち上がってmemoryが足りない現象が起きてしまうからです。
cluster設定2
Networkingは作っておいたVPCと2つのSubnetの設定でOKです。
EC2のSecurityGroupも選択してください。
ALB作成するところにも書きましたが、必ずALBのSGと紐づけてください。
cluster設定3
補足
・「ecsInstanceRole」がなかったら下記の手順で作成してください。
・ecsInstanceRole作成方法
・IAM > Roles > Create Role
・EC2選択 > Next:Permissions
・AmazonEC2ContainerServiceForEC2Role検索後チェック > Next: Tags
・Add tagsスルーしてNext:Reviewに移動
・Role nameをecsInstanceRoleにしてCreate role
Service作成
Service設定
先ほど作ったClusterの詳細にService Createをクリックして移動しましょう。
補足
・作成したTable Definition名とRevisionを選択してください。
・作成したClusterを選択してください。
・Service nameは好きなもので入力してください。
Deployment設定
今回はRolling update選択して、「Next step」をクリックしてください。
Network設定
補足
・Deployのなめに、ALBを選択してください。
・「ecsServiceRole」がなかったら下記の手順で作成してください。(おそらくすでにあると思います)
・ecsServiceRole作成方法
・IAM > Roles > Create Role
・Elastic Container Service選択 > ユースケースの選択でElastic Container Service選択 > Next:Permissions
・AmazonEC2ContainerServiceRole検索後チェック > Next: Tags
・Add tagsスルーしてNext:Reviewに移動
・Role nameをecsServiceRoleにしてCreate role
・作成したLoad balancer nameを選択してください。
ALB target設定
補足
・Target group nameで作成してALB targetを選択すると、そのtargetによる情報で設定されます。
設定がおわったら、そのまま次のページに移動してください。
Auto Scaling設定
今回使わないので、
「Do not adjust the service’s desired count」を選択してそのまま作成まで進んでください。
CodePipeline作成
CodePipeline作成手順
- CodeBuild作成
- CodePipeline作成
CodeBuild作成
Project configuration
Project名だけでOKです。
Source
CodeBuildするSource先を選んでください。
補足
・Source providerにAWS CodeCommitなど色々ありますが、今回はGitHubを使いました。
Primary source webhook events
GitHubで何かのアクションを行ったらBuildを動かすものですが、
今回はCodePipelineで設定するので、別にやる必要はないです。
一応下記のイメージでやっていることだけ説明すると、
testというブランチにgit pushするたびにBuildが走ることになります。
Environment
Docker imageを使用するには、Environment imageのManaged imageを選択して、
Operating system, Runtime, Image, Image versionを適切に選択してください。
補足
・Docker image buildするために、Privilegedを必ず選択してください。
Buildspec
CodeBuildするために、builspec.ymlファイルが必要なので、「Use a builspec file」を選択してください。
builspec.yml作成
必要なfile
・builspec.yml(codeBuildするためのymlファイル)
・imagedefinitions.json(codeDeployの時、この情報でServiceのTableDefinitionの新しいリビジョンを作成し、新しいタスク定義を使用してサービスを更新するファイル)
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region us-east-1)
build:
commands:
- echo Building the Docker image...
- docker image build --file Dockerfile . -t イメージ名:latest
- docker tag イメージ名:latest ************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest
post_build:
commands:
- echo Pushing the Docker image...
- docker push ************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest
- echo Writing image definitions file...
- printf '[{"name":"{container name}","imageUri":"%s"}]' ************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
補足
・container nameは「Container Definitions設定」のcontainer nameを入力してください。
・imagedefinitions.jsonはファイル作成だけでOKです。
CodePipeline作成
Pipeline setting
Pipeline名を作成して次に進んでください。
source stage
Source ProviderをGitHubを選択して、Repository > Branchを選択すると、
そのBranchにpushするたびに、このCodePipelineが動き始めます。
build stage
作成したCodeBuildを選択してください。
deploy stage
Deploy providerをAmazon ECSを選択して、
作成したCluster nameとService nameを選択してください。
補足
・image definitions fileはCodeBuildする時作成されるので、書かなくても大丈夫です。
deploy success画面
まとめ
個人的に初めてAWSを深く触れる機会になって、非常に面白かったです。
実はDockerすら詳しくなかったので、ハードルが高いと感じられたし、触るたびにエラーばかりでした。
しかし、Docker buildからECRにpushしたり、ECSだけ動かしてみたりしながら、少しずつ理解した結果、
ついにgit pushだけでDocker deployができる仕組みを作りました。
今回構築において最も困っていたところはエラーlogの確認が難しいことでした。
色々試してみたら、下記の方法がなんとかアプローチできたのではないかと思います。
・Cluster > Service > Tasks or Events or Deployments確認
・ALB target health確認
・直接にServerに入ってlog確認
ちなみに、今後Qiitaに追加したい内容はECS(Blue/Green Deploy)と本記事内容のCloudFormation作成です!
最後に政谷さん色々ありがとうございましたー
参考
チュートリアル: Amazon ECR ソースと、ECS と CodeDeploy 間のデプロイでパイプラインを作成する
CodePipelineからECSにBlue/Greenデプロイする
Amazon ECS入門 〜公式のDockerイメージを使って10分で構築してみる〜