AWSECS

ECSの環境変数に機密データを安全に設定する

ECSを運用するときにDBパスワードなどの機密データ(秘密・秘匿情報、シークレット)を、どうやってコンテナ内に渡すか悩みどころだと思います。

例えばdotenvを利用した場合、機密データが記述された.envをおいそれとGitHubにコミットするのはリスクがあるため、コンテナへ.envをデプロイすることも難しくなると思います。

そこで機密データを管理するためのAWSサービスである Secrets Manager もしくは Systems Managerのパラメータストア を利用します。(使い分けはこちらのQiitaが参考になります)

今回はこの2つのサービスからECSコンテナの環境変数に機密データを埋め込んでみます。

スポンサーリンク

前提

ECS Execの有効化

手順の最後にコンテナに入って環境変数の確認を行うため、以下の記事を参考にしながらECS Execを有効化してください。(機密データの埋め込み自体に必要な設定というわけではないです)

ECS環境変数への機密データの設定手順

Secrets Managerでシークレットの作成

AWSマネジメントコンソールの画面上部検索窓 [ Secrets Manager ] で検索 → 当該サービスをクリック → 画面右上の[ 新しいシークレットを保存する ] をクリックします。

次の画面から以下のとおり設定します。明記してない項目はデフォルトのままでOKです。

項目名
シークレットのタイプその他のシークレットのタイプ
キーecs
from-secretsmanager
シークレットの名前demo

Systems Managerでパラメータの作成

AWSマネジメントコンソールの画面上部検索窓 [ Systems Manager ] で検索 → 当該サービスをクリック → 画面左ペイン アプリケーション管理の [ パラメータストア ] → 画面右上の [ パラメータの作成 ] をクリックします。

次の画面から以下のとおり設定します。明記してない項目はデフォルトのままでOKです。

項目名
名前/secrets/demo/ecs
タイプ安全な文字列
from-parameterstore

ECSのタスク実行ロールにIAMポリシーの追加

ECSのタスク実行ロールへ以下のIAMポリシーを付与します。

Secrets Manager と Systems Managerのパラメータストアで作成したリソースへの読み込みアクセスを許可しています。

{
    "Statement": [
        {
            "Action": [
                "ssm:GetParameters",
                "secretsmanager:GetSecretValue"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:ap-northeast-1:AWSアカウントID:parameter/secrets/demo/ecs",
                "arn:aws:secretsmanager:ap-northeast-1:AWSアカウントID:secret:demo-設定されたランダムな文字列"
            ]
        }
    ],
    "Version": "2012-10-17"
}

ECSのタスク定義に機密データの設定

AWSマネジメントコンソールの画面上部検索窓 [ ECS ] で検索 → 画面左ペイン [ タスク定義 ] → 当該タスク定義 → 最新リビジョン → [ 新しいリビジョンの作成 ] をクリックします。

環境変数を設定するコンテナをクリックし [ 環境 ] の [ 環境変数 ] を以下のとおり設定します。(新規にタスク定義を作成する場合も同様です)

キー
FROM_PARAMETERSTORE_ARNarn:aws:ssm:ap-northeast-1:AWSアカウントID:parameter/secrets/demo/ecs
FROM_PARAMETERSTORE_NAME/secrets/demo/ecs
FROM_SECRETSMANAGER_ARNarn:aws:secretsmanager:ap-northeast-1:AWSアカウントID:secret:demo-設定されたランダムな文字列
FROM_SECRETSMANAGER_ARN_KEYsecretsmanager:ap-northeast-1:AWSアカウントID:secret:demo-設定されたランダムな文字列:ecs::

SSMパラメータストアの指定はARNか、ECSと同じリージョンであれば名前のみの設定でもOKです。

シークレットマネージャーはARNを指定します。ただARNのみであるとJSON形式で値が取得されるため、ARNの最後に :キー:: とJSONの当該キーを指定することで、その値のみを取得できるようになります

注意点としてこちらに記載のとおり、キーの後ろにはversion-stageとversion-idを省略していることになるため最後にコロン2つ(::)をつけることを忘れないでください

忘れるとECS起動時に以下のエラーとなります。

ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secret from asm: service call has been retried 1 time(s): secrets manager: failed to retrieve secret from arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:demo-xxx:ecs: unexpected ARN format with parameters when trying to retrieve ASM secret

ECSコンテナ内の環境変数の確認

環境変数を設定したタスク定義で更新されたコンテナに対して、ECS Execを使ってenvコマンドを実行してみます。

以下のように環境変数に機密データが設定されていることが確認できます。

$ aws ecs list-tasks --cluster demo
{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:123456789012:task/demo/1b960xxxxx"
    ]
}
$
$ aws ecs execute-command  --cluster demo --task 1b960xxxxx --container demo --interactive --command env |grep FROM |sort
FROM_PARAMETERSTORE_ARN=from-parameterstore
FROM_PARAMETERSTORE_NAME=from-parameterstore
FROM_SECRETSMANAGER_ARN={"ecs":"from-secretsmanager"}
FROM_SECRETSMANAGER_ARN_KEY=from-secretsmanager
$

今回は以上です〜ノシ

参考

(`・ω・´)ノ アリガトウゴザイマス!!

Amazon ECS 機密データの指定
AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較
ECSでコンテナ環境変数をSecretManagerから取得する際にResourceInitializationErrorが発生したときの対処方法