我创建了一个私有的s3存储桶和一个fargate集群,其中包含一个简单的任务,试图使用 python 3
和 boto3
从该存储桶中读取数据。我在两个不同的docker镜像上尝试了这个任务,在其中一个镜像上,boto返回ClientError
,提示HeadObject Bad request (400)
,而在另一个镜像上,则返回NoCredentialsError: Unable to locate credentials
。
这两个镜像唯一真正的区别是,一个报告错误的镜像是正常运行的,而另一个是通过ssh手动运行到任务容器中。因此,我不确定为什么一个镜像会显示“bad request”,而另一个则是“unable to locate credentials”。
我已经尝试了几个不同的IAM策略,包括(terraform
)以下策略:
data "aws_iam_policy_document" "access_s3" {
statement {
effect = "Allow"
actions = ["s3:ListBucket"]
resources = ["arn:aws:s3:::bucket_name"]
}
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectTagging",
"s3:GetObjectVersionTagging",
]
resources = ["arn:aws:s3:::bucket_name/*"]
}
}
第二次尝试:data "aws_iam_policy_document" "access_s3" {
statement {
effect = "Allow"
actions = ["s3:*"]
resources = ["arn:aws:s3:::*"]
}
}
我尝试的最后一个是内置的策略:
resource "aws_iam_role_policy_attachment" "access_s3" {
role = "${aws_iam_role.ecstasks.name}"
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
桶的定义非常简单:resource "aws_s3_bucket" "bucket" {
bucket = "${var.bucket_name}"
acl = "private"
region = "${var.region}"
}
访问S3存储桶所使用的代码:
try:
s3 = boto3.client('s3')
tags = s3.head_object(Bucket='bucket_name', Key='filename')
print(tags['ResponseMetadata']['HTTPHeaders']['etag'])
except ClientError:
traceback.print_exc()
无论我做什么,我都无法在Fargate容器任务中使用boto3来访问AWS资源。我能够在EC2实例上使用boto3访问同一个S3存储桶,而不需要提供任何凭证,只使用IAM角色/策略即可。我做错了什么?从Fargate容器以相同的方式访问AWS资源是否不可能?忘记提到我正在将IAM角色分配给任务定义执行策略和任务策略。
更新:事实证明,我所遇到的“找不到凭证”错误是一个误导。我无法获得凭证的原因是我的直接ssh会话没有设置AWS_CONTAINER_CREDENTIALS_RELATIVE_URI环境变量。
AWS Fargate将代表您注入名为AWS_CONTAINER_CREDENTIALS_RELATIVE_URI的环境变量,其中包含boto用于获取API访问凭证的URL。因此,我实际上遇到并需要帮助解决的是“Bad request”错误。我检查了容器内的环境变量,并且Fargate已经设置了AWS_CONTAINER_CREDENTIALS_RELATIVE_URI值。