当使用Node.js连接到S3时,我如何使在AWS Fargate容器中运行的代码承担IAM角色



我正在尝试使用IAM角色来控制对应用程序中S3的访问。然而,我并没有准备好所有的东西来完成这项工作。当在AWS中运行时,我的代码会抛出一个";缺少凭据"例外,所以很明显我错过了一步。

我的印象是,如果不指定凭据,SDK将默认使用容器的标识,但事实似乎并非如此。我认为我的代码是错误的,或者我创建的"假定角色"策略没有指定正确的主体。我只是没能从医生那里弄清楚我应该做什么。

我的另一个想法是,也许我需要创建一个单独的角色来访问S3存储桶,然后编写一些代码来承担这个角色,并在我的S3客户端中使用这些凭据。

如有任何帮助,我们将不胜感激。

我正在使用Terraform来建立我的基础设施,并在下面包含了相关摘录。在文章的最后,我包含了用于访问S3的Typescript代码。

当前配置

  1. 我已经为我的ECS Fargate任务定义了一个角色
resource "aws_iam_role" "ecs_task_execution_role" {
name = "ecsTaskExecutionRole"
assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role.json
}
  1. 我已经为此任务定义了"假定角色"策略
data "aws_iam_policy_document" "ecs_task_execution_role" {
version = "2012-10-17"
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["ecs-tasks.amazonaws.com"]
}
}
}
  1. 我定义了一个IAM策略,该策略管理对有问题的S3存储桶的访问:
resource "aws_iam_policy" "read_write_image_storage" {
name = "${var.environment}-read-write-image-storage"
description = "Allows read access to s3 bucket in the ${var.environment} environment"

policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Action = [
"s3:*"
],
Resource = [
aws_s3_bucket.image_storage.arn,
]
}]
})
}
  1. 我已将策略附加到运行容器的角色:
resource "aws_iam_role_policy_attachment" "read_write_image_storage" {
role = aws_iam_role.ecs_task_execution_role.name
policy_arn = aws_iam_policy.read_write_image_storage.arn
}
  1. 在与该任务相关的容器中运行的node.js代码中,我启动了一个默认的S3客户端,并尝试使用它来访问bucket:
const s3config = {
region: process.env.AWS_REGION,
};
const s3 = new S3(s3config);
export const putBlob = async (key: string, blob: Buffer) => {
// save buffer to an AWS S3 bucket
const params = {
Bucket: process.env.AWS_ATTACHMENT_STORAGE_BUCKETNAME,
Key: key,
Body: blob,
ContentType: "image/png",
};

try {
console.debug("Saving image to S3");
const result = await s3.upload(params).promise();
} catch(e) {
console.error(e.message) // MissingCredentials
throw 2
}
}
  1. 我已经定义了Fargate任务来使用步骤1中定义的角色
resource "aws_ecs_task_definition" "webapp" {
family                   = "webapp-task"
execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
network_mode             = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu                      = "256"
memory                   = "512"
container_definitions = jsonencode([
{
"name" : "MyContainerDefinition",
"image" : "MyContainerImage",
"cpu" : 256,
"memory" : 512,
"essential" : true,
"portMappings" : [
{
"containerPort" : 80,
"hostPort" : 80,
"protocol" : "tcp"
}
],
}
])
}```

您必须设置task_role_arn。这与execution_role_arn不同。

相关内容

  • 没有找到相关文章

最新更新