AWS

TerraformとecspressoでAmazon ECSを構築してAWS AppConfigの機能フラグを活用する

yassan

当社では9月に夏合宿を開催することになり、様々なテーマに沿って当日は活動します。合宿当日をとても楽しみにしております。やっさんでございます。

Amazon ECSのタスク定義とサービス定義はecspresso側にオフロードしながらもTerraformでインフラストラクチャのIaCを管理し、AWS AppConfigの機能フラグのオン / オフ を切り替える方法をご紹介します。

AWS AppConfigとは

AWS AppConfig(以下AppConfig)とは、アプリケーション設定を作成・管理するためのAWS Systems Managerの機能です。AppConfigを利用することで、アプリケーションのチューニング、機能の切り替え、そして許可リストなど、様々なアプリケーションの設定を管理することができます。

AppConfigは下記2種類のアプリケーション設定を管理することが出来ます。自由形式の設定プロファイルと機能フラグです。

アプリケーション設定 種別説明
自由形式の設定プロファイルプレーンテキスト形式の設定プロファイルを管理
Text / JSON / YAML のフォーマットで記述

設定ソースの選択肢が豊富で、入力した設定内容の検証の仕組みを用意することも可能。
機能フラグフラグのオン / オフを管理する機能

非推奨フラグの指定、フラグへの追加属性、そして拡張機能のオプションがある。
AWS AppConfig アプリケーション設定の説明

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_IDAWSのアカウントID
M_AWS_REGIONAWSのリージョン
TF_S3_BUCKETTerraformのtfstateファイルを保存するS3バケット
TF_S3_KEYTerraformの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_TAGECRにアップロードされたコンテナイメージのイメージタグ。1-1の手順の時点では、未入力で問題ありません。
.env ファイルの説明

入力例は以下の通りです。

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との相性についても模索していければと思います。

AUTHOR
Yasuyuki Sato
Yasuyuki Sato
記事URLをコピーしました