Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last 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分で構築してみる〜

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away