1. はじめに
- devops関連の復習をしている。前の記事「【初心者】CodeCommit, CodeDeploy, CodePipeline を使ってみる」で、初めてcode系サービスのハンズオンを行ったが、もう少し詳しいものをやってみたいと思い、CodeBuildなどが内容に含まれている別のものを実施する。
2. やったこと
- AWS Japanから公開されている「AWS CI/CD for Amazon ECS ハンズオン」を実施する。
- 2020/4に作成されており少し古いため、そのまま実行できない箇所もある様子だが、まあ大丈夫かなと思いチャレンジする。
- ハンズオンに含まれる内容は以下の通り。
- ハンズオン1: ECS環境の構築
- 今回のハンズオンの動作環境となるVPCやALBの構築、サンプルコンテナアプリを作成しECRに登録
- ハンズオン2: AWS Fargate環境の構築
- Fargate環境をデプロイしサンプルコンテナアプリを稼働させ、外部からWEBアクセスできることを確認
- ハンズオン3: AWS Code Services を利用したCI/CDパイプラインの構築
- 上記のサンプルコンテナアプリの更新をCode系サービスを用いてCI/CD化
- ハンズオン1: ECS環境の構築
3. 構成図
4. 手順
- ハンズオン手順書はマネージメントコンソールの画面付きとなっており、基本的にそのまま実施可能。つまづいた点などを補足的に記載する。
ハンズオン1: ECS環境の構築
VPC作成
- VPC、 Subnet(Public/Private 2個ずつ)、NAT Gateway などをCloudFormationで作成する。指示通りN.Virginiaリージョンで作成する。(別リージョンでも可能だが、後の手順でN.Virginia前提の部分(設定ファイル内にus-east-1の記載など)があり、別リージョンで作業する場合は都度修正必要)
ALB作成
- 作成するコンテナへのhttpアクセスを中継するためのALBを手動作成する。作成時に必要となるリスナーやターゲットグループをダミーで作成し、すぐ削除する。
Dockerアプリ開発
- ECRリポジトリを作成する。
- 可視性設定として「プライベート」を選択する。(もともとは選択肢がなかったが、本ハンズオン資料より後の2020/12に、「パブリック」リポジトリの機能がリリースされている)
- 作業用(gitなどの実行用)として、Cloud9環境を作成する。
- Platform として、「Amazon Linux 2(recommended)」を選択する。(ハンズオン資料では選択画面なし)
- PHPサンプルアプリ(httpアクセスするとコンテナが稼働するホスト名を返すアプリ)を作成し、ECRのリポジトリに登録する。
ハンズオン2: AWS Fargate環境の構築
- CodeDeploy用のIAMロールを作成する。
- Fargateクラスターを作成する。
- Fargateタスク定義を作成し、ハンズオン1の手順で作成したコンテナを指定する。
- オペレーティングシステムファミリーとして、「Linux」を選択する。(ハンズオン資料では選択画面なし)
- Fargateサービスを作成する。
- ALBにインターネットからアクセスし、PHPサンプルアプリ(ホスト名表示)の結果が表示されることを確認する。
ハンズオン3: AWS Code Services を利用したCI/CDパイプラインの構築
設定作業(手順書どおりに実施)
-
CodeCommitリポジトリにファイルを配備する(Cloud9環境でサンプルファイルを編集後、git push)。
-
CodePipelineで、パイプラインを作成する。
- 「出力アーティファクト形式」:「CodePipelineのデフォルト」を選択。
- build作成時、イメージを「aws/codebuild/standard:6.0」を選択。
-
CodePinelineでパイプラインの作成完了後、初回実行が行われるが、まだ全ての設定が済んでいないため失敗する。引き続き手順通りに以下設定を行う。
- CodeBuildの実行ロールに対してECRのリポジトリ操作の権限を追加する。
- CodePipelineの設定を編集し、Artifactの選択などを修正する。
設定作業(手順書にはない追加作業)
- 手順書通り設定後、パイプラインを実行すると、CodeBuildで失敗する。(以下、ビルドログ)
[Container] 2022/07/04 09:28:04 Command did not exit successfully $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email) exit status 252
[Container] 2022/07/04 09:28:04 Phase complete: PRE_BUILD State: FAILED
[Container] 2022/07/04 09:28:04 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email). Reason: exit status 252
- こちらの記事「aws ecr get-loginでエラー252」で、対処方法が詳しく記載されており、それを参考にbuildspec.ymlを修正する。原因としては、Codebuildの中では現在「ecr get-login」が使えなくなっており、対策として「ecr get-login-password」を使う必要があること。
buildspec.yml
# 修正前
- $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
# 修正後
- DOCKER_URI=https://XXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com
- aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_URI
- 再度、CodeBuildで失敗する。(以下、ビルドログ)
Step 1/2 : FROM php:7.4.0-apache
7.4.0-apache: Pulling from library/php
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
-
こちらの記事「AWS CI/CD for Amazon ECS ハンズオンをやってみた」に詳細説明あり。原因はDocker Hubに対する同一SRCIPからのダウンロード制限。対策としては、CodeBuildの実行環境をVPCに変更し、NAT Gateway経由でDocker Hubにアクセスさせる構成に変更する。手順はリンク先のサイトを参照。
-
上記2点を修正した上で、パイプラインを実行すると、無事CodeDeployまでの処理が成功し、Fargate上のコンテナの更新が行われる。また、CodeCommitに対してindex.phpなどのファイルを更新してアップロードすると、パイプラインが再実行され、コンテナが更新されることを確認できる。
5. エラーと原因
- ハンズオン実施中、自分の不注意(コピペミス、手順見落としなど)により各種エラーが発生した。備忘のため間違え箇所とエラーメッセージをまとめる。
エラー位置 | エラー内容 | 原因 |
---|---|---|
CodeDeploy | You are missing permissions to access input artifact: BuildArtifact. | buildspec.ymlのインデントミス。「artifacts:」の行に不要なインデントがあり「artifacts:」が「post_build:」 の下に入ってしまっていた。CodeBuildはエラーにならず完了するが、Artifactが出力されていなかった。エラーを見て「Artifactの参照権限がないの?」と思ったがそもそもファイル自体がなかった。 |
CodeDeploy | Exception while trying to read the task definition artifact file from: BuildArtifact. | マネコン上での操作ミス。手順上、Deploy実行時に使用するArtifactをBuildArtifactからSourceArtifactへ変更するところがあるが、マネコンで設定画面の「Done」を押した後、「Save」を押すのを忘れて設定が反映されていなかった。 |
CodeBuild | [Container] 2022/07/05 07:01:52 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker push $REPOSITORY_URI:latest. Reason: exit status 1 | buildspec.yml で、REPOSITORY_URIの指定時、ハンズオン資料だと us-east-1 になっている。最初、東京リージョンで手順を実行しており、ここを直すのを忘れてリポジトリアクセスに失敗した。 |
6. その他参考サイト
- このハンズオンをやった結果をメモしている記事がいくつかあり、内容把握の参考になった。
7. 所感
- 各サービスの利用の流れを把握するというゴールは達成した。自分でインフラ・アプリを構築する時に使いこなせるかというと、もう少し数をこなして理解を深めることが必要そう。