Edited at

CodePipelineでECSにデプロイする(Ver.rolling update)


課題


  • AWS上にDocker環境管理からデプロイまで行うこと。


解決方法


  • AWS CodePipelineで自動ビルドとECSにrolling updateデプロイする。


構成

スクリーンショット 2019-05-17 14.49.11.png


事前準備


  • VPC作成

  • Dockerfile(可能であれば、buildして問題ないもの)


構築順番

※今回はAWSマネージメントコンソールで作成します。


  1. ECR作成

  2. ECS作成

  3. CodePipeLine作成


ECR作成


Repostory name入力

ecr_create_qiita.png


View push commands確認

Repostory作成できたら、詳細に移動して「View push commands」をクリックすると、

下記のimgのように、ECRにpushする方法が表示されます。

ecr_view_command_qiita.png

補足


・ECRに上げる方法は上記のcommandsとCodeBuildがあります。
CodeBuildによるpushの方法は下記の'CodeBuild作成'のところを参考してください。
・今後ECS Service作成のために、ECRにあげておきましょう。


ECRにpush後一覧表示

ecr_after_push_qiita.png

補足

・imageURLに'************.dkr.ecr.us-east-1.amazonaws.com/イメージ名:latest'の確認ができ、

このimageURLがECS Serviceのcontainer作成する時必要になります。


ECS作成

ECS作成手順

1. TableDefinition作成

2. ELB作成

3. Cluster作成

4. Service作成


TableDefinition作成


EC2 type選択

ecs_tabledefinition_craete1_qiita.png


EC2 詳細設定

ecs_tabledefinition_craete2_qiita.png

補足

・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設定

スクリーンショット 2019-09-26 19 40 10

補足

・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作成


  1. EC2コンソール > Load Balancers選択

  2. Create Load Balancer選択

  3. Application Load Balancer選択 > Create

  4. Configure Load Balancerページ


    1. NameにLoad Balancer名入力

    2. Schemaにinternet-facing設定

    3. Ip address typeでipv4選択

    4. Load Balancer ProtocolでHTTP選択してPortを80にする

    5. 前もって作ったVPCを選択後、2つのSubnetを選択

    6. Next: Configure Security Settings



  5. Configure Security Groupsページ


    1. なかったらnewを、あったらexistingを選択

    2. Next: Configure Routing



  6. Configure Routingページ


    1. Target groupでNew target group選択

    2. NameにTarget名入力

    3. Target typeでIPを選択

    4. ProtocolでHTTP選択

    5. portに80

    6. Next: Register Targets



  7. Reviewページ


    1. 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)

ecs_cluster1_qiita.png


cluster設定1

ecs_cluster2_qiita.png

補足

・EC2 instance typeは t2.medium以上をオススメします。

 CodeDeployする時一時的にContainerが2つ立ち上がってmemoryが足りない現象が起きてしまうからです。


cluster設定2

Networkingは作っておいたVPCと2つのSubnetの設定でOKです。

EC2のSecurityGroupも選択してください。

ALB作成するところにも書きましたが、必ずALBのSGと紐づけてください。


cluster設定3

ecs_cluster3_qiita.png

補足

・「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をクリックして移動しましょう。

ecs_service1_qiita.png

補足

・作成したTable Definition名とRevisionを選択してください。

・作成したClusterを選択してください。
・Service nameは好きなもので入力してください。


Deployment設定

今回はRolling update選択して、「Next step」をクリックしてください。

ecs_service2_qitta.png


Network設定

ecs_network1_qiita.png

補足

・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設定

スクリーンショット 2019-05-17 16.36.56.png

補足

・Target group nameで作成してALB targetを選択すると、そのtargetによる情報で設定されます。

 設定がおわったら、そのまま次のページに移動してください。


Auto Scaling設定

今回使わないので、

「Do not adjust the service’s desired count」を選択してそのまま作成まで進んでください。


CodePipeline作成

CodePipeline作成手順

1. CodeBuild作成

2. CodePipeline作成


CodeBuild作成


Project configuration

Project名だけでOKです。

スクリーンショット 2019-05-17 16.47.00.png


Source

CodeBuildするSource先を選んでください。

スクリーンショット 2019-05-17 16.47.17.png

補足

・Source providerにAWS CodeCommitなど色々ありますが、今回はGitHubを使いました。


Primary source webhook events

GitHubで何かのアクションを行ったらBuildを動かすものですが、

今回はCodePipelineで設定するので、別にやる必要はないです。

一応下記のイメージでやっていることだけ説明すると、

testというブランチにgit pushするたびにBuildが走ることになります。

スクリーンショット 2019-09-25 10 41 51


Environment

Docker imageを使用するには、Environment imageのManaged imageを選択して、

Operating system, Runtime, Image, Image versionを適切に選択してください。

スクリーンショット 2019-05-17 16.54.58.png

補足

・Docker image buildするために、Privilegedを必ず選択してください。


Buildspec

CodeBuildするために、builspec.ymlファイルが必要なので、「Use a builspec file」を選択してください。

スクリーンショット 2019-05-17 16.58.26.png


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名を作成して次に進んでください。

スクリーンショット 2019-05-17 17.12.20.png


source stage

Source ProviderをGitHubを選択して、Repository > Branchを選択すると、

そのBranchにpushするたびに、このCodePipelineが動き始めます。

スクリーンショット 2019-05-17 17.12.42.png


build stage

作成したCodeBuildを選択してください。

スクリーンショット 2019-05-17 17.13.03.png


deploy stage

Deploy providerをAmazon ECSを選択して、

作成したCluster nameとService nameを選択してください。

スクリーンショット 2019-05-17 17.13.32.png

補足

・image definitions fileはCodeBuildする時作成されるので、書かなくても大丈夫です。


deploy success画面

スクリーンショット 2019-05-17 17.20.45.png


まとめ

個人的に初めて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分で構築してみる〜