web-dev-qa-db-fra.com

Impossible d'accéder au compartiment S3 à partir du conteneur Fargate (mauvaise demande et impossible de localiser les informations d'identification)

J'ai créé un compartiment s3 privé et un cluster fargate avec une tâche simple qui tente de lire à partir de ce compartiment en utilisant python 3 Et boto3. J'ai essayé ceci sur 2 images de docker différentes et sur l'une j'obtiens un ClientError de boto disant HeadObject Bad request (400) et l'autre j'obtiens NoCredentialsError: Unable to locate credentials.

La seule vraie différence dans les images est que celle qui dit mauvaise requête est exécutée normalement et l'autre est exécutée manuellement par moi via ssh vers le conteneur de tâches. Je ne sais donc pas pourquoi une image dit "mauvaise demande" et l'autre "impossible de localiser les informations d'identification".

J'ai essayé quelques politiques IAM différentes, y compris (terraform) les politiques suivantes:

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/*"]
  }
}

Deuxième essai:

data "aws_iam_policy_document" "access_s3" {
  statement {
    effect    = "Allow"
    actions   = ["s3:*"]
    resources = ["arn:aws:s3:::*"]
  }
}

Et le dernier que j'ai essayé était une politique intégrée:

resource "aws_iam_role_policy_attachment" "access_s3" {
  role       = "${aws_iam_role.ecstasks.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}

la définition du bucket est très simple:

resource "aws_s3_bucket" "bucket" {
  bucket = "${var.bucket_name}"
  acl    = "private"
  region = "${var.region}"
}

Code utilisé pour accéder au compartiment 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()

Peu importe ce que je fais, je ne peux pas utiliser boto3 Pour accéder aux ressources AWS à partir d'une tâche de conteneur Fargate. Je peux accéder au même compartiment s3 avec boto3 Sur une instance de EC2 Sans fournir aucun type d'informations d'identification et en utilisant uniquement les rôles/politiques IAM. Qu'est-ce que je fais mal? N'est-il pas possible d'accéder aux ressources AWS de la même manière à partir d'un conteneur Fargate?

J'ai oublié de mentionner que j'affecte les rôles IAM à la stratégie d'exécution de définition de tâche et à la stratégie de tâche.

UPDATE : Il s'avère que l'erreur unable to find credentials que j'ai eue est un hareng rouge. La raison pour laquelle je n'ai pas pu obtenir les informations d'identification était parce que ma session ssh directe n'avait pas la variable d'environnement AWS_CONTAINER_CREDENTIALS_RELATIVE_URI Définie.

AWS Fargate injectera en votre nom une variable d'environnement nommée AWS_CONTAINER_CREDENTIALS_RELATIVE_URI Qui contient une URL vers ce que boto doit utiliser pour récupérer les informations d'identification d'accès à l'API. L'erreur Bad request Est donc celle que j'obtiens et j'ai besoin d'aide pour la résoudre. J'ai vérifié mes variables d'environnement à l'intérieur du conteneur et la valeur AWS_CONTAINER_CREDENTIALS_RELATIVE_URI Est définie par Fargate.

6
vane

J'ai eu beaucoup de mal avec ce problème et j'ai constamment AWS_CONTAINER_CREDENTIALS_RELATIVE_URI incorrectement défini sur None, jusqu'à ce que j'ajoute un rôle de tâche personnalisé en plus à mon actuel rôle d'exécution de tâche.

1) Le rôle d'exécution de la tâche est responsable d'avoir accès au conteneur dans ECR et de donner l'accès pour exécuter la tâche elle-même, tandis que 2) le rôle de tâche est responsable de votre docker conteneur effectuant des demandes d'API à d'autres services AWS autorisés.

1) Pour mon rôle d'exécution de tâche, j'utilise AmazonECSTaskExecutionRolePolicy avec le JSON suivant;

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

2) Je me suis enfin débarrassé du NoCredentialsError: Unable to locate credentials lorsque j'ai ajouté un rôle de tâche en plus du rôle d'exécution de tâche, par exemple, responsable de la lecture à partir d'un certain compartiment;

{
    "Version": "2012-10-17",
    "Statement": [
           {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket_name/*"
        }
    ]
}

En résumé; assurez-vous d'avoir à la fois un rôle pour 1) executionRoleArn pour l'accès pour exécuter la tâche et 2) taskRoleArn pour l'accès pour effectuer des demandes d'API aux services AWS autorisés définis dans votre définition de tâche .

4
NorahKSakal

Pour autoriser l'accès en lecture seule à Amazon S3 pour votre rôle d'instance de conteneur

Ouvrez la console IAM sur https://console.aws.Amazon.com/iam/ .

Dans le volet de navigation, choisissez Rôles.

Choisissez le rôle IAM à utiliser pour vos instances de conteneur (ce rôle est probablement intitulé ecsInstanceRole). Pour plus d'informations, consultez Rôle IAM d'instance de conteneur Amazon ECS.

Sous Stratégies gérées, choisissez Attach Policy.

Sur la page Attach Policy, pour Filter, tapez S3 pour affiner les résultats de la stratégie.

Sélectionnez la case à gauche de la stratégie AmazonS3ReadOnlyAccess et choisissez Attach Policy.

1
Jay_C