AWS Proton を使って快適に開発をしたいのです!

AWS Proton を使って快適に開発をしたいのです!

いつもお世話になっております。株式会社アンチパターンの矢ヶ崎です。

さて、今回は AWS Proton について書いてみたいと思います。まだ日本語の情報も少なく、あまり有名になっていない気がするサービスですが、日本のエンジニアリングの状況にとってもマッチしている気がしていますので、活用が進むといいな〜と思っております。

開発と運用・アプリとインフラの各チームの関係性

よく DevOps という言葉を聞く場面があるかと思います。雑に言うと、開発(Dev)・運用(Ops)の垣根をなくそうぜ!人的にも組織的にもカルチャー的にもツールやプラクティス的にも!そうするとアジリティが上がるからいろいろいいぜ!みたいな感じです。しかし、さらにアプリとインフラという分けも出てくるので実際の事象は複雑です。

AWS Well-Architected フレームワークでは、運用上の優秀性の柱の組織の領域において、運用モデル 2 x 2 の表現として以下のような4つの運用モデルを示してくれています。
https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/operational-excellence-pillar/operating-model-2-by-2-representations.html

完全に分離された運用モデル

これは、大きな企業や大きなプロジェクトではよくある分け方だと思います。

アプリを作る人、運用する人、インフラを作る人、運用する人、みたいに分かれています。また各チームごとに目的が異なっているので、チーム間で責任の押し付け合いが発生することもしばしばあります。システムを作る目的は、利用者の生産性向上やユーザ体験の向上などで共通しているのに、各チームの目的にブレイクダウンすると責任の押し付け合いになってしまうのは悲しいですし不毛ですよね。

分離されたアプリケーションのエンジニアリングと運用 (AEO) および一元化されたガバナンスを備えたインフラストラクチャのエンジニアリングと運用 (IEO)
分離された AEO および一元化されたガバナンスとサービスプロバイダを備えた IEO
分離された AEO と一元化されていないガバナンスを備えた IEO

2つ目以降のモデルでは、いわゆる”you build it you run it”つまり作った人が運用するモデルになっています。これはDevOpsにおいても重要なポイントの一つで、実際に運用している人が直面している問題、お客様が持っている課題をストレートに実装に活かせます。アプリケーションの分野においてはそれはとても良いかもしれませんが、ここにプラットフォームやインフラストラクチャの話が入ってくるとまたやっかいです。

4つ目のモデルになってくると、アプリケーションエンジニアが大半の部分を担当することになります。昨今のシステム開発・サービス開発においては、アプリケーションのアーキテクチャはインフラのアーキテクチャと深い関係があるので、これを同じ人が行うことでより最適な全体アーキテクチャが構築できるのは理想的です。しかし、本番のシステム運用においてはアプリケーションには直接関係がない、インフラ・プラットフォームとしてのセキュリティや、さらにシステムをまたいでのガバナンスコントロール、マネージメントなどが必要になってきます。これはとても重要なポイントですが、アプリケーションエンジニアがそこまで考えるのか?というとなかなか難しく、また、そもそもやりたくないよ!ということも多々あるかと思います。

本番環境の実際

例えば、インフラストラクチャも含めたアプリケーションエンジニアが思い描くAWSインフラの設計としては

このような感じかもしれません。アプリケーション寄りの方にとってのインフラとはこのようなイメージで、おれ超いい感じにインフラも設計できたぜ!っていう感じかと思います。たしかに、サービス、アプリケーションの可用性、性能、拡張性などを考えると、いい感じですよね。


しかし、本番運用を行っていく上では実際には、

このように考えることが大幅に増えます。
本番環境においては、 機能・性能・可用性など以外にも、 運用・セキュリティ・ガバナンス・マネージメントなど 他にも多くのことを考えてインフラを構築する必要が出てきます。

では、アプリケーションエンジニアリングチームがやりたいこと「サービスにおけるシステム全体のアーキテクチャ設計と開発、運用」に集中し、「サービス内やサービスを超えたセキュリティ、ガバナンスコントロールやマネージメント」をプラットフォームエンジニアリングチームに任せるという分担を行うにはどうすればよいでしょうか?

具体的にAWSにおいては、 AWS Organizations や AWS Control Tower を使ってアカウントの払い出し、ランディングゾーンなどを活用し、 Service control policies や CloudFormation StackSets を使ってガバナンスコントロールやマネージメントを行っていくことになるかと思います。しかし、 AWS Organizations を使えない環境、複数ベンダーのアカウントの環境、各アカウント個別の環境と環境のバージョンコントロール、バージョンアップのタイミングなどを考えると、なかなか頭が痛くなってきます。

まってました AWS Proton!

そこで! AWS Proton の出番ですたぶん。 AWS Proton は、「コンテナおよびサーバーレスデプロイメント向けの管理の自動化」と説明がついているので、コンテナ・サーバレス文脈のサービスかな?と見えますが、どっちかというとコンテナ・サーバレスに限らずに「マネージメントとガバナンス」寄りのサービスかと思います。実際、分類的にも「マネージメントとガバナンス」になっています。

AWS Proton を使うにあたっては、2種類の登場人物が出てきます。管理者(Administrators)と開発者(Developers)です。

What is AWS Proton? - AWS Proton
As an administrator, you create a library of versioned infrastructure-as-code templates to provide standardized infrastructure and deployment tooling for serverless and container-based applications. Then, you or developers on your team, in turn, can select from the available templates to automate th…

正確には上記公式ドキュメントを読んでいただければと思いますが、ざっくりの流れでいうと

・管理者が環境テンプレート(ネットワーク、セキュリティ、マネジメントやガバナンスが入っている)を作成する
・環境テンプレートを、実際のAWSアカウントの各環境に適用する
・管理者がサービステンプレート(インスタンスやオートスケーリング、CI/CDなど実際のプロダクトやサービスに必要な構成が入っている)を作成する
・管理者もしくは開発者が、サービステンプレートを各環境に適用する
・開発者はアプリケーションのコードを書く
・開発者はコードリポジトリにプッシュし、CI/CDパイプラインがデプロイする
・サービスが動き出す

という感じです。

この「環境」というものの単位をどう考えるのかがまた一つのポイントになってきます。VPC単位で環境を考える、アカウント単位で環境を考えるなどによっても構成のしかたが変わってきます。
昨今のAWSのマルチアカウントベストプラクティスを考えると、例えば開発環境・ステージング環境・本番環境などの分割、またサービスによる環境の分割においても、AWSアカウントを分割する方法が良さそうです。実際にAWSの各種サービスもマルチアカウントを前提にしているサービスが多くなってきている印象です。そのため、ここではAWS Protonを利用するにあたっても、「環境」=「AWSアカウント」という単位で考えてみることにしたいと思います。

マルチアカウントでAWS Proton利用する場合は、

・環境アカウント(各サービスが動くアカウント)から、管理アカウント(AWS Protonのテンプレートやそのバージョンが管理されているアカウント)に環境利用の申請をする
・管理アカウントが許可する
・管理アカウントから環境アカウントへ、環境テンプレートやサービステンプレートが展開できるようになる
・管理者で環境やサービスをコントロールしてあげる
・開発側はアプリケーションに集中する

という感じになります。

レッツドゥーイット!

では、実際にやってみましょう!

Fargate ベースでのサンプルを使って実際に AWS Proton を操作してみるサンプルは、こちらのGitHubの公式サンプルにそってやっていただくのがわかりやすいかと思います!このサンプルもマルチアカウントに対応しており、サービス展開時に、環境アカウント側のAWSアカウントIDを入力する部分(pipeline: environment_account_ids)にアカウントIDを入れれば、クロスアカウントでのECRからのデプロイを行うCI/CDパイプラインが作成されます。おおよそのイメージとしては、下図のような感じのインフラができちゃいます!

そのうち、「環境」として作成されるものは、

こんな感じで、この「環境」に対応した「サービス」として作成されるものは、

この丸の部分になります。

こうなると何がよいかというと、「環境」の部分は完全にプラットフォーム・インフラチームが管理することができ、「サービス」の部分は、プラットフォーム・インフラチームもしくはアプリケーションチームと相談してテンプレート化してバージョン管理をする、さらにその上で動作する部分はCI/CDパイプラインを通して完全にアプリケーションチームが管理することができます。
つまり、アプリケーションチームの立場からすると、「アプリケーションの関係するところに集中して、まわりのよくわからない部分はやらなくてもいいのね!最高!」って感じになることもできそうです。これは熱いですね。効率やアジリティのためにある程度はインフラも意識して開発する必要がありますが、直接関係ないところや管理はおまかせできちゃうなんて最高です。

そんな、モダンって言われても・・・

ただ、結局はコンテナとかサーバレスとかにしないとだめなんじゃないのか・・・EC2でJavaベースで作ってるから、このような状況は結局作れない、、、結局 2x2 の運用モデルになっちゃうのか・・・

と思いきや、AWS Proton のテンプレートは基本的に CloudFormation ベースでできているので、EC2/Javaベースでも当然できます。コンテナほどスムーズにはいかないですが、できます。

ということで、サンプルを作ってみました。

GitHub - yaggytter/sample-template-aws-proton
Contribute to yaggytter/sample-template-aws-proton development by creating an account on GitHub.

これはテンプレートのサンプルで、その上で動く簡易的な Spring Boot アプリケーションは、

GitHub - yaggytter/simpleapp-springboot-java
Contribute to yaggytter/simpleapp-springboot-java development by creating an account on GitHub.

こちらです。

これを使ってみると、おおよそこんな感じの構成が実現できます。

EC2 ベースでの CI/CD のやり方はいろいろあるかと思いますが、今回の構成では、 AMI を作成する専用のインスタンスを用意しておき、Code Repository(GitHubなど)の更新のタイミングでCodePipelineが動き、CodeBuildで mvn clean package をして成果物を AMI作成用 インスタンスにコピーし、 AMI を再作成、そしてオートスケーリンググループを更新しています。(EC2 Image Builder を使うのも良いかもしれません)

今後の AWS Proton への期待

AWS Proton 、ほんと素晴らしくて、ぼくたちの開発・運用スタイルをがらっと変えてくれる期待が高いのですが、まだちょっとアレなので、現時点でこういう機能があるともっと現実的に使いやすいな〜と思うものとしては

・テンプレートにCDKが使いたい(できればTerraformも)
・開発側アカウント(環境アカウント)から、サービステンプレートを自分で選んで適用できるようになりたい
・サンプルの環境テンプレートやサービステンプレートが充実してるといいな
・謎の内部エラーが出たときにデバッグできない
・公式ドキュメントがわかりづらい、そして間違っている・・・(フィードバック送ります)

このあたりができると、各組織のCCoEのみなさんもハッピーになれるんじゃないかな、デベロッパーもいろいろ考えなくて良くてハッピーになれるんじゃないかな、なんて思ってたりします。

ということで、 AWS Proton を使ってハッピーデベロッパーライフを過ごしていきましょ〜(希望)

こちらからは以上です。

謝辞:AMI 更新の部分は、 株式会社シーズの原口さんにご教示いただきました。ありがとうございます!