无法从Fargate容器中访问S3存储桶(错误请求且无法找到凭据)

van*_*ane 5 amazon-s3 python-3.x amazon-iam boto3 aws-fargate

我创建了一个私有s3存储桶和一个Fargate集群,其中包含一个简单的任务,尝试使用python 3和从该存储桶中进行读取boto3。我已经在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/*"]
  }
}
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

data "aws_iam_policy_document" "access_s3" {
  statement {
    effect    = "Allow"
    actions   = ["s3:*"]
    resources = ["arn:aws:s3:::*"]
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试的最后一个是构建策略:

resource "aws_iam_role_policy_attachment" "access_s3" {
  role       = "${aws_iam_role.ecstasks.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
Run Code Online (Sandbox Code Playgroud)

桶的定义非常简单:

resource "aws_s3_bucket" "bucket" {
  bucket = "${var.bucket_name}"
  acl    = "private"
  region = "${var.region}"
}
Run Code Online (Sandbox Code Playgroud)

用于访问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()
Run Code Online (Sandbox Code Playgroud)

无论我做什么,我都无法使用boto3Fargate容器任务中访问AWS资源。我能够与访问相同的S3存储boto3上的EC2实例,而无需提供任何凭证,只有使用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错误是我实际上遇到的错误,需要解决。我检查了容器内的环境变量,该AWS_CONTAINER_CREDENTIALS_RELATIVE_URI值由Fargate设置。

小智 18

我在这个问题上苦苦挣扎,并且不断AWS_CONTAINER_CREDENTIALS_RELATIVE_URI错误地设置为None,直到我当前的任务执行角色之外添加了一个自定义任务角色

1)任务执行角色负责访问 ECR 中的容器并授予运行任务本身的访问权限,而2)任务角色负责您的 docker 容器向其他授权的 AWS 服务发出 API 请求。

1) 对于我的任务执行角色,我使用AmazonECSTaskExecutionRolePolicy以下 JSON;

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

2)我终于摆脱了NoCredentialsError: Unable to locate credentials当我在任务执行角色之外添加了一个任务角色时,比如负责从某个bucket中读取;

{
    "Version": "2012-10-17",
    "Statement": [
           {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket_name/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

总之; 确保两者都有一个角色,用于1) executionRoleArn用于访问以运行任务和2) taskRoleArn用于访问以向任务定义中设置的授权 AWS 服务发出 API 请求。


小智 -4

Boto3 有一个凭证查找路径:https://boto3.readthedocs.io/en/latest/guide/configuration.html。当您使用 AWS 提供的映像创建 EC2 实例时,该实例会预安装 aws 命令和其他 AWS 凭证环境变量。然而,Fargate 只是一个容器。您需要手动将 AWS 凭证注入到容器中。一种快速解决方案是将 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 添加到 fargate 容器。

  • 这是不正确的。使用 IAM 角色时,容器内部甚至容器外部都不需要 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。我实际上已经找到了更多关于此的信息,并且需要更新我的问题。Fargate 实例在幕后代表您注入一个名为“AWS_CONTAINER_CREDENTIALS_RELATIVE_URI”的环境变量,然后 boto 使用该变量进行 AWS API 调用以确定 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。因此,这些不需要提前完成,而是由 AWS SDK 和 Fargate 自动完成 (8认同)