如何更改我的 IAM ECSTaskExecutionRole 以授予我从 Systems Manager - Parameter Store 获取参数的权限?

How do I change my IAM ECSTaskExecutionRole to give me permission to get parameters from Systems Manager - Parameter Store?

我想将秘密或敏感信息安全地传递到 Amazon Elastic Container Service (Amazon ECS) 任务中的容器。我在 ECS 上有一个 Docker 容器和一个从 Systems Parameter Store 中提取环境变量的任务定义。但是,当我 运行 我在 ECS 中的任务时,当我尝试 运行 我的容器时收到以下错误消息。

STOPPED (Fetching secret data from SSM Parameter Store in us-east-2: AccessDeniedException: User: arn:was:sts::<my_account_id>:assumed-role/ecsTaskExecutionRole/2c0dfb5f086da28abc753c07b6de728 is not authorized to perform: ssm:GetParameters on resource: arn:was:ssm:us-east-2:<my_account_id>:parameter/<MY_PARAMETER> status code: 400, request id: <request_id>

https://gyazo.com/5a3dd8c06da3614d19b8bc725e572f2c

我关注了这篇关于在 ECS 任务中将敏感信息传递给容器的文章。

https://aws.amazon.com/premiumsupport/knowledge-center/ecs-data-security-container-task/

根据这篇文章,我进入了 IAM 并将以下内联策略添加到我的 ecsTaskExecutionRole 中。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "ssm:GetParameters"
            ],
            "Resource": [
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:SLACK_API_TOKEN*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_USER*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_PASSWORD*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_HOST*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_DATABASE_NAME*",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/SLACK_API_TOKEN",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_USER",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_PASSWORD",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_HOST",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_DATABASE_NAME",
            ]
        }
    ]
}

我在相同的 ecsTaskExecutionRole 下也有一个看起来像这样的 AWS 托管策略。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

ecsTaskExecutionRole 的完整 IAM 角色如下所示:

https://gyazo.com/b28a4ae1beca4db31228298767685fe2

Parameter Store 中的密钥存储为秘密字符串。我没有使用自己的密钥,而是使用我帐户的默认密钥。

我通过查看

了解了这一点

由于我使用 AWS 的默认 KMS 对 SSM 中的参数进行加密,因此我需要在我的 ecsExecuteTask 角色的内联策略中授予 KMS 权限。我还需要去掉写着“Sid”的那一行:“VisualEditor0”。我不确定那是怎么进来的。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "ssm:GetParameters",
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:SLACK_API_TOKEN*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_USER*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_PASSWORD*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_HOST*",
                "arn:aws:secretsmanager:<my_region>:<my_account_id>:secret:DB_DATABASE_NAME*",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/SLACK_API_TOKEN",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_USER",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_PASSWORD",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_HOST",
                "arn:aws:ssm:<my_region>:<my_account_id>:parameter/DB_DATABASE_NAME",
                "arn:aws:km:<my_region>:<my_account_id>:key/<my_key>"
            ]
        }
    ]
}

这完全解决了错误。

将这些敏感信息传递给容器的另一种方法是在容器启动时通过环境变量注入它们。

在任务定义中定义 secrets 键,并在 valueFrom 中提供这些变量的 arn。请参阅以下示例:

{
  "volumes": [],
  "family": "example-tasks",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/example-tasks",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "portMappings": [
        {
          "hostPort": 5000,
          "protocol": "tcp",
          "containerPort": 5000
        }
      ],
      "cpu": 0,
      "memoryReservation": 512,
      "volumesFrom": [],
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/example:latest",
      "name": "example-container",
      "environmentFiles": [
        {
            "value": "arn:aws:s3:::s3_example_bucket/s3_example.env",
            "type": "s3"
        }
      ],
      "secrets": [
        {
          "name": "SECRET_1",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/SECRET_1"
        },
        {
          "name": "SECRET_2",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/SECRET_2"
        }
      ]
    }
  ]
}