TerraformとecspressoでAmazon ECSを構築してAWS AppConfigの機能フラグを活用する
当社では9月に夏合宿を開催することになり、様々なテーマに沿って当日は活動します。合宿当日をとても楽しみにしております。やっさんでございます。
Amazon ECSのタスク定義とサービス定義はecspresso側にオフロードしながらもTerraformでインフラストラクチャのIaCを管理し、AWS AppConfigの機能フラグのオン / オフ を切り替える方法をご紹介します。
AWS AppConfigとは
AWS AppConfig(以下AppConfig)とは、アプリケーション設定を作成・管理するためのAWS Systems Managerの機能です。AppConfigを利用することで、アプリケーションのチューニング、機能の切り替え、そして許可リストなど、様々なアプリケーションの設定を管理することができます。
AppConfigは下記2種類のアプリケーション設定を管理することが出来ます。自由形式の設定プロファイルと機能フラグです。
アプリケーション設定 種別 | 説明 |
---|---|
自由形式の設定プロファイル | プレーンテキスト形式の設定プロファイルを管理 Text / JSON / YAML のフォーマットで記述 設定ソースの選択肢が豊富で、入力した設定内容の検証の仕組みを用意することも可能。 |
機能フラグ | フラグのオン / オフを管理する機能 非推奨フラグの指定、フラグへの追加属性、そして拡張機能のオプションがある。 |
Amazon ECSにおけるAWS AppConfigの利用
Amazon ECSにおいてAppConfigを活用することで、アプリケーションのビルド・デプロイを行うことなく、機能のオン / オフを切り替えることが出来るようになります。
Amazon ECSにおけるAWS AppConfig エージェントの利用
Amazon ECSの場合はタスク定義にサイドカーコンテナとしてAppConfigのエージェントを指定することでアプリケーションコンテナから機能フラグのオン / オフを切り替えることができます。
やってみよう!Amazon ECSでAWS AppConfig!
ここからは、Amazon ECSでAWS AppConfigを利用し機能フラグの オン / オフ を切り替える手順をご紹介します。今回利用するコードはGitHubにあります。アプリケーションはPythonのFastAPIフレームワークを用いたシンプルなAPIサーバーを構築します。
前提条件
本記事に記載されている手順を実行するには、以下のソフトウェアをインストールする必要があります。
- Terraform
- ecspresso
- AWS CLI
- jq
- Docker Desktop
また、本記事の手順でAWSリソースを構築した場合はAWS利用料金が発生いたします。1日で1ドル前後の利用料金になります。手順3を実施し作成したAWSリソースを削除してください。
手順1. Terraformとecspressoを用いてIaCをプロビジョニングする
本手順では、Amazon ECSを用いてアプリケーションをデプロイするためのインフラストラクチャのサービスをIaCでデプロイします。IaCはまず、Terraformを用いて以下のサービスをプロビジョニングします。
- Amazon ECS クラスター
- Application Load Balancer
- Security Group
- Amazon CloudWatch Log Group
- AWS AppConfig
TerraformのIaCのコード全文はGitHubをご参照下さい。
次にecspressoを用いてECSの以下の機能を管理します。
- Amazon ECS タスク定義
- Amazon ECS サービス定義
ecspressoはECSのにおける「サービスとタスク定義の管理」と「デプロイ」を容易にするオープンソースソフトウェア(OSS)です。
ecspressoのIaCのコード全文はGitHubをご参照下さい。
ecspressoはTerraformのtfstateファイルの値を参照することができます
ecspressoは、IaCのソフトウェアを繋げる糊のような仕組みを持っています。今回はecspressoが管理するECSサービスとタスク情報に、事前に構築したTerraformのインフラストラクチャ情報の値を埋め込んでいます。
以下のコード例では、escpressoのECSサービス定義はTerraformで作成されたセキュリティグループを下記のように tfstate
構文によって参照しています。また、 must_env
構文によってローカルの環境変数も参照しています。
"networkConfiguration": {
"awsvpcConfiguration": {
"assignPublicIp": "ENABLED",
"securityGroups": [
"{{ tfstate `aws_security_group.yassan-fa-ac-ecs-srv-sg.id` }}"
],
"subnets": [
"{{ must_env `TF_VAR_subnet_id_public_a` }}",
"{{ must_env `TF_VAR_subnet_id_public_c` }}"
]
}
},
それでは、IaCのコードをプロビジョニングしていきます。まず最初に、 .env.example
ファイルから .env
ファイルを作成し、下記の必要な項目を入力します。
環境変数名 | 説明 |
---|---|
M_AWS_ACCOUNT_ID | AWSのアカウントID |
M_AWS_REGION | AWSのリージョン |
TF_S3_BUCKET | Terraformのtfstateファイルを保存するS3バケット |
TF_S3_KEY | Terraformのtfstateファイルを保存するS3キー |
TF_VAR_vpc_id | 事前に用意するAWSのVPC ID |
TF_VAR_subnet_id_public_a | 事前に用意するAWSのPublic Subnet その1 |
TF_VAR_subnet_id_public_c | 事前に用意するAWSのPublic Subnet その2 |
CONTAINER_IMAGE_TAG | ECRにアップロードされたコンテナイメージのイメージタグ。1-1の手順の時点では、未入力で問題ありません。 |
入力例は以下の通りです。
M_AWS_ACCOUNT_ID=xxxxxxxxxxxx
M_AWS_REGION=ap-northeast-1
TF_S3_BUCKET=xxxxxxxxxxxx-tf
TF_S3_KEY=tfstate/try-fast-api-appconfig-iac/terraform.tfstate
TF_VAR_vpc_id=vpc-xxxxxxxxxxxxxxxxx
TF_VAR_subnet_id_public_a=subnet-xxxxxxxxxxxxxxxxx
TF_VAR_subnet_id_public_c=subnet-xxxxxxxxxxxxxxxxx
CONTAINER_IMAGE_TAG=
次にTerraformを用いてAWSの環境に必要なリソースをプロビジョニングします。AWSのクレデンシャル情報は事前に設定して頂くようお願いします。以下のコマンドを実行しTerraform環境を初期化します。
1export $(cat .env| grep -v "#" | xargs)
2make tf_init
そして、以下のコマンドを実行しTerraformのインフラストラクチャコードをプロビジョニングします。
1make tf_apply
Terraformの実行が正常終了したら、以下のコマンドを実行してアプリケーションをビルドしコンテナレジストリ(Amazon ECR)にプッシュします。正常終了後に出力されたGitのコミットハッシュを控えておきます。
1make app_build_and_push
上記コマンド実行後に出力されたGitのコミットハッシュを環境変数ファイル .env
に入力します。入力した例は以下のようになります。8行目を変更しました。
M_AWS_ACCOUNT_ID=xxxxxxxxxxxx
M_AWS_REGION=ap-northeast-1
TF_S3_BUCKET=xxxxxxxxxxxx-tf
TF_S3_KEY=tfstate/try-fast-api-appconfig-iac/terraform.tfstate
TF_VAR_vpc_id=vpc-xxxxxxxxxxxxxxxxx
TF_VAR_subnet_id_public_a=subnet-xxxxxxxxxxxxxxxxx
TF_VAR_subnet_id_public_c=subnet-xxxxxxxxxxxxxxxxx
CONTAINER_IMAGE_TAG=f76cbc6
次にecspressoを用いてECSのサービス定義とタスク定義をデプロイします。以下のコマンドを実行します。
1export $(cat .env| grep -v "#" | xargs)
2make ecspresso_deploy
上記までの手順を行うことで、インフラストラクチャとプロビジョニングとアプリケーションのデプロイが完了しました。
手順2. AWS AppConfigを利用して機能のオン / オフを切り替える
それでは、前項でデプロイしたアプリケーションでAppConfigの機能フラグを切り替えてみます。まずは、AWSマネージメントコンソールからAPIのURLを確認します。その後に、URL(API Endpoint)を呼び出して機能フラグの状態を確認します。
URLのエンドポイントは /hello/name
とします。
フラグはfalse(オフ)が返却され、機能が無効であることを確認できました。
TerraformのIaCコードを変更し、AppConfigの機能フラグをオンにします。Terraformの変更箇所は以下の通りです。
resource "aws_appconfig_hosted_configuration_version" "yassan-ac-hcv" {
application_id = aws_appconfig_application.yassan-ac-app.id
configuration_profile_id = aws_appconfig_configuration_profile.yassan-ac-c-profile.configuration_profile_id
content = jsonencode({
flags : {
featureA : {
name : "featureA"
}
},
values : {
featureA : {
enabled : "true"
}
},
version : "1"
})
content_type = "application/json"
}
上記の機能フラグの変更を有効にするには、以下のコマンドを実行します。
1make tf_apply
反映後に、機能フラグの変更がデプロイされていることをAWSマネージメントコンソールから確認できました。
それでは、もう一度APIのEndpointを呼び出して機能フラグの状態を確認します。
機能フラグが有効(オン)になっていることを確認できました!
手順3. 後片付け
最後に全てのAWSリソースを削除して、不要なコストを削減しましょう。以下のコマンドを順番に実行してリソースを削除します。
1make ecspresso_delete
2make ecr_clean
3make tf_destroy
まとめ
TerraformとecspressoでAmazon ECSのIaC環境を構築してAWS AppConfigの機能フラグを活用する方法についてご紹介しました。AWS AppConfigは漸進的なアーキテクチャ構築を行う上でとても重要なサービスです。引き続き積極的にAppConfig活用していければと思います。
今回はAppConfigのIaCにTerraformコードの履歴を追う想定でバージョンを管理しましたが、AppConfigのネイティブバージョン管理機能を用いた場合のIaCとの相性についても模索していければと思います。