飽き性の頭の中

CodePipeline + ECRを使ってDockerイメージをElastic Beanstalkに自動デプロイできるようにした話【CI/CD】

CodePipeline + ECRを使ってDockerイメージをElastic Beanstalkに自動デプロイできるようにした話【CI/CD】

tawachan
tawachan

こんにちは、たわです。AWS で Elastic Beastalk でワークフローを整理したのでそのときのメモです。

ゴールとしては、

  • GitHub で変更をプッシュしたら
  • 自動で Docker イメージがビルドされ
  • Amazon ECR 上にプッシュされて
  • それが Elastic Beastalk 上にデプロイされる

ワークフローを作ることです。

Elastic Beastalk の環境構築

Elastic Beastalk を立ち上げます。

アプリケーションの作成

まずはコンソールからアプリケーションの作成をします。

assets/20200116224045.jpg

assets/20200116224119.jpg

そうすると、空のアプリケーションができあがります。

assets/20200116224138.jpg

環境の作成

次はアプリケーションの中に環境を作成していきます。

  • development
  • staging
  • production

といったように環境ごとに作り分けるという思想なんだと思います。

  • backend
  • frontend

というように分けてもいいのかもしれません。管理しやすいようにすればよいと思います。

ウェブサーバー環境を選択

  • ウェブサーバー環境
  • ワーカー環境

がありますが、今回はウェブサーバー環境を選択します。

assets/20200116224446.jpg

プラットフォームは Docker を選択

インスタンスの中で何を稼働させるかを選択できます。

  • Node.js
  • Go
  • Python

といったランタイムを選ぶこともできますが、今回は Docker を選択します。

assets/20200116224517.jpg

アプリケーションコードはサンプルのまま

アプリケーションコードはサンプルがデフォルトだと思いますがそのままにします。

あとでデプロイフローは整えそのときに自分のコードが展開されるようにするのでとりあえずこれでよいです。

assets/20200116224710.jpg

その他オプション設定はここで

  • インスタンスの数
  • セキュリティグループ
  • VPC
  • ロードバランサー

などなど設定する場合は「より多くのオプションの設定」を押して詳細設定画面に遷移しましょう。

assets/20200116224906.jpg

数分待てば起動完了

数分待てば Elastic Beanstalk に関連する、EC2 やその他必要なものが立ち上がり準備完了となるはずです。

CodeBuild の設定

次に GitHub から自動で Docker イメージをビルドして ECR にプッシュする流れを設定する必要があります。

CodePipeline でデプロイまでのフローを設定する前に必要です。

ここの詳細に関しては別記事で紹介しているのでそちらを参照してください。今回は当記事との差分だけ紹介します。

buildspec.ymlを修正

CodePipeline では後続のタスクに情報を引き継ぐことができます。

なので、CodeBuild の設定ファイル(buildspec.yml)を修正して、ビルド後にデプロイに必要な情報を引き継げるようにします。

元々のbuildspec.yml

上記記事でも紹介している設定ファイルはこんな感じです。

   version: 0.2

phases:
  install:
    runtime-versions:
      docker: 18
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
      - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}
      - 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...
      - echo $IMAGE_REPO_NAME:$IMAGE_TAG
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG -f $DOCKERFILE .
      - echo docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image to $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG ...
      - DOCKER_URL=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - docker push $DOCKER_URL

Elastic Beastalk ではDockerrun.aws.jsonが必要

Elastic Beanstalk の設定ファイルはDockerrun.aws.jsonとなります。

上記公式サイトを参考にすると次のような設定ファイルです。

   {
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "username/beanstalk-flask",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "5000"
    }
  ]
}

なのでこれに準じたファイルを作成し引き継ぎます。

実際の修正箇所

先ほどのbuildspec.ymlを修正してこうなります。

   version: 0.2

phases:
  install:
    runtime-versions:
      docker: 18
  pre_build:
    commands:
      ## ... 省略
  build:
    commands:
      ## ... 省略
  post_build:
    commands:
      ## ... 省略
      ## ↓ 追加
      - printf '{"AWSEBDockerrunVersion":"1","Image":{"Name":"%s","Update":"true"},"Ports":[{"ContainerPort":"%s"}]}' $DOCKER_URL $PORT > Dockerrun.aws.json
## ↓ 追加
artifacts:
  files:
    - Dockerrun.aws.json

※ポート番号は CodeBuild の環境設定から適宜渡すようにしてください。

CodePipeline の設定

CodeBuild の設定ができたら CodePipieline を設定します。

パイプラインの作成

まずはパイプラインの作成をします。

assets/20200116231724.jpg

assets/20200116231745.jpg

ソースステージを追加する

データソースを設定します。ここでは GitHub を設定します。

assets/20200116231846.jpg

自動デプロイのトリガーにするブランチを決めて作っておくとよいでしょう。

ビルドステージを追加する

次にデータソースをもとにどのようにビルドするのかの設定です。

ここでは先ほど CodeBuild で作成したプロジェクトを指定するだけとなります。

assets/20200116232039.jpg

デプロイステージを追加する

最後にデプロイステージの追加です。最初に作成した Elastic Beastalk を指定しましょう。

assets/20200116232128.jpg

assets/20200116232150.jpg

確認して良さそうであればパイプラインの作成は完了です。

assets/20200116232229.jpg

Elastic Beanstalk に ECR アクセスの権限を付与

デフォルトだと Elastic Beastalk が各 EC2 に設定するロールでは ECR にアクセスできないはずです。

Elastic Beanstalk が Docker のプライベートレジストリにアクセスする場合、認証が必要なので、先ほどのDockerrun.aws.jsonAuthenticationを追加する必要があると書いてあるものがありますが、AWS ECR の場合はその限りではありません。同じ AWS のサービスなので適切なロールを与えて上げれば大丈夫です。

IAM インスタンスプロフィールを確認

まず、Elastic Beanstalk についている IAM プロフィールを確認しましょう。

assets/20200116233427.jpg

ECR への Read 権限を付与

あとは確認したプロフィールを IAM のコンソール画面から編集します。

ロールを選択して、AmazonEC2ContainerRegistryReadOnlyポリシーをアタッチすれば大丈夫なはずです。

assets/20200116233618.jpg

まとめ

上記をやってうまく行っていればパイプラインがグリーンマークで表示されるでしょう。

assets/20200116232250.jpg

先ほどこの設定をしたので備忘録的に書きました。基礎的なことですが数日後には忘れているので困らないように。

関連記事