CodePipelineを試す

CIを回すサービス

それほど設定は面倒ではなかった。CodePipelineのウィザードに従うと、必要なIAMの作成、CodeBuildのプロジェクトが一気通貫で作成される。

ただ、buildspec.ymlなど各種手順を構築するのが面倒ではある ( が、これは、会社やサービスのシステム構成によってデプロイ方法は異なるものなので、しょうがない。本質的な問題と言える。 この手のツールにありがちな「本質的な悩みに到達する前の作業に時間がかかる」といった悩みの時間は少ないと言える )

はまりポイント

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

https://dev.classmethod.jp/cloud/aws/developing-cloudformation-ci-cd-pipeline-with-github-codebuild-codepipeline/

『ブランチ運用をどうすべきか?』

最初は、「特定のブランチに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

User
CloudFront
ALB
EC2
RDS