Closed13
ECSタスクの環境変数をParameterStoreで管理する
paramterstore内の値を使用することで、タスク定義・コンテナ定義に機密情報を記載せずにすむ
パラメータに値を格納し、それをTerraformでひっぱってくる形で試してみます
paramter storeとsecrets managerはどちらを使用する?
こちらの記事を大変参考にさせていただきました。
無料で使用したいのでparamterstoreを使う
手動で試す
parameter store
secure stringで1つ作成します
タスク定義
- Key:環境変数名
- Value type:ValueFrom
- Value:パラメータストアの名前かArn
パラメータストアのためのIAMポリシー
こちらに記載があります
タスク実行ロールに必要です。タスクロールではないので注意
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters"
],
"Resource": [
"arn:aws:ssm:<Region>:<AccountID>:parameter/test-secret-string"
]
}
]
}
ポリシーが足りないと以下のようなエラーがタスクから吐かれます
ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secrets from ssm: service call has been retried 1 time(s):
確認
ECSEXECして確認します
SecretEnv
という環境変数があり、中身がパラメータストアに設定した値と同じであればよいです
root@ip-10-0-15-247:/# env | grep SecretEnv
SecretEnv="Today's date is June 10th, 2023."
考慮点
いくつか考慮点があります。
- 稼働中のコンテナに環境変数は渡せないため、新しくデプロイする必要がある
- Fargateでパラメータストアを使用する場合、Fargateの1.3.0以上を使用する必要がある
- プライベートサブネットにECSタスクが存在する場合、VPCエンドポイント経由でSSMエンドポイントへアクセスする必要がある
Terraform化
メモを残していきます
TerraformでAWSアカウントとリージョンを取得する
parameterstoreはTerraformで管理しないように考えていたため、リージョンとIDを取得しました
それぞれ以下の様に取得可能です
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
data "aws_iam_policy_document" "GetParameterStore" {
statement {
effect = "Allow"
actions = [
"ssm:GetParameters",
]
resources = [
"arn:aws:ssm:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:parameter/test-secret-string",
]
}
}
パラメータストアのArnに使用しています。
parameter store設定
awscliでやります
設定
$ aws ssm put-parameter \
--name "/test/secret-string" \
--description "test securestring" \
--value "Today's date is June 10th, 2023." \
--type SecureString
確認
$ aws ssm get-parameters \
> --names "/test/secret-string" \
> --with-decryption \
> --query Parameters[].Value \
> --output text
Today's date is June 10th, 2023.
Terraformのdataでparameterstoreを引っ張ってくる
with_decryption
でsecurestringを復号してくれます。
デフォルトでtrueなのですが、plaintextと区別する上でも有益だと思うので明示しておきます
data "aws_ssm_parameter" "securestring" {
name = "/test/secret-string"
with_decryption = "true"
}
data "aws_iam_policy_document" "GetParameterStore" {
statement {
effect = "Allow"
actions = [
"ssm:GetParameters",
]
resources = [
"${data.aws_ssm_parameter.securestring.arn}",
]
}
}
取得出来る属性はこちらを参照
(さっきのこれ不要だったな...)
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
引っ張ってきたparameter storeをcontainer definitionでも使う
templatefile
を使っているので、こんな感じでcontainer_definitions.jsonに運びます
secrets
でパラメータストアを扱えます
resource "aws_ecs_task_definition" "app" {
container_definitions = templatefile("../../modules/app/container_definitions.json",
{
securestring = data.aws_ssm_parameter.securestring.arn
}
)
container_definition.json
[
{
// 略
"secrets": [
{
"name": "SecretEnv",
"valueFrom": "${securestring}"
}
],
ECSExec用IAMロール、ポリシー
これが無いとECSExec出来ません。
これはタスクロールなので混同することがないようにします
## Taskrole
data "aws_iam_policy_document" "ECSExec" {
statement {
effect = "Allow"
actions = [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
]
resources = ["*"]
}
}
resource "aws_iam_policy" "ECSExec" {
name = "ECSExec"
path = "/"
policy = data.aws_iam_policy_document.ECSExec.json
}
resource "aws_iam_role" "task_role" {
name = "${var.system_name}_${var.environment}_task_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { Service = "ecs-tasks.amazonaws.com" }
Action = "sts:AssumeRole"
}
]
})
managed_policy_arns = [
"${aws_iam_policy.ECSExec.arn}"
]
}
動作確認
terraform init,plan,apply
を実行後、ECSExecで環境変数を確認できればOKです
$ aws ecs execute-command --cluster <cluster> \
--task <task arn> \
--container nginx \
--interactive \
--command "/bin/bash"
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-04b9bc781d0f1939a
root@ip-10-10-1-158:/#
root@ip-10-10-1-158:/# env | grep SecretEnv
SecretEnv=Today's date is June 10th, 2023.
このスクラップは2023/06/10にクローズされました