如何在节点 AWS 开发工具包代码中使用 AWS ECS 任务角色

Posted

技术标签:

【中文标题】如何在节点 AWS 开发工具包代码中使用 AWS ECS 任务角色【英文标题】:How to use AWS ECS Task Role in Node AWS SDK code 【发布时间】:2019-02-22 19:29:11 【问题描述】:

使用 AWS Node SDK 的代码似乎无法获得 ECS 任务的角色权限。

如果我在 EC2 ECS 实例上运行代码,代码似乎继承了实例上的角色,而不是任务。

如果我在 Fargate 上运行代码,代码不会获得任何权限。

相比之下,在实例中运行的任何 bash 脚本似乎都具有适当的权限。

确实,the documentation 并没有提到这是 node sdk 的一个选项,只是:

    从 Amazon EC2 的 IAM 角色加载(如果在 EC2 上运行), 从共享凭证文件 (~/.aws/credentials) 加载, 从环境变量加载, 从磁盘上的 JSON 文件加载, 在您的应用程序中硬编码

有没有办法让你的节点代码获得ECS任务的权限?

这似乎是将权限传递给您的代码的合乎逻辑的方式。它与在实例上运行的代码完美配合。

我能想到的唯一解决方法是为每个 ECS 服务创建一个 IAM 用户,并在任务定义中将 API Key/Secret 作为环境变量传递。但是,这似乎不太安全,因为任何有权访问任务定义的人都可以以纯文本形式看到它。

【问题讨论】:

你是怎么创建客户端的,你用的是什么功能? @titogeo 只是实例化没有参数的客户端,应该使用凭证链解析器 docs.aws.amazon.com/AmazonECS/latest/developerguide/…希望你关注这个 您能否编辑问题以包括任务的aws ecs describe-task-definition 的输出以及您的任务所承担角色的aws iam get-role 的输出? AWS SDK 将透明地使用 ECS 任务角色,只要这些角色和您的 ECS 代理配置正确(或者在使用 Fargate 时自动配置),所以我猜这与您的任务或 IAM 角色配置错误/缺失有关。跨度> @ydaetskcoR 感谢您对此进行调查。 task definition 和 role 按要求提供。 【参考方案1】:

您的问题缺少很多关于如何设置 ECS 集群的详细信息,而且我不确定问题是针对 ECS 还是专门针对 Fargate。

确保您使用的是最新版本的 SDK。 javascript 支持 ECS 和 Fargate 任务凭证。

ECS 上的凭据经常存在混淆。有分配给集群 EC2 实例的 IAM 角色和分配给 ECS 任务的 IAM 角色。

最常见的问题是没有在 ECS 任务角色上设置“信任关系”。选择您的 IAM 角色,然后选择“信任关系”选项卡,并确保它看起来像这样:


  "Version": "2012-10-17",
  "Statement": [
    
      "Sid": "",
      "Effect": "Allow",
      "Principal": 
        "Service": "ecs-tasks.amazonaws.com"
      ,
      "Action": "sts:AssumeRole"
    
  ]

除了运行任务和服务所需的标准 Amazon ECS 权限外,IAM 用户还需要iam:PassRole 权限才能将 IAM 角色用于任务。

接下来验证您是否在任务定义中使用 IAM 角色。在任务角色字段中指定正确的 IAM 角色 ARN。请注意,这与任务执行角色不同(它允许容器拉取图像并发布日志)。

接下来确保您的 ECS 实例使用的是最新版本的 ECS 代理。代理版本列在右侧“代理版本”列下的“ECS 实例”选项卡上。当前版本是1.20.3

您是否使用 ECS 优化的 AMI?如果没有,请将--net=host 添加到启动代理的docker run 命令中。查看此link 了解更多信息。

【讨论】:

我可以确认我拥有正确的信任关系和iam:PassRole 权限。这个问题专门针对Fargate。相同的角色在 EC2 实例上运行良好。网络模式是awsvpc,据我所知,我无法控制Fargate中docker run的参数。 经过仔细检查,我可以看到AWS JS SDK 调用以Error: connect EINVAL 169.254.169.254:80 - Local (0.0.0.0:0) 失败。我认为这是 AWS 元数据服务,所以我假设 AWS JS SDK 正在尝试获取凭证并失败。如前所述,在具有完全相同设置的同一容器中运行的 bash 脚本可以完美地使用任务角色凭据。 PS:抱歉回复慢。赏金已过期,但这对我们来说是一个非常重要的问题,我很高兴开设一个新的、更大的。 今天下班后我会再次调查您的问题。这是一个元数据访问问题,现在我知道问题出在 Fargate 上应该很容易解决。 这太奇怪了。我的启动命令首先运行一个从 S3 获取配置文件的 bash 脚本,然后运行 ​​node.js。 "start": "/var/get-config.sh && node app.js"。我想知道那里是否正在发生某些事情,因此该节点没有获得某些环境变量。 get-config.sh 中的任何代码都具有所有任务权限,可以调用任何 aws 服务。我在169.254.170.2/v2/metadata 中添加了一个卷曲,它工作得很好。【参考方案2】:

我想通了。这很奇怪。

一位同事认为如果我们在proccess.env 上拨打Object.freeze 会“更安全”。这以某种方式干扰了 SDK 访问凭据的能力。

删除了那个“改进”,一切又好了。我认为教训是“不要惹process.env”。

【讨论】:

以上是关于如何在节点 AWS 开发工具包代码中使用 AWS ECS 任务角色的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS Lambda 中运行 AWS SDK Opsworks 命令?

如何使用 AWS 开发工具包进行身份验证

如何在使用Java AWS开发工具包创建AWS EC2时提供实例名称

如何使用适用于 DynamoDb 的 AWS Rust 开发工具包编写惯用的 Rust 错误处理?

如何承诺 AWS JavaScript 开发工具包?

如何在 Elastic Beanstalk 上安装 AWS PHP 开发工具包? [关闭]