我使用 python 3
和 boto3
尝试从该存储桶中读取一个简单的任务,创建了一个私有 s3 存储桶和一个 fargate 集群。我已经在 2 个不同的 docker 图像上尝试过这个,在一个上我得到一个 ClientError
从 boto 说 HeadObject Bad request (400)
另一个我得到 NoCredentialsError: Unable to locate credentials
图像中唯一真正不同的是,一个说错误请求正在正常运行,另一个是由我通过 ssh 手动运行到任务容器。所以我不确定为什么一张图片说“请求错误”而另一张图片说“无法找到凭据”。
我尝试了几种不同的 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()
无论我做什么,我都无法使用 boto3
从 Fargate
容器任务中访问 AWS 资源。我可以在 EC2
boto3
同一个 s3 存储桶,无需提供任何类型的凭据,仅使用 IAM 角色/策略。我究竟做错了什么?从 Fargate 容器以同样的方式访问 AWS 资源是不可能的吗?
忘记提及我正在将 IAM 角色分配给任务定义执行策略和任务策略。
更新:事实证明,我遇到的 unable to find credentials
错误是一条红鲱鱼。我无法获得凭据的原因是因为我的直接 ssh 会话没有设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
环境变量。
AWS Fargate 将代表您注入一个名为 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
的环境变量,其中包含 boto 应该用于获取 API 访问凭证的 url。所以 Bad request
错误是我实际遇到的错误,需要帮助解决。我检查了容器内的环境变量,Fargate 正在设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
值。
原文由 vane 发布,翻译遵循 CC BY-SA 4.0 许可协议
我在这个问题上纠结了很久,并且经常将
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
错误地设置为None
,直到我在当前 任务执行角色之外添加了自定义任务角色 。1) 任务执行角色负责访问 ECR 中的容器并授予运行任务本身的权限,而 2) 任务角色负责您的 docker 容器向其他授权 AWS 服务发出 API 请求。
AmazonECSTaskExecutionRolePolicy
和以下 JSON;2)我终于摆脱了
NoCredentialsError: Unable to locate credentials
,除了任务执行角色外,我还添加了一个任务角色,例如负责从某个桶中读取;总之;确保两者都具有以下角色: 1) executionRoleArn 用于访问以运行任务, 2) taskRoleArn 用于访问以向任务定义中设置的授权 AWS 服务发出 API 请求。