Pourquoi est-ce que je reçois des erreurs Access Denied (Accès refusé) lorsque j'utilise une fonction Lambda pour charger des fichiers vers un compartiment Amazon S3 d'un autre compte AWS ?

Date de la dernière mise à jour : 28/03/2022

Je reçois une erreur Access Denied (Accès refusé) lorsque j'utilise une fonction AWS Lambda pour charger des fichiers vers un compartiment Amazon Simple Storage Service (Amazon S3). Le compartiment Amazon S3 se trouve dans un autre compte AWS. Comment résoudre ce problème ?

Brève description

Si les autorisations entre une fonction Lambda et un compartiment Amazon S3 sont incomplètes ou incorrectes, Lambda renvoie une erreur Access Denied (Accès refusé).

Pour configurer les autorisations entre une fonction Lambda d'un compte (compte 1) et un compartiment S3 d'un autre compte (compte 2), procédez comme suit :

1.    (Dans le compte 1) Créez un rôle d'exécution Lambda qui permet à la fonction Lambda de charger des objets vers Amazon S3.

2.    (Dans le compte 2) Modifiez la politique de compartiment du compartiment S3 pour permettre à la fonction Lambda de charger des objets vers le compartiment.

Solution

Important : la solution suivante nécessite une fonction Lambda dans un compte AWS et un compartiment S3 dans un autre compte.

Exemple de code pour une fonction Lambda qui charge des fichiers vers un compartiment S3 (Python version 3.8)

import json
import boto3

s3 = boto3.client('s3')

def lambda_handler(event,context):
    bucket = 'AccountBBucketName'
    transactionToUpload = {}
    transactionToUpload['transactionId'] = '12345'
    transactionToUpload['type'] = 'PURCHASE'
    transactionToUpload['amount'] = 20
    transactionToUpload['customerId'] = 'CID-1111'

    fileName = 'CID-1111'+'.json'
    uploadByteStream = bytes(json.dumps(transactionToUpload).encode('UTF-8'))
    s3.put_object(Bucket=bucket), Key=filename, Body=uploadByteStream, ACL='bucket-owner-full-control')
    print("Put Complete")

(Dans le compte 1) Créez un rôle d'exécution Lambda qui permet à la fonction Lambda de charger des objets vers Amazon S3

1.    Créez un rôle AWS Identity and Access Management (IAM) pour votre fonction Lambda.

2.    Copiez l'Amazon Resource Name (ARN) du rôle IAM.

Remarque : vous devez obtenir l'ARN du rôle IAM avant de pouvoir mettre à jour la politique de compartiment du compartiment S3. Pour obtenir l'ARN du rôle IAM, vous pouvez exécuter la commande get-role de l'AWS Command Line Interface (AWS CLI). Si vous recevez des erreurs lors de l'exécution des commandes AWS CLI, assurez-vous que vous utilisez la version la plus récente d'AWS CLI.

3.    Attachez une politique au rôle IAM qui accorde l'autorisation de charger des objets (s3:PutObject) vers le compartiment du compte 2.

Exemple de politique IAM qui accorde à un rôle IAM les autorisations s3:PutObject et s3:PutObjectAcl

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

4.    Remplacez le rôle d'exécution de votre fonction Lambda par le rôle IAM que vous avez créé. Pour obtenir des instructions, consultez Configuration des options de fonction Lambda.

(Dans le compte 2) Modifiez la politique de compartiment du compartiment S3 pour permettre à la fonction Lambda de charger des objets vers le compartiment

Mettez à jour la politique de compartiment afin qu'elle spécifie l'ARN du rôle d'exécution Lambda en tant que Principal ayant accès à l'action s3:PutObject.

Exemple de politique de compartiment S3 qui permet à une fonction Lambda de charger des objets vers le compartiment

Remarque : la politique suivante accorde également au rôle d'exécution de la fonction Lambda l'autorisation s3:PutObjectAcl.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::AccountA:role/AccountARole"
      },
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::AccountBBucketName/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    }
  ]
}

Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?