Comment puis-je créer une configuration de notification Amazon S3 pour Lambda sur un compartiment S3 existant en utilisant AWS CloudFormation ?
Date de la dernière mise à jour : 08/07/2020
Je veux utiliser un compartiment Amazon Simple Storage Service (Amazon S3) existant pour créer une configuration de notification Amazon S3 pour une fonction AWS Lambda en utilisant AWS CloudFormation.
Courte description
Pour créer une configuration de notifications Amazon S3, vous pouvez utiliser AWS CloudFormation afin de créer un nouveau compartiment S3. Ensuite, ajoutez une configuration de notifications à ce compartiment à l'aide de la propriété NotificationConfiguration. Vous pouvez également ajouter manuellement une configuration de notifications à un compartiment S3 existant.
Les étapes suivantes vous montrent comment ajouter une configuration de notifications à un compartiment S3 existant avec AWS CloudFormation en utilisant une ressource personnalisée soutenue par AWS Lambda créée dans Python 3.6. La ressource personnalisée déclenche une fonction Lambda, qui déclenche l'API PutBucketNotification pour ajouter une configuration de notification à votre compartiment S3.
Résolution
Important : les étapes suivantes s'appliquent uniquement aux configurations de notification S3 pour les compartiments S3 qui n'ont aucune configuration de notification existante. Si votre compartiment S3 possède déjà une configuration de notification existante ou créée manuellement, les étapes suivantes remplacent ces configurations.
1. Créez un modèle AWS CloudFormation appelé LambdaS3.template qui inclut le code suivant :
Important : dans l'exemple suivant, vous ajoutez la configuration de notification S3 à la ressource S3NotificationLambdaFunction. Vous utilisez la fonction Lambda CustomResourceLambdaFunction pour ajouter la configuration de notification S3 pour S3NotificationLambdaFunction. Vous pouvez modifier le code dans la ressource CustomResourceLambdaFunction pour répondre à vos besoins.
AWSTemplateFormatVersion: 2010-09-09
Description: >-
Sample template to illustrate use of existing S3 bucket as an event source for a Lambda function
Parameters:
NotificationBucket:
Type: String
Description: S3 bucket that's used for the Lambda event notification
Resources:
S3NotificationLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile: !Join
- |+
- - import json
- 'def lambda_handler(event,context):'
- ' return ''Welcome... This is a test Lambda Function'''
Handler: index.lambda_handler
Role: !GetAtt LambdaIAMRole.Arn
Runtime: python3.6
Timeout: 5
LambdaInvokePermission:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: !GetAtt S3NotificationLambdaFunction.Arn
Action: 'lambda:InvokeFunction'
Principal: s3.amazonaws.com
SourceAccount: !Ref 'AWS::AccountId'
SourceArn: !Sub 'arn:aws:s3:::${NotificationBucket}'
LambdaIAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 's3:GetBucketNotification'
- 's3:PutBucketNotification'
Resource: !Sub 'arn:aws:s3:::${NotificationBucket}'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
CustomResourceLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.lambda_handler
Role: !GetAtt LambdaIAMRole.Arn
Code:
ZipFile: |
from __future__ import print_function
import json
import boto3
import cfnresponse
SUCCESS = "SUCCESS"
FAILED = "FAILED"
print('Loading function')
s3 = boto3.resource('s3')
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
responseData={}
try:
if event['RequestType'] == 'Delete':
print("Request Type:",event['RequestType'])
Bucket=event['ResourceProperties']['Bucket']
delete_notification(Bucket)
print("Sending response to custom resource after Delete")
elif event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
print("Request Type:",event['RequestType'])
LambdaArn=event['ResourceProperties']['LambdaArn']
Bucket=event['ResourceProperties']['Bucket']
add_notification(LambdaArn, Bucket)
responseData={'Bucket':Bucket}
print("Sending response to custom resource")
responseStatus = 'SUCCESS'
except Exception as e:
print('Failed to process:', e)
responseStatus = 'FAILURE'
responseData = {'Failure': 'Something bad happened.'}
cfnresponse.send(event, context, responseStatus, responseData)
def add_notification(LambdaArn, Bucket):
bucket_notification = s3.BucketNotification(Bucket)
response = bucket_notification.put(
NotificationConfiguration={
'LambdaFunctionConfigurations': [
{
'LambdaFunctionArn': LambdaArn,
'Events': [
's3:ObjectCreated:*'
]
}
]
}
)
print("Put request completed....")
def delete_notification(Bucket):
bucket_notification = s3.BucketNotification(Bucket)
response = bucket_notification.put(
NotificationConfiguration={}
)
print("Delete request completed....")
Runtime: python3.6
Timeout: 50
LambdaTrigger:
Type: 'Custom::LambdaTrigger'
DependsOn: LambdaInvokePermission
Properties:
ServiceToken: !GetAtt CustomResourceLambdaFunction.Arn
LambdaArn: !GetAtt S3NotificationLambdaFunction.Arn
Bucket: !Ref NotificationBucket
2. Pour lancer une pile AWS CloudFormation avec le fichier LambdaS3.template, utilisez la console AWS CloudFormation ou l'interface de ligne de commande AWS (CLI AWS) suivante :
aws cloudformation create-stack --stack-name lambda-s3-notification --template-body file://LambdaS3.template --parameters ParameterKey=NotificationBucket,ParameterValue=existing-bucket-for-lambda-notification --capabilities CAPABILITY_NAMED_IAM --region us-east-1
Important : lorsque vous lancez votre pile AWS CloudFormation, vous devez transmettre votre compartiment S3 (compartiment-existant-pour-la-notification-lambda).
La pile crée une fonction Lambda et des autorisations Lambda pour Amazon S3. Vous pouvez maintenant utiliser le compartiment S3 pour des notifications Lambda, car la pile a ajouté la configuration de notifications requise au compartiment S3.
Cet article vous a-t-il été utile ?
Besoin d'aide pour une question technique ou de facturation ?