_python 3
_と_boto3
_を使用してバケットから読み取ろうとする単純なタスクで、プライベートs3バケットとファーゲートクラスターを作成しました。私はこれを2つの異なるDockerイメージで試しました。1つはbotoからClientError
を取得してHeadObject Bad request (400)
と言い、もう1つは_NoCredentialsError: Unable to locate credentials
_を取得しています。
画像の唯一の本当の違いは、悪いリクエストが正常に実行されていることと、タスクコンテナーへのsshを介して私が手動で実行していることです。そのため、1つの画像が「不正なリクエスト」であり、もう1つの画像が「資格情報を見つけることができない」という理由がわかりません。
以下のポリシー(terraform
)を含むいくつかの異なるIAMポリシーを試しました。
_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/*"]
}
}
_
2回目の試行:
_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リソースにアクセスできません。 _boto3
_インスタンスで_EC2
_を使用して同じ種類のs3バケットにアクセスできますが、いかなる認証情報も提供せず、IAMロール/ポリシーのみを使用します。何が悪いのですか? Fargateコンテナーから同じ方法でAWSリソースにアクセスすることはできませんか?
IAMロールをタスク定義実行ポリシーとタスクポリシーに割り当てていることを説明するのを忘れていました。
[〜#〜] update [〜#〜]:私が抱えていた_unable to find credentials
_エラーは、赤いニシンであることがわかりました。資格情報を取得できなかったのは、直接のsshセッションで_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
_環境変数が設定されていなかったためです。
AWS Fargateは、APIアクセス認証情報を取得するためにbotoが使用するURLを含む_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
_という名前の環境変数を注入します。したがって、_Bad request
_エラーは実際に発生しているエラーであり、解決の助けが必要です。コンテナ内の環境変数を確認しましたが、_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
_の値はFargateによって設定されています。
私はこの問題でかなり苦労し、常にAWS_CONTAINER_CREDENTIALS_RELATIVE_URI
現在のタスク実行ロールにカスタムタスクロール追加を追加するまで、誤ってNone
に設定しました。
1)タスク実行ロールはECR内のコンテナーへのアクセス権を持ち、タスク自体を実行するためのアクセス権を与えます。一方、2)タスクロールはドッカーを担当します他の承認済みAWSサービスにAPIリクエストを行うコンテナ。
1)タスク実行ロールでは、次のJSONでAmazonECSTaskExecutionRolePolicy
を使用しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
2)ようやくNoCredentialsError: Unable to locate credentials
タスク実行ロールに加えて、たとえば特定のバケットからの読み取りを担当するタスクロールを追加したとき。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::bucket_name/*"
}
]
}
要約すれば;タスクの実行にアクセスするための1)executionRoleArnと、タスク定義で設定された承認済みAWSサービスへのAPIリクエストを行うためのアクセスのための2)taskRoleArnの両方のロールがあることを確認してください。
Amazon S3にコンテナーインスタンスロールの読み取り専用アクセスを許可するには
https://console.aws.Amazon.com/iam/ でIAMコンソールを開きます。
ナビゲーションペインで、[Roles]を選択します。
コンテナーインスタンスに使用するIAMロールを選択します(このロールは、おそらくecsInstanceRoleというタイトルです)。詳細については、「Amazon ECSコンテナインスタンスのIAMロール」を参照してください。
[Managed Policies]で、[Attach Policy]を選択します。
[ポリシーのアタッチ]ページの[フィルター]に「S3」と入力して、ポリシーの結果を絞り込みます。
AmazonS3ReadOnlyAccessポリシーの左側にあるボックスを選択し、[Attach Policy]を選択します。