#amazon-web-services #aws-lambda #aws-api-gateway #amazon-cloudformation
#amazon-web-services #aws-lambda #aws-api-gateway #amazon-cloudformation
Вопрос:
Я искал ответ по всему Интернету.
По сути, мы запускаем API с использованием Swagger, который потрясающий и отлично работает, но одна вещь не работает… Когда мы выполняем вызов конечной точки, мы получаем ошибку 500 (мы предоставляем не ошибку 500, либо она из AWS). Ошибка гласит: «Сбой выполнения из-за ошибки конфигурации: недопустимые разрешения для лямбда-функции» (https://youtu.be/H4LM_jw5zzs <- Это видео от другого пользователя с ошибкой, которую я получаю).
Я прошел через множество дыр и нашел ответ… Это связано с использованием командной строки AWS и выглядит примерно так:
aws lambda add-permission
--function-name FUNCTION_NAME
--statement-id STATEMENT_ID
--action lambda:InvokeFunction
--principal apigateway.amazonaws.com
--source-arn "arn:aws:execute-api:us-east-1:ACCOUNT_ID:API_ID/*/METHOD/ENDPOINT"
Это здорово и все такое, но мы используем CloudFormation для запуска всего, и мы хотим, чтобы это было автоматизировано. Есть ли более простой способ сделать это? Есть ли что-то в CloudFormation, что даст нам необходимую политику ресурсов?
Я немного затрудняюсь с этим, но сегодня я работал над этим несколько часов, и это немного блокирует нашу версию API, поэтому любая помощь будет очень признательна. 🙂
Комментарии:
1. Как бы то ни было, вы также можете сделать это с помощью AWS SDK. Я использую его для Go, поэтому он здесь: docs.aws.amazon.com/sdk-for-go/api/service/lambda/… … Чего я не вижу, если какой-либо способ перечислить существующие разрешения. Поэтому я просто допускаю ошибки, связанные с этим, уже существующие в моем инструменте развертывания. Странно. Я имею в виду, что я даже не видел ничего о необходимости этого разрешения, и его нет ни в каком экспортированном Swagger.
Ответ №1:
У CloudFormation
этой проблемы есть решение. Смотрите следующий CloudFormation
фрагмент:
"Permission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": { "Fn::GetAtt": [ "Lambda", "Arn" ] },
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com",
"SourceArn": { "Fn::Join": [ "", [
"arn:aws:execute-api:",
{ "Ref": "AWS::Region" }, ":",
{ "Ref": "AWS::AccountId" }, ":",
{ "Ref": "API" },
"/*/*/*"
] ] }
}
}
Это предоставляет API Gateway
разрешения на запуск вашей Lambda
функции. Переменные в этом фрагменте, которые вам нужно изменить, — это Lambda
(строка 4) и API
(строка 11).
Комментарии:
1. Есть ли какая-либо опасность
"/*/*/*"
при использовании versus/*/POST/example
? на первый взгляд кажется, что мы открываем разрешения для этой конечной точки api для вызова любого пути к ресурсам2. @David все зависит от приложения — нужно ли вам, чтобы API Gateway был фильтром
3. для всех функций, которые я должен использовать?
4. мне нужно дать разрешение на все мои лямбда-функции, так что я должен указать в functionName??
5. Вы можете видеть, что это ARN. Проверьте его, и вы сможете поставить «*» в конце, где находится имя функции.
Ответ №2:
Для разрешений на вызов:
"APIInvokePermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Ref": "YOUR_LAMBDA_FUNCTION_RESOURCE_NAME"
},
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${YOUR_REST_API_RESOURCE_NAME}/*/*/*"
}
}
},
Комментарии:
1. мне нужно дать разрешение на все мои лямбда-функции, так что я должен указать в functionName??
Ответ №3:
Спасибо https://twitter.com/edjgeek за то, что помог мне разобраться в этом у себя в голове.
В этой статье показано, как использовать AWS ::Serverless:Function с событиями для автоматического создания необходимого AWS ::Lambda::Permission, чтобы разрешить APIGateway (для данного маршрута) вызывать ваш лямбда-интерфейс.:
https://gist.github.com/rainabba/68df1567cbd0c4930d428c8953dc2316
Оба следующих подхода предполагают api, такой как (многие поля опущены для удобства чтения):
MyApi:
Type: 'AWS::Serverless::Api'
Properties:
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: openapi.yaml
Использование «Событий SAM»
Наиболее важный бит (я пропустил много обязательных полей):
MyLambdaFunction:
Type: 'AWS::Serverless::Function'
Properties:
Events:
MyRouteEventToProxy:
Type: Api
Properties:
Method: POST
Path: '/some-route/{pathParm}'
RestApiId: !Ref MyApi # ResourceName of AWS::Serverless::Api
Auth:
Authorizer: NONE
Использование «привязки openapi»
Если вы предпочитаете объявлять привязку в openapi.yaml, тогда посмотрите следующий проект (лямбда / события не требуются). Для этого подхода требуется явная роль, позволяющая вызывать.
шаблон.соответствующие биты yaml:
MyLambdaFunction:
Type: 'AWS::Serverless::Function'
Properties:
# Events: # No need for Events when binding from openapi.yaml
MyHttpApiRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "apigateway.amazonaws.com"
Action:
- "sts:AssumeRole"
соответствующие биты openapi.yaml:
paths:
post:
x-amazon-apigateway-integration:
httpMethod: POST
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}:live/invocations"
contentHandling: "CONVERT_TO_TEXT"
type: aws_proxy
credentials:
Fn::GetAtt: [MyHttpApiRole, Arn]
https://github.com/aws-samples/sessions-with-aws-sam/tree/master/http-api-direct-integration