AWS CodePipelineを使ってAWS CodeBuildでビルドしFargateにデプロイしてみる


前置き

書き始めた日付と公開日がかなりずれたため、画像が現状のAWSのものとは異なる場合がございます。ご了承くださいmm

概要

下記で作成したものを使って、AWS CodePipelineでFargateにデプロイしてみます。

AWS CodePipelineの設定

基本的には「早速始めてみる」のフローで作成するだけでも設定可能です

 パイプラインの設定

適当にパイプライン名を設定し、ロールを選択。なければ新規に作成。

ソースの場所

ソースプロバイダはGitHubを選択。
GitHubと連携すると、リポジトリとブランチを選択できるので、該当のリポジトリとブランチを選択。

ビルド

AWS CodeBuild+Amazon ECRを試してみるで作成したものを選択。

デプロイ

デプロイプロパイダーは Amazon ECS を選択し、Fargateで自作したコンテナイメージを動かしてみるで作成したものを設定。

Image filename は空白でも大丈夫のようです。その場合、imagedefinitions.jsonが利用されるとのこと。

作成されたパイプライン

確認画面を経て、作成されたパイプラインは下記。

try&error

上記で作成されて、自動的にパイプラインが実行されるが、なかなかうまくいかず><

実行権限でエラー

しばらくすると自動的に実行されるが、、、なぜか失敗><
CodeBuildで失敗しているので確認したところ、

[91m/bin/sh: /work/gradlew: Permission denied
[0mThe command '/bin/sh -c /work/gradlew build' returned a non-zero code: 126

CodeBuild上で実行、もしくはGitHubをHookして実行された時はこのようなエラーが出なかったが、
今回はCodeBuildのイニシエーターが KotlinWebFlux の場合だけ失敗。

ただし、下記のように実行権限を明示的につけてあげれば無事成功。

phases:
  pre_build:
    commands:
    - echo If needing exist before testing, here writing.
    - chmod +x gradlew

参考: コミットが GitHub リポジトリにプッシュされたときに Android アプリをビルドしてテストするパイプラインを作成

ビルド後のOutput/Inputが合わなくてエラー

実行権限をつけて、無事にテストが通ったと思いきや、今度はビルド部分でエラー、、、エラーログは下記。

[Container] 2018/10/07 15:21:09 Waiting for agent ping
[Container] 2018/10/07 15:21:09 Waiting for DOWNLOAD_SOURCE

ふむふむ、ビルドしたいがDOWNLOAD_SOURCEがなくて怒られる。
CodeBuildをそれぞれ繋ぐだけではダメで、それぞれのOutputを指定してあげないとダメな模様。
今回はGithubから落としてきたソースを全て使うので、下記のようなartifactsを追加。

buildspec-test.yml
・・・・・
artifacts:
  files:
    - '**/*'

このようにしたら、テスト後のビルドもうまく通るようになった。

ECSでリソースな見つからないと怒られる

こちらも上記のように artifacts を指定する必要がある。
その指定は、CodePipeline で ECS にデプロイできるようになり、Docker 環境の継続的デリバリも簡単になりました を参考にする限り、タスク定義書を指定すればOKの模様。
上記を参考に下記を追加。

buildspec.yml
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - echo Writing image definitions file...
      - echo "[{\"name\":\"kotlinwebflux\",\"imageUri\":\"${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}:${IMAGE_TAG}\"}]" > imagedefinitions.json
artifacts:
  files: imagedefinitions.json

・・・・これでも失敗。。。ECSにデプロイできないと怒られる><

イメージ定義ファイル

buildspec.json で吐き出すjsonファイルのフォーマット、吐き出しファイル名が一致しないとダメ><

[
  {
    "name":"<<タスク定義内のnameと同じにしましょ>>",
    "imageUri":"<<ECRのURI>>"
  }
]

これで再度実行し、最終的には下記のような画になれば成功。

→ 最後のコンテナの入れ替えには多少の時間を要するかもしれません。

感想

  • ポチポチやるだけでbuildからdeployまでのパイプライを作成できるのは楽チン。
  • ECSへのデプロイ部分がblackbox化しているのが若干怖い? ( どのような設定でデプロイがされているのかなど? ) 気もしましたが、ECSさえ準備できていればCI/CDのパイプラインは簡単に作成できるのは良い。
  • ポチポチやると再現性が無くなりそうなので、この辺はTerraformとかで管理できると良さそう ( 複数のコンポーネントがあっても結局は同じことをやりそうなので )
  • あとは、、、AWSのドキュメントをちゃんと読めばはまらないので、ちゃんと読むべしですね>< ( 当たり前のことですが、サボるとハマることを学びました )

終わりに

この何回かで試したことを実践するチャンスがありました!その辺で考えたことなどは、また書いていければと思います。読んでいただきましてありがとうございましたmm

参考