はじめに
AWS SSMとDatadogの自動検出テンプレート変数を使って、Terraformやtask_definitionsにパスワードが平文表示されてしまう問題を解決したので記事にしました。
Datadog database monitoringの設定をしていて、Datadog AgentにRDSのユーザパスワードを渡す必要がありました。
AgentはECS上にコンテナとして立てていました。
そのため、task_definitionにDBの接続情報を書かなければなりません。
しかし、task_definitionsにパスワードをベタ書きすると、TerraformやAWSのECSコンソールからパスワードが平文で丸見え状態になってしまうので、セキュリティ的に好ましくありません。
そこで、今回の記事に記載している対応を取りました。
想定する読者
- Datadog Agentのパスワードが露出するのを避けたい方
- Datadogのテンプレート変数の使い方を知りたい方
この記事で得られること
- Terraform & ECSにおけるDatadog Agentへのパスワードの渡し方
- 自動検出テンプレート変数の使い方
解決策
以下の2つの手段を取り、今回の問題を解決しました。
- AWSのSSMにパスワードを保存し、datadog-agentコンテナの環境変数として読み込む
- 環境変数に設定されたパスワードを、テンプレート変数を使って動的に読み込む
AsIsとTobeのイメージ図は以下の通りです。
AsIs
ToBe
1つずつ解説していきます。
AWSのSSMにパスワードを保存。コンテナの環境変数に設定する。
Datadogの公式ドキュメントを読むと、Dockerの場合は以下のようにdatabase monitoringの設定をすると記載があります。
https://docs.datadoghq.com/database_monitoring/setup_mysql/aurora/?tab=docker#command-line
export DD_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export DD_AGENT_VERSION=7.36.1
docker run -e "DD_API_KEY=${DD_API_KEY}" \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-l com.datadoghq.ad.check_names='["mysql"]' \
-l com.datadoghq.ad.init_configs='[{}]' \
-l com.datadoghq.ad.instances='[{
"dbm": true,
"host": "<AWS_INSTANCE_ENDPOINT>",
"port": 3306,
"username": "datadog",
"password": "<UNIQUEPASSWORD>"
}]' \
gcr.io/datadoghq/agent:${DD_AGENT_VERSION}
これを、task_definitionsで定義すると「com.datadoghq.ad.instances」の部分は、以下のように設定出来ます。
...
},
"dockerLabels": {
"com.datadoghq.ad.check_names": "[\"mysql\"]",
"com.datadoghq.ad.init_configs": "[{}]",
"com.datadoghq.ad.instances": "[{\"dbm\": true, \"host\": \"※rds_endpoint※\", \"port\": 3306,
\"username\": \"datadog\", \"password\": \"hogehoge(rds パスワード)\"}]"
}
...
この場合、Terraformのコード上はpasswordが平文の状態で管理されてしまいます。
TerraformコードがGitHubで管理されているとした場合、このままリポジトリにPushしたくないです。
そこで、passwordをAWS SSMに登録し、TerraformからはSSMのパスを参照します。
AWS Systems Managerのパラメータストアから、パラメータを作成します。
例えばこんな感じです。
秘匿情報なので「安全な文字列」を選択します。
なお、ECSを実行するロールが、SSMに登録されたSecretをDecryptする権限も必要となります。
権限不足の場合、以下のドキュメントを参考に必要な権限を付与します。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/specifying-sensitive-data-parameters.html
自動検出テンプレート変数を使って、コンテナに設定された環境変数を動的に読み込む
自動検出テンプレート変数はDatadog Agentの機能です。
自動検出テンプレート変数として記述されている変数は、エージェントが動的に値を読み替えてくれます。
詳細は以下のドキュメントをご覧ください。
https://docs.datadoghq.com/agent/guide/template_variables/
今回は以下の記述方法に従うことで、datadog-agentから見た環境変数の値(password)を動的に読み替えてもらいます。
「”%%env_<ENV_VAR>%%”」
イメージとしてはこんな感じです。
これにより、コードやコンソール上からはパスワードが露出することなく、datadogエージェントはpasswordを読み取れるようになります。
先程の設定に対しては、以下のようにtask_definitionを記入します。
// Set as container environment variable
"secrets": [
{
"name": "PASSWORD",
"valueFrom": "/db/password/datadog"
}
],
"dockerLabels": {
"com.datadoghq.ad.check_names": "[\"mysql\"]",
"com.datadoghq.ad.init_configs": "[{}]",
"com.datadoghq.ad.instances": "[{\"dbm\": true, \"host\": \"※rds_endpoint※\", \"port\": 3306, \"username\": \"datadog\", \"password\": \"%%env_PASSWORD%%\"}]"
}
ここまで設定できたら、あとはdatadog-agentを起動するだけです。
おわりに
今回は、datadog-agentで秘匿情報を扱う際に、自動検出テンプレート変数を用いる方法を紹介しました。
Datadog Database Monitoringを導入するにあたってぶつかる問題だと思います。
皆様の参考になれば嬉しいです。
Datadog Database Monitoringを試してみたい場合は、以下の記事もご覧ください。