☕️

ecspresso advent calendar 2020 day 21 - やること、やらないこと

5 min read

Amazon ECS のデプロイツールである ecspresso の利用法をまとめていく ecspresso Advent calendar 21日目です。

ecspresso の設計思想

ecspresso は、ツールが操作する範囲を意図的に ECS のみに限定するように設計されています。必要な関連リソースについては利用者が他の手段で管理することを前提としています。

ここではその意図と、ecspresso の実装を説明します。

AWSでアプリケーションを構築するために必要なサービス

ECS は AWS のサービスの中で、コンテナオーケストレーションのためのビルディングブロックとして存在しています。

ECS だけでアプリケーションのすべてを構築することはできません。データの永続化には外部のデータストア (S3, RDS, ElastiCache, DynamoDB...)を利用するのが前提です。ログの記録には CloudWatch Logs を、ロードバランサーには ELB を利用します。

VPC 内にしか配置できないサービス (RDS, ElastiCache, EFS など) を利用するためには、ECS が利用する VPC とそれらのサービスを同一の VPC に配置するのが自然です。VPC 内のネットワークレベルでのアクセス制御にはセキュリティーグループが必要になります。

アプリケーションのすべてが ECS で構築されておらず、EC2 や Lambda が組み合わさって動作する場合には、1つの ELB から ECS と EC2 と Lambda にそれぞれアクセスを振り分けるような構成もあり得ます。

つまり ECS をデプロイするために必要な関連リソースは、他のサービスと共用されるものが多いのです。

ECS の管理に特化する必要性

ECS で動作するアプリケーションの関連リソースは、実際に構築されているシステムによって千差万別です。デプロイツールがすべてを掌握できるとは思えません。

特に既存の EC2 で動いているアプリケーションを ECS に移行するような場合は、ほとんどの関連リソースが存在している状態で、後から ECS のみを追加していくことになります。ECS のために必要なリソースだからといって、デプロイツールが新規に関連リソースを作成して管理下に置いてしまうと、既存リソースと管理方法を揃えることができなくなってしまいます。

そのため、ecspresso は意図的に ECS のみに管理範囲を絞っています。

ライフサイクルの違い

ECS ではアプリケーションに特化したドメインを扱う、自らが開発したソフトウェアを動作させることが多いと思います。そのソフトウェアは開発が進むごとに、多ければ日に何度もデプロイ(リリース)されることもあるでしょう。

それと比較して、ネットワークの設定や、データ保存のために AWS が提供しているマネージドサービスの構成変更は、そこまで頻繁ではないのが一般的です。

すべてが一体となってアプリケーションを構成しているのは間違いないのですが、ライフサイクルの違いから、ソフトウェアの開発とそれ以外の AWS のサービスの管理はそれぞれ別のチームが担当していることも多くあります。

その場合にすべてを1つのツールで管理していると、頻繁に行われるソフトウェアのリリースに伴って、意図しない関連リソースの設定変更が引き起こされてしまうような事故の可能性も増えてしまいます。

ecspresso は ECS のみに管理範囲を絞ることで、頻繁にデプロイされることが多いソフトウェアと、そうではないリソースの管理を分割しています。チームが分かれている場合でもそれぞれの操作範囲を限定し、安全性を高めています。

外部リソースとの連携

ecspresso が扱うタスクとサービスの定義ファイルには、関連リソースの ID や ARN などが含まれます。このファイル内の ID や ARN をハードコードせずに記述できると管理が容易になります。

19日目 では、Terraform の tfstate ファイルを読み込むことで連携する方法について解説しています。

20日目 では、定義ファイルを Jsonnet というテンプレート言語で生成することで、定義ファイルの JSON を管理しやすいソースコードから生成する方法について解説しています。

ecspresso が管理する範囲を実装から確認する

実際に ecspresso がなにを操作するのか、実装から確認してみましょう。

ecspresso はほぼ ECS のみの操作しか行いません。それ以外のリソースについては、基本的には読み取り操作のみを行います。(CodeDeploy へのデプロイメント発行、オートスケーリングの一時停止、verifyでのログ書き込みが例外です)

アプリケーション本体

ecspresso のアプリケーション本体を表現しているのが ecspresso.App 構造体です。

https://github.com/kayac/ecspresso/blob/v1.2.1/ecspresso.go#L40-L45
type App struct {
	ecs         *ecs.ECS
	autoScaling *applicationautoscaling.ApplicationAutoScaling
	codedeploy  *codedeploy.CodeDeploy
	cwl         *cloudwatchlogs.CloudWatchLogs
	iam         *iam.IAM

この中のフィールドとして、ecspresso が操作する aws-sdk-go のそれぞれのサービスが存在しています。

  • ECS: いうまでもなくメインは Amazon ECS です。ecspresso が操作するサービスはほぼ ECS のみです
  • ApplicationAutoScaling: ecspresso deploy --suspend-autoscaling オプションで、デプロイ前に一時的にオートスケーリングを停止させるためだけに使用します
  • CodeDeploy: CodeDeploy で Blue/Green デプロイを行うサービスの場合、CodeDeploy アプリケーションとデプロイグループを検索し、デプロイメントを作成するためだけに使用します
  • CloudWatchLogs: ecspresso run で起動したタスクが CloudWatch Logs にログを出力している場合、そのログを表示するためだけに使用します
  • IAM: ecspresso verify で、タスク定義内の IAM Role を確認するためだけに使用します

verifier

ecspresso verify コマンドで行う検証作業に使用する構造体が ecspresso.verifier です。この中にも AWS のサービスを操作するフィールドが存在します。

https://github.com/kayac/ecspresso/blob/v1.2.1/verify.go#L29-L36
type verifier struct {
	cwl            *cloudwatchlogs.CloudWatchLogs
	elbv2          *elbv2.ELBV2
	ssm            *ssm.SSM
	secretsmanager *secretsmanager.SecretsManager
	ecr            *ecr.ECR
	opt            *VerifyOption
}
  • CloudWatchLogs: ログの書き込みができるかの検証に使用します
  • ELBV2: LBターゲットグループが存在するかの確認に使用します
  • SSM, SecretsManager: タスク定義の secrets が読み取れるかの検証に使用します
  • ECR: タスク定義内のコンテナイメージが ECR に存在しているかの検証に使用します

ecspresso を実行するために必要な IAM Policy

v1.2.1 の時点では ecspresso の全機能を使うためには次の IAM 権限が必要になります。

  • ecs:*
  • iam:PassRole
  • logs:GetLogEvents (run コマンドを使用する場合)
  • codedeploy:List* (CodeDeploy でデプロイする場合)
  • codedeploy:CreateDeployment
  • codedeploy:BatchGet*
  • application-autoscaling:Describe* (deploy --suspend-autoscaling を使用する場合)
  • application-autoscaling:Register*

以下は ecspresso verify で必要になります。

  • iam:GetRole
  • sts:AssumeRole
  • ecr:ListImages
  • elasticloadbalancing:DescribeTargetGroups
  • ssm:GetParameter
  • secretsmanager:GetSecretValue

22日目は、ecspresso が内部で使用している OSS について説明します。

https://zenn.dev/fujiwara/articles/ecspresso-20201222