見出し画像

AWS ECS(fargate)を使ったCI・CD環境構築と悩んだポイント

藤田ニコル推しのみなさんこんにちは。システムチームnugget担当の船津です。Fintertechでは安全にサービスを開発・運用するために、日々研究をしています。
今回はAWSのECS(fargate)というdockerコンテナのマネジメントサービスを使ったシステム構成の紹介と導入にあたって悩んだポイントについてご紹介します。


課題

システム開発現場でのよくある運用課題として以下のようなものが挙げられるかと思います。

・開発・検証環境と本番環境の構成が異なっている
・デプロイの度に長大な手順を安全確認しながら手作業している
・担当者が辞めてしまったので誰もサーバーをメンテナンスできない

最初は小さかったこのような課題は時間とともに大きくなりがちで、現在進行形で悩んでおられる方も多いのではないでしょうか。
弊社においてもこれらは他人事ではなく、フィンテック企業として安心・安全なアプリケーションを継続的にデリバリーするために新しい仕組みを検討していました。

このような課題の解決策を考える中で、ECS(fargate)を使うと比較的低コストで、以下のような環境を構築することができ、上記課題を解決できそうだと考えました。

・デプロイがボタン一つでできる(自動化も可能)
・ブルーグリーンデプロイができる
・動作環境をDockerにすることでコード管理することができる
・Dockerなので本番環境と検証環境、またローカルの開発環境をほぼ同一に保つことができる
・サーバーの管理、メンテナンスが不要

そこで、まずは開発中であった1コンテナ1プロセス構成のアプリケーションで導入してみることにしました。

システム構築にあたっての注意点

前提として、ECS(fargate)はディスク容量が限られており、ログやファイルなどは基本的に外部に出す必要があります。
また、オートスケールやデプロイによってインスタンスが簡単に破棄されるため、基本的に内部に状態を持つべきではありません。そのため、設定、環境変数、機密情報についてはAWSのパラメータ保存系サービスと連携させる必要があります(タスク定義にも設定することが可能ですが、おそらくあまりオススメではないでしょう)。

上記を考慮した結果、以下のような構成になりました。

・ELB + アプリケーション + RDS
・アプリケーションログはすべて標準出力 → Cloudwatchlogsへ送信
・画像ファイルなどはS3にアップロード
・機密情報はKMSに設定、ECS(fargate)にロールを設定して復号化

Pushからコンテナイメージのビルド、タスク定義更新までを自動化

開発されたアプリケーションはコンテナイメージとしてECR(Dockerのコンテナイメージを貯めておくところ、DockerHubのようなもの)に集約されます。
CodeCommitにpushされたDockerfileを元にCodeBuildでDockerイメージを作成し、ECRへpush、そのイメージをもとにタスク定義を更新する仕組みをecs-deployを用いて構築しました。

画像1


CodeBuildでのコンテナイメージビルドの際にはDockerfileに基づいて作成された環境で、アプリケーションのテスト・ビルドが実行され、動作保証がされたもののみがコンテナイメージとしてECRにpushされ、ECSタスク定義の更新までを自動実行します。

画像2


本番環境とステージング環境で同じコンテナイメージを利用

本番環境とステージング環境で同じコンテナイメージを利用することで、環境変数以外が全く同じ環境でのアプリケーション実行環境の構築を実現しました。
タスク定義の更新はmasterブランチにpushされた場合にCodebuildから自動で行われます。


ブルーグリーンデプロイが非常に魅力的

ブルーグリーンデプロイを標準機能として持っているのでそちらも利用しました。
デプロイが完了するとELBがルーティングするターゲットグループを自動で変更してくれます。
ロールバックもボタン一つなので、万が一不具合が発生した場合も安心できます。
コンテナイメージサイズにもよりますが、デプロイに5分、ロールバックに1分くらいでしょうか。

画像3

導入で悩んだポイント

導入するにあたって悩んだポイントも多くありましたが、大きくは以下の2つかと思います。

セキュリティ

サーバーのセキュリティ対策は考えなくて良くなりましたが、Dockerイメージのセキュリティ問題は残ります。ECRではイメージスキャンが可能なので、Codebuildの中でスキャンを組み込むと良いかと思います。

運用

ssh、docker exec系のコマンドが使用できないため、実機デバッグ不可という運用において大きな課題が存在します(これはセキュリティ的に見ると利点でもあるのですが…)。そのためアプリケーションログの設計が非常に大事になります。後で整形して分析しやすいようにJSON形式でのログ出力がおすすめです。
DBへのマイグレーション等も難しいところで、別途インスタンスやコンテナを用意するといった一手間が必要になります。


終わりに

アプリケーション開発は運用がはじまってからが本番です。
運用を見据えて、負荷を最小限にする構成で構築していくのが大事ですね。
1プロセスだけの小さなアプリケーション(今回のようなELB+アプリケーション+RDSだけの構成など)なら導入ハードルが低いので検討してみるのが良いかと思います。小さなチームにとって、サーバー管理から開放されるメリットはとてつもなく大きいと思います。

また、サービス検出サービスというものを用いると他のサービス(EC2等)とfargateインスタンスとの相互通信が可能になるため、大きなサービスを分割してマイクロサービスとして改修していくのに役立つ仕組みも用意されています。ぜひご検討ください。

また運用の悩みをブログにて共有できればと思います。

FintertechではAWSでの構築・運用に興味がある方を募集しています!
お問い合わせお待ちしています!