Help us understand the problem. What is going on with this article?

ECSのコンテナ定義からパラメータストアが参照できるようになった!

  • 2018/12/18 Fargate対応を追記
  • 2019/1/23 Secrets ManagerのSecrets参照について補足を追記

はじめに

ECSのコンテナ定義を眺めていたところ見慣れない文言が。

image.png

'valueFrom'フィールドを使用して、AWS Systems ManagerのパラメータストアキーまたはARNを指定することもできます。 ECSは実行時にコンテナに値を注入します。

やったぜ!

ドキュメントも更新されていました。

Specifying Sensitive Data
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html

というわけで、もしDBパスワードのようなセンシティブ情報を環境変数に
直接入れてしまっている場合は、パラメータストアから参照するようにしましょう。約束です。

注意点としては、2018/11/16時点でFargateには対応していません。
2018/12/18 追記
Platform Version 1.3.0 で Fargateにも対応しました。
ただしSecrets Managerの参照はまだ対応していません。
https://aws.amazon.com/jp/about-aws/whats-new/2018/12/aws-fargate-platform-version-1-3-adds-secrets-support/

やってみる

ECS コンテナエージェントのアップデート

コンテナエージェントのバージョンが1.22.0以降である必要があります。
既存のコンテナインスタンスで実行するにはエージェントの更新が必要です。

image.png

現在のコンテナインスタンスが1.21.0を実行していましたので以下の手順を参考に更新を行います。
Updating the Amazon ECS Container Agent
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html

LinuxのECS最適化AMIであればコンソールまたはAWS CLIから更新が可能です。
コンソールの場合は、コンテナインスタンスの詳細ページからエージェントの更新を選択します。

image.png

AWS CLIの場合は以下のコマンドです。

$ aws ecs update-container-agent --cluster cluster_name --container-instance container_instance_id

パラメータストアの作成

ECSから参照させるパラメータストアを作成します。
ここでは以下のように設定しています。

image.png

名前: ecs-db-password
タイプ: 安全な文字列
KMSの主要なソース: 現在のアカウント
KMSキーID: alias/aws/ssm
値: password

タスク実行ロールへの権限追加

ECSがパラメータストアを参照できるようにするため、
タスク実行ロールに以下のような権限を追加します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameters",
        "secretsmanager:GetSecretValue", ★オプション
        "kms:Decrypt" ★オプション
      ],
      "Resource": [
        "arn:aws:ssm:<region>:<aws_account_id>:parameter/ecs-db-password",
        "arn:aws:secretsmanager:<region>:<aws_account_id>:secret:<secret_name>", ★オプション
        "arn:aws:kms:<region>:<aws_account_id>:key:<key_id>" ★オプション
      ]
    }
  ]
}

secretsmanager:GetSecretValue および kms:Decryptはオプションです。
secretsmanager:GetSecretValue: パラメータストアから更にSecrets Managerを参照させる場合のみ必要です。
kms:Decrypt: カスタムKMSキーを使用する場合のみ必要です。
今回はどちらも使用していません。

以下のようにインラインポリシーで追加しました。

image.png

コンテナ定義の変更

タスク定義で新しいリビジョンを作成し、コンテナ定義を編集します。
環境変数で任意のキーを入力し、ValueFromを選択します。値にはパラメータ名を入力します。
異なるリージョンのパラメータストアを参照する場合はARNでの入力が必須です。

image.png

JSONで直接タスク定義を編集する場合には、containerDefinitionsに以下のように追加します。

    "containerDefinitions": [
~~省略
            "secrets": [
                {
                    "name": "DB_PASSWORD",
                    "valueFrom": "ecs-db-password"
                }
            ],
~~以下略

動作確認

後は通常どおりにサービス、タスクを起動します。
タスク起動後、コンテナに定義されている環境変数を確認すると、
パラメータストアの値が設定されていることが確認できます。

# docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' 01dbaed2e060
AWS_EXECUTION_ENV=AWS_ECS_EC2
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/xxxxxxxxxxxxxxxxxxx
ECS_CONTAINER_METADATA_URI=http://169.254.170.2/v3/xxxxxxxxxxxxxxxxxxxxxxxxxx
DB_PASSWORD=password ★パラメータストアの値が設定されている
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
APACHE_RUN_USER=www-data
APACHE_RUN_GROUP=www-data
APACHE_LOG_DIR=/var/log/apache2

Secrets Managerの値を参照させる場合

前述した通り、パラメータストア経由でSecrets Managerの値を参照させることができます。

Secrets Manager シークレットの作成

ここでは以下の通りRDSデータベースの認証情報を作成しました。
確認用のため、自動ローテーションは無効にしています。
ユーザー名: rdsuser
パスワード: rdspassword
暗号化キーを選択: DefaultEncryptionKey
データベースを選択: 任意のDBインスタンス
シークレット名: dev/aurora/secret

image.png

タスク実行ロールへの権限追加

secretsmanager:GetSecretValue を追加で設定します。

Referencing AWS Secrets Manager Secrets from Parameter Store Parameters
https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-ps-secretsmanager.html
ここでは以下のように設定しています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameters",
        "secretsmanager:GetSecretValue"
      ],
      "Resource": [
        "arn:aws:ssm:<region>:<aws_account_id>:parameter:/aws/reference/secretsmanager/dev/arurora/secret",
        "arn:aws:secretsmanager:<region>:<aws_account_id>:secret:dev/aurora/secret",
      ]
    }
  ]
}

タスク定義の作成

Secrets Managerのシークレットを参照する場合、パラメータ名は/aws/reference/secretsmanager/
で始まる必要があります。

2019/1/23追記
ECS側のアップデートにより上記のような名称にしなくとも、直接Secrets Managerを
参照できるようになったようです。

"containerDefinitions": [
    {
        "secrets": [
            {
                "name": "environment_variable_name",
                "valueFrom": "arn:aws:ssm:region:aws_account_id:parameter/parameter_name"
            }
        ]
    }
]

Specifying Sensitive Data
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html

以上です。
参考になれば幸いです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away