こんにちは、SREチーム、エンジニアの西脇(@yasuhiro1711)です。今日は、circleci/go-ecs-ecrを使って、CircleCI からECS にデプロイをしてみたいと思います。(参考リンクには非常にお世話になりました。ありがとうございます。)

今回は題材にちょうど合う、CircleCIを通じて、AWS ECS/ECR にデプロイするGoアプリケーションがあったのでこれを利用していきます。勉強の題材にとてもよかったです。(しかし注意として、今回利用の「circleci/go-ecs-ecr」は、2018年6月現在、すでに更新されていないため、現在のCircleCIとAWS環境に自分で合わせないと動作できない可能性もあります。ご注意ください。)

circleci/go-ecs-ecr: Example project for deploying a Go application to AWS ECS/ECR via CircleCI.
[https://github.com/circleci/go-ecs-ecr](https://github.com/circleci/go-ecs-ecr)

最終的に目指すのはこのような設計です。(ECSクラスタ部分は図としては詳細には書いておりません。)

設計

今回の構成では、GitHubにユーザからpushがされると、CircleCIがそれを自動検知し、build実行を始めます。すると最新のソースがECRのレジストリに登録されて、ECSにて定義更新等が走り、EC2内のDockerコンテナにデプロイされる仕組みです。

事前準備

これらは事前に準備しておきましょう。今回は詳細は触れません。

  • GitHubアカウント
  • CircleCI(GitHub連携)アカウント
  • AWS Credentials
  • ローカルMac端末にてaws cliコマンド導入済みであること

circleci/go-ecs-ecr準備

早速始めましょう。zipダウンロードかforkしてきます。

GitHub上でポチポチして、forkします。

github_fork

ソースの中身を見てみます。注意としては、このままだとリージョンが全てバージニアになるので、東京に全部変更してしまいましょう。

対象ファイル:circle.yml 、deploy.sh 
変更点:バージニア (us-east-1) から 東京 (ap-northeast-1) に変更する。

AWSのECRサービスにリポジトリを作成

ECR に go-sample-webapp という名前でリポジトリを作成しておきます。名前は今回利用のアプリケーションと揃えます。

一覧から、リポジトリの作成を選択します。

一覧

リポジトリ名を設定します。

リポジトリ設定

リポジトリの作成完了

完了すると、ECRへの接続方法がここで詳しく表示されます。(これは後からでも参照できますので、大丈夫です。)

リポジトリ作成完了

docker-login

つづいて、docker-pushの時にログインを促されるため、aws ecr get-login コマンドで,ECR にログインできることを確認しておきます。(ちゃんとみてないですが、今回の場合は実はいらないかもしれない。)

ローカルMACにて、
$ $(aws ecr get-login --region ap-northeast-1)

実施すると、エラーが発生。対応します。以下が原因でした。

小ネタ1

変なeが出力されるぞ。これを参考にして。

【小ネタ】Docker17.06以上からAmazon ECRへのdockerログインコマンドが変わった

dockerが17.06以上だと、 –no-include-email オプションが必要なのだそう。

$(aws ecr get-login –region ap-northeast-1 –no-include-email)

これに変更することで無事に実行。

そしてもう一つ。

小ネタ2

ローカルmacで、Docker起動してないと、以下のようなエラーになるよ。たまに忘れるので。

bash-3.2# $(aws ecr get-login --region ap-northeast-1 --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Warning: failed to get default registry endpoint from daemon (Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?). Using system default: https://index.docker.io/v1/
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

というわけで、$(aws ecr get-login --region ap-northeast-1 --no-include-email)で実行。

実行履歴

bash-3.2# $(aws ecr get-login --region ap-northeast-1 --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

ECS で仮のタスク定義を作成

CircleCIで実行するbuildで、自動的にECSの「タスク定義」を作成されるようにするため、ここでは ECSクラスタを起動するためだけに仮のタスク定義を作成しておきます。

タスク定義にて、「新しいタスク定義の作成」を選択し、

タスク定義

名前は sample-webapp-task としておきます。

タスク定義2

※コンテナ定義も今回は仮で適当に入れて進めます

次に ECSクラスタと ECSサービスを作成していきます。

ECSクラスタを作成

まずは、ECSクラスタを作成しましょう。

クラスターの作成 を選択。

クラスタ作成

テンプレート選んで、

テンプレ

今回は以下の項目で設定しました。

  • クラスタ名 : sample-webapp-cluster
  • インスタンスタイプ : t2.micro
  • インスタンス数 : 3
  • ネットワーク : 既存VPCを利用
  • セキュリティ : TCP 80をIP制限かけて解放
  • コンテナインスタンス IAM ロール : デフォルト
作成完了!

クラスタ作成完了

続いて、ECSサービスの作成に取り掛かります。

ECSサービス作成

作成したクラスターに入って、サービスタブで、「作成」

ECSサービス作成

こんな感じで設定します。
  • サービス名 : sample-webapp-service
  • タスク定義名 : sample-webapp-task-family(自動的にデプロイされるので設定はなし。)
  • Desired Count : 1
  • 最小ヘルス率 : デフォルト
  • 最大率 : デフォルト
  • ELB :  なし
  • autoscalling : なし

画像と数値が違いますが、この画面です。
新規作成

作成が完了すると、このような画面に遷移します。

作成完了

CircleCI の設定

続いて、CircleCIでの作業です。通常、初めて利用する場合はCircleCIとGithubの連携をしないといけませんが、今回は省きまして、プロジェクトの追加からです。

project を追加

Add Projectsを選択

add_project1

今回のprojectで、「Set up Project」ボタンをクリックして、projectの設定に進みます

add_project3

※ 今はCicleCIがversion2.0 になっているので、この画面では、2.0を促してきます。 2.0にしたい場合はここでこの手順のように、2.0の書き方にymlを変更する必要があります。)

project 追加完了

これでプロジェクトは登録完了です。このままbuildしたいけど、追加設定が必要です。

利用IAMユーザへ権限付与(作業はAWS)

CircleCI用の IAM User を作成します。 今回は、既存アカウントを利用しましたが、利用ユーザに以下権限をアタッチします。

AmazonEC2ContainerRegistryFullAccess
AmazonEC2ContainerServiceFullAccess

Environment Variables に環境変数を設定

以下の環境変数を設定します。

AWS_ACCOUNT_ID   xxxxxxxx
AWS_ACCESS_KEY_ID    xxxxxxxx
AWS_SECRET_ACCESS_KEY  xxxxxxxx
左メニューからinsightsを選択し、今回のプロジェクトの歯車ボタンを押す。

insight

メニューから環境変数設定を選び、設定。

環境変数

設定したら、buildを走らせます。

初ビルド

お!

deploy.sh の下記で止まりました。

デプロイ中

確認してみて、

最終的に、$(aws ecr get-login --region ap-northeast-1 --no-include-email)の記述を、$(aws ecr get-login --region ap-northeast-1)に変更することで解決しました。うーん、なるほどです。

その結果

ビルド成功

build成功

デプロイされ、起動したアプリのIPに接続すると、無事に、「Hello World!」の表示が確認できます。

Hello world

これで、一連の設定が出来ました。せっかくなのでこのまま、アプリを編集しての再デプロイしてみましょう。

継続的インテグレーションしてみる

アプリの出力を「Hello World!」から「Hello World! weddingpark」と変更します。(Hello World!の文字列出力部分はbuildの時のtestでも利用しているので変更には気をつけましょう。)
今回はテストなので、GitHub上で修正してpushします。すると、自動でCircleCIがキックされbuildを開始し、デプロイまでされて、、

成功!

build2

簡単にアプリ修正からリリースまでが自動で実行できました。

デプロイの仕組み

今回の仕組みで大事なのは、CircleCI向けの設定と、deploy.sh の設定です。それぞれどんなことをしているのか、簡単に見て見ます。

circle.yml

  • docker build を実行して、Dockerイメージを作成。
  • テストでは docker runでコンテナを実行、起動。アプリの起動を確認する。
  • masterブランチにpushされた場合には deploy.sh を実行する。

deploy.sh

  • AWS CLI の設定をする
  • ECR に Dockerイメージをpushする
  • タスク定義のリビジョンを更新。最新のDockerイメージをサービスに反映
  • サービスに紐付くタスク定義を更新して ECSクラスターにデプロイをする

エンジニア大募集中

Wedding Parkでは一緒に技術のウエディングパークを創っていくエンジニアを募集しています。
興味のある方はぜひ一度気軽にオフィスに遊びにいらして頂ければと思います。

ブライダル業界のデジタルシフトを加速させるリードエンジニア候補募集!

とてもお世話になった参考サイト

CircleCI で ECS にデプロイをするサンプルプロジェクト circleci/go-ecs-ecr を試した – kakakakakku blog

CircleCI+ECS+ECR環境でDockerコンテナのCD(継続的デプロイ)環境を構築する -後編- | Developers.IO

Join Us !

ウエディングパークでは、一緒に働く仲間を募集しています!
ご興味ある方は、お気軽にお問合せください(カジュアル面談から可)

採用情報を見る