こんにちは、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します。
ソースの中身を見てみます。注意としては、このままだとリージョンが全てバージニアになるので、東京に全部変更してしまいましょう。
対象ファイル: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 としておきます。
※コンテナ定義も今回は仮で適当に入れて進めます
次に ECSクラスタと ECSサービスを作成していきます。
ECSクラスタを作成
まずは、ECSクラスタを作成しましょう。
クラスターの作成 を選択。
テンプレート選んで、
今回は以下の項目で設定しました。
- クラスタ名 : sample-webapp-cluster
- インスタンスタイプ : t2.micro
- インスタンス数 : 3
- ネットワーク : 既存VPCを利用
- セキュリティ : TCP 80をIP制限かけて解放
- コンテナインスタンス IAM ロール : デフォルト
作成完了!
続いて、ECSサービスの作成に取り掛かります。
ECSサービス作成
作成したクラスターに入って、サービスタブで、「作成」
こんな感じで設定します。
- サービス名 : sample-webapp-service
- タスク定義名 : sample-webapp-task-family(自動的にデプロイされるので設定はなし。)
- Desired Count : 1
- 最小ヘルス率 : デフォルト
- 最大率 : デフォルト
- ELB : なし
- autoscalling : なし
画像と数値が違いますが、この画面です。
作成が完了すると、このような画面に遷移します。
CircleCI の設定
続いて、CircleCIでの作業です。通常、初めて利用する場合はCircleCIとGithubの連携をしないといけませんが、今回は省きまして、プロジェクトの追加からです。
project を追加
Add Projectsを選択
今回のprojectで、「Set up Project」ボタンをクリックして、projectの設定に進みます
※ 今はCicleCIがversion2.0 になっているので、この画面では、2.0を促してきます。 2.0にしたい場合はここでこの手順のように、2.0の書き方にymlを変更する必要があります。)
これでプロジェクトは登録完了です。このまま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を選択し、今回のプロジェクトの歯車ボタンを押す。
メニューから環境変数設定を選び、設定。
設定したら、buildを走らせます。
お!
deploy.sh の下記で止まりました。
確認してみて、
最終的に、$(aws ecr get-login --region ap-northeast-1 --no-include-email)
の記述を、$(aws ecr get-login --region ap-northeast-1)
に変更することで解決しました。うーん、なるほどです。
その結果
ビルド成功
デプロイされ、起動したアプリのIPに接続すると、無事に、「Hello World!」の表示が確認できます。
これで、一連の設定が出来ました。せっかくなのでこのまま、アプリを編集しての再デプロイしてみましょう。
継続的インテグレーションしてみる
アプリの出力を「Hello World!」から「Hello World! weddingpark」と変更します。(Hello World!の文字列出力部分はbuildの時のtestでも利用しているので変更には気をつけましょう。)
今回はテストなので、GitHub上で修正してpushします。すると、自動でCircleCIがキックされbuildを開始し、デプロイまでされて、、
成功!
簡単にアプリ修正からリリースまでが自動で実行できました。
デプロイの仕組み
今回の仕組みで大事なのは、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