Как я могу предоставить разрешение API Gateway на вызов лямбда-функций через CloudFormation?

#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