目前我们正在运行 4 个命令:
下面是 Jenkins Docker 容器中的两个 AWS CLI 命令:
sh 'aws cloudformation package ...'
s3Upload()
在 docker 容器中的两个 aws cli 命令下面:
aws s3 cp source dest
aws cloudformation deploy
要在 docker 容器中运行上述 4 个命令,aws cli
从 docker host( EC2 ( 派生访问权限,该主机承担具有具有权限的策略的角色(访问 s3 和创建/更新云形成堆栈(。
但这种解决方案的问题是,
我们必须将此角色(例如xrole
(分配给在每个测试环境中运行的每个EC2。有 3-4 个测试环境。
在内部,aws 会创建一个临时用户,因为aws::sts::{account Id}::assumerole/xrole/i-112223344
个以上的命令代表该用户运行。
更好的解决方案是创建一个用户并为此分配相同的角色(xrole
(,并运行与此用户相同的 4 个命令。
但
1( 创建此类用户的过程是什么?因为它必须假设xrole
...
2(如何与此用户一起运行上述4个命令?
最佳实践是在使用 EC2 实例时使用角色,而不是用户。仅当您需要向在 AWS 环境(本地(之外的计算机上运行的应用程序授予权限时,才需要用户。即便如此,最佳做法仍然是授予此用户权限,使其仅代入授予必要权限的角色。
如果您从容器内运行所有命令,并且想要向容器而不是整个 EC2 实例授予权限,那么您可以做的是使用 ECS 服务而不是普通 EC2 实例。
将 EC2 启动类型与 ECS 配合使用时,您对 EC2 实例具有相同的控制权,但不同之处在于您可以将角色附加到特定任务(容器(而不是整个 EC2 实例。通过执行此操作,您可以在同一 EC2 实例上运行多个不同的任务(容器(,而每个任务(容器(仅具有其所需的权限。因此,如果您的某个容器需要将数据上传到 S3,您可以创建必要的角色,在任务定义中指定角色,并且只有该特定任务才具有这些权限。其他任务和 EC2 实例本身都无法将对象上传到 S3。
此外,如果您为任务指定awsvpc
联网模式,则每个任务都将获得自己的 ENI,这意味着您可以为每个任务单独指定安全组,即使它们在同一 EC2 实例上运行也是如此。
下面是使用存储在 ECR 中的 docker 映像和名为AmazonECSTaskS3BucketRole
的角色进行任务定义的示例。
{
"containerDefinitions": [
{
"name": "sample-app",
"image": "123456789012.dkr.ecr.us-west-2.amazonaws.com/aws-nodejs-sample:v1",
"memory": 200,
"cpu": 10,
"essential": true
}
],
"family": "example_task_3",
"taskRoleArn": "arn:aws:iam::123456789012:role/AmazonECSTaskS3BucketRole"
}
以下是任务定义的文档
在同一主机上运行的应用程序通过实例配置文件共享分配给主机的权限。如果出于安全要求,您希望隔离在同一实例上运行的不同应用程序,最好在单独的实例上启动它们。 不建议使用每个应用程序的访问密钥,因为访问密钥是长期凭据,并且在共享主机时可以轻松检索它们。
可以按照上一个答案的建议将 IAM 角色分配给 ECS 任务。但是,不会阻止在容器实例上运行的容器访问通过实例配置文件提供的凭证。因此,建议为容器实例角色分配最低权限。
如果您在 awsvpc 网络模式下运行任务,则可以配置 ECS 代理以防止任务访问实例元数据。您只需设置代理配置变量ECS_AWSVPC_BLOCK_IMDS=true并重新启动代理。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html