Não consigo inscrever minha função do AWS Lambda em uma notificação de evento do Amazon Simple Storage Service (Amazon S3) ou em um tópico do Amazon Simple Notification Service (Amazon SNS) na minha pilha do AWS CloudFormation.
Breve descrição
Se você usar o recurso AWS::Lambda::EventSourceMapping para inscrever sua função do Lambda, poderá receber o seguinte erro: "Unrecognized event source, must be kinesis or dynamodb stream."
Esse recurso foi projetado para fontes de eventos baseadas em pull, como streams de eventos do Amazon DynamoDB e do Amazon Kinesis. Quando você usa fontes de eventos baseadas em push, como notificações de eventos do Amazon S3 ou mensagens do Amazon SNS, a fonte do evento invoca a função do Lambda. Para que uma fonte de evento push invoque uma função do Lambda, a política de recursos da função deve autorizar um serviço que possa invocar funções do Lambda.
Resolução
Em seu modelo do CloudFormation, adicione uma política baseada em recursos usando o recurso AWS::Lambda::Permission.
Por exemplo, a seguinte política baseada em recursos permite que um tópico do Amazon SNS invoque uma função do Lambda:
"LambdaResourcePolicy": { "Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName" : { "Ref" : "MyFunction" },
"Principal": "sns.amazonaws.com",
"Action": "lambda:InvokeFunction",
"SourceArn" : { "Ref" : "MySNSTopic" }
}
}
Para uma fonte de evento de tópico do Amazon SNS, você deve definir uma política de tópico com as permissões necessárias.
Para uma fonte de evento do Amazon S3, você deve ter uma declaração de configuração de notificação que inscreva a função do Lambda no bucket do Amazon S3. Por exemplo:
{ "AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"BucketPrefix": {
"Type": "String",
"Default": "test-bucket-name"
}
},
"Resources": {
"EncryptionServiceBucket": {
"DependsOn": "LambdaInvokePermission",
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": {
"Fn::Sub": "${BucketPrefix}-encryption-service"
},
"NotificationConfiguration": {
"LambdaConfigurations": [
{
"Function": {
"Fn::GetAtt": [
"AppendItemToListFunction",
"Arn"
]
},
"Event": "s3:ObjectCreated:*",
"Filter": {
"S3Key": {
"Rules": [
{
"Name": "suffix",
"Value": "zip"
}
]
}
}
}
]
}
}
},
"LambdaInvokePermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"AppendItemToListFunction",
"Arn"
]
},
"Action": "lambda:InvokeFunction",
"Principal": "s3.amazonaws.com",
"SourceAccount": {
"Ref": "AWS::AccountId"
},
"SourceArn": {
"Fn::Sub": "arn:aws:s3:::${BucketPrefix}-encryption-service"
}
}
},
"AppendItemToListFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
},
"Code": {
"ZipFile": {
"Fn::Join": [
"",
[
"exports.handler = function(event, context) {",
"console.log('Received event: ', JSON.stringify(event, null, 2));",
"};"
]
]
}
},
"Runtime": "nodejs20.x"
}
},
"LambdaExecutionRole": {
"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": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:log-group:/path/<log-group-name>:log-stream:<log-stream-name>"
}
]
}
}
]
}
}
}
}
No exemplo anterior, o bucket do S3 e a configuração de notificação são criados ao mesmo tempo. O exemplo evita uma dependência circular por meio da função intrínseca Fn::GetAtt e do atributo DependsOn para criar os recursos.
Observação: Quando o atributo DependsOn não é especificado, o CloudFormation cria o bucket do S3 e os recursos de permissão do Lambda ao mesmo tempo.
Os recursos são criados na seguinte ordem:
- Perfil do AWS Identity and Access Management (AWS IAM)
- Função do Lambda
- Permissões do Lambda
- Bucket do S3
Para obter mais informações, consulte Como faço para corrigir o erro no CloudFormation?"Unable to validate the following destination configurations"
Informações relacionadas
Práticas recomendadas do CloudFormation
Permissões de ação de recursos do Lambda
Atualizar comportamentos dos recursos da pilha