飽き性の頭の中
CodePipeline + ECRを使ってDockerイメージをElastic Beanstalkに自動デプロイできるようにした話【CI/CD】のサムネイル

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

2020-01-17
# 技術メモ

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

ゴールとしては、

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

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

Elastic Beastalk の環境構築

Elastic Beastalk を立ち上げます。

アプリケーションの作成

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

20200116224045.jpg

20200116224119.jpg

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

20200116224138.jpg

環境の作成

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

  • development
  • staging
  • production

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

  • backend
  • frontend

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

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

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

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

20200116224446.jpg

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

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

  • Node.js
  • Go
  • Python

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

20200116224517.jpg

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

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

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

20200116224710.jpg

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

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

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

20200116224906.jpg

数分待てば起動完了

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

CodeBuild の設定

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

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

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

blog.tawa.me

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となります。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/single-container-docker.html#single-container-docker.test-remote

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

{
  "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 を設定します。

パイプラインの作成

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

20200116231724.jpg

20200116231745.jpg

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

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

20200116231846.jpg

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

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

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

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

20200116232039.jpg

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

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

20200116232128.jpg

20200116232150.jpg

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

20200116232229.jpg

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

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

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

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

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

20200116233427.jpg

ECR への Read 権限を付与

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

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

20200116233618.jpg

まとめ

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

20200116232250.jpg

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



©2022 tawachan All Rights Reserved.