CIを回すサービス
それほど設定は面倒ではなかった。CodePipelineのウィザードに従うと、必要なIAMの作成、CodeBuildのプロジェクトが一気通貫で作成される。
ただ、buildspec.ymlなど各種手順を構築するのが面倒ではある ( が、これは、会社やサービスのシステム構成によってデプロイ方法は異なるものなので、しょうがない。本質的な問題と言える。 この手のツールにありがちな「本質的な悩みに到達する前の作業に時間がかかる」といった悩みの時間は少ないと言える )
はまりポイント
- CodePipelineは「ECSのために作られている訳ではない」ので、 デプロイターゲットをECSとした場合でもIAM権限で、ECSへのアクセス権限が足りないケースがあった。 IAMロールは修正が必要 https://dev.classmethod.jp/tool/docker/20170225-codebuild-docker/ オフィシャルは日本語化されてて、だいたいこれが参照されている http://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker.html
git cloneできない。これsshの設定からやらねばならんか…
[Container] 2017/12/21 11:25:28 Running command git clone git@github.com:aoi-zemi/Docker_Dev.git
Cloning into 'Docker_Dev'...
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
参考
基本、これに添っていきたい CloudFormationで、ECSのCI/CD環境を構築した際のハマりどころ 〜CodePipeline,CodeBuild,KMSも添えて〜 - Qiita
CodePipeline, CodeBuildを使ってAmazon ECSへの継続的デプロイメントを試してみた | Developers.IO
ここが非常に参考になった、権限が足りない場合がある https://qiita.com/tiibun/items/f0045011c86efca254fc
高速化は –cache-from を使うようだ https://qiita.com/na-o-ys/items/7e7a7e4cde378fc54b32
手順
CloudFormationで構築した方が、作業早いし、再現性が高い、理想的といえる。 がGUIでやってみても、それほど時間がかかる訳ではないので残しておく
- CodePipelineページ開く
名前
- [ パイプラインの作成 ]->[ パイプライン名 ]
ソース
- [ ソースプロバイダ ]は s3, CodeCommit, Githubが選択できる。Githubを選択
- [ GitHubに接続 ]押すとGithubとの認証が走る模様->[ リポジトリ ]->[ ブランチ ]->[ 次のステップ ] ここでの疑問、パイプラインはブランチ単位で作成するものだろうか? できれば「新しいブランチができたら自動的に処理して欲しい」ぶっちゃけていうとRoute53で新しいブランチ名のついた検証用ドメインを作って欲しい。
ビルド
- ビルドプロバイダは AWS CodeBuild, Jenkins, Solano CIが選択可能、私はCodeBuildを選択
Codebuildを選択すると、追加で設定可能なメニューが現れる。 これはCodeBuild側のプロジェクト設定( わかりづらいが、PipelineからCodeBuildのプロジェクトが作れるようになってる。慣れると一気通貫で設定ができるので、この方が効率良さそう ) [ 新しいビルドプロジェクトを作成 ]を選択、プロジェクト名も入力。
[ 環境の設定 ]は『CodeBuildがビルド時に用いるDockerイメージ』を決める。 カスタムDockerイメージの指定もできるが「AWS CodeBuildマネージ型イメージの使用」を選択した。 OSは[ Ubuntu ]、ランタイムは[ Docker ]を選択。バージョンは2017/12/22で選択可能だった[ aws/codebuild/docker:17.09.0 ]を選択した。このDockerイメージって公開されているのだろうか、 公開されてると、手元で検証しやすいので良いのだが、まだ見つけられてない。
CodeBuild サービスロール( 重要、私はハマった )
ここで作成されるIAMだが、ECRへの接続許可がついてなかった。ので、CodeBuildでECR用のイメージをアップするために
aws ecr get-login --no-include-email --region ap-northeast-1
しようとした段階で権限が足りないエラーが出た。IAM権限に追加する箇所は次のステップかな、と勘違いしてた…
docker pull しようとした際に、イメージがダウンロードできないエラーが出た。
「そんなリポジトリは無い」というエラー。下記の権限はついていた。が、
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetAuthorizationToken",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
リストアップする権限がついてないとpullできない。AmazonEC2ContainerRegistryPowerUser の権限を付与したら下記のようになってpullできるようになった。
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
ここが非常に参考になった https://qiita.com/tiibun/items/f0045011c86efca254fc
ただpullする目的であった、Dockerイメージのキャッシュを利用してビルド高速化、はできてない。 再度、ビルドプロセスが走ってしまう。
-
VPCは管理下のVPC、サブネット、セキュリティグループを選択した。
-
[ アドバンスド ]は、今は設定せずに[ ビルドプロジェクトの保存 ]をクリックした( 多分、環境変数を設定する際に必要になりそう )
-
UIが分かりづらい気がするが [ 次のステップ ]を押す前に、ビルドプロジェクトを保存する必要がある。 ここは、Pipelineの画面だが、一部CodeBuildの設定が開いているような構図になっていて、先にCodeBuildのプロジェクトを保存する必要がありそうだ。
デプロイ
[ デプロイプロバイダ ]は[ デプロイ無し ]を選択した。 現状、確定できていないが、方法としては2つありそうだ。
- [ Amazon ECS ]を選択して、PipelineからECSにデプロイしてもらう
- あらかじめCloudFormationのスタックを組んでおいて [ AWS CloudFormation ]を選択する 後者の方がどうやら良いらしいが、当座は『まずCodeBuildで弊社用のDockerイメージをビルドしてECRにアップする』をやってみる。
AWSでは、最後のリリースをCloudFormationで行う例が紹介されてる AWS CodePipeline, AWS CodeBuild, Amazon ECR, AWS CloudFormationを利用したAmazon ECSへの継続的デプロイメント | Amazon Web Services ブログ コードを出して頂きたいところでもあるが。
サービスロール
これが分かりにくかった、新しくサービスロールを作成する場合[ AWS-CodePipeline-Service ]というIAMロールが作成され IAMの管理画面から確認できる、一見すると、このIAMロールに「ECRへのアクセス許可を付与すれば良いのではないか」と思ったが、 それではダメで、[ CodeBuild サービスロール ]に必要な権限が付与されている必要がある。 ( 私の環境ではECRへのアクセス許可を追加する必要があった。 これはAWSが悪いわけではない。 CodeBuildは必ずしもECS, ECRに特化している訳ではないので )
レビュー
[ パイプラインの作成 ]をクリック
buildspec.yml について
ECRへのDockerイメージのアップができたら、下記のように構成になるように進める。
CodePipeline, CodeBuildを使ってAmazon ECSへの継続的デプロイメントを試してみた | Developers.IO
『ブランチ運用をどうすべきか?』
最初は、「特定のブランチにpushされたらECRのイメージを更新する」というPipelineを考えていた。 が、「あるブランチに複数の傍流からのpushを送るとコンフリクトする」という状況がある。
これを解決するため、ほかの状況でどのような運用がされているか確認してみた。
エンジニア一人ひとりの検証環境をAWSECSを使って実装してみる
http://techblog.scouter.co.jp/entry/2017/06/19/090000
この人の目指している環境は理想的だ。ただAndroidアプリが参照するAPIエンドポイントは固定(のハズ。コードを変更する必要がある) と考えると「APIエンドポイントは一人ひとりというよりは『会社でひとつ』くらい」が妥当と思われる。
ただ興味深い知見がある
https://github.com/kotamat/ecs_dev のcloud-formation.ymlを参考にサービスを起動します。
読んでみたら、CodeBuild使ってのDockerイメージの更新とかではなく、ecs-cliで開発者側にコンテナをアップデートしてもらってた。
CodePipeline, CodeBuildを使ってAmazon ECSへの継続的デプロイメントを試してみた | Developers.IO 上記の内容は『特定の一つのブランチ(マスターブランチ)を監視しているのみ』だった。
CloudFormation でTask定義をアップデートしていく
この情報はかなり細かく、また詳しい。またかなり苦労してるっぽい。シンプルな説明はないものか、と思うが複雑な問題を扱っているのかも ECSのcloudformationのtemplateを作成 - Septeni Engineer’s Blog
こちらの方が手順が新しい。2017/12 にCodePipelineがECSへのデプロイをサポートした。それを使っての手順。 AWS CodePipelineがECSへのデプロイをサポートしたのでやってみる - Qiita
こちらの機能を使っているようだ。buildspec.ymlの参考に CodePipeline で ECS にデプロイできるようになり、Docker 環境の継続的デリバリも簡単になりました | Developers.IO
CodeBuildのフォーマット( 日本語 )
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html