Как предоставить шлюзу API разрешение на вызов функции Lambda в шаблоне CloudFormation?

У меня есть шаблон AWS CloudFormation, написанный на yaml, который успешно создает все необходимые мне ресурсы и настраивает шлюз API для успешного вызова лямбда-файла, за исключением того, что у шлюза API нет разрешения на автоматический вызов лямбда-функции.

В настоящее время мне нужно войти в шлюз API и дать разрешение вручную. Перед этим я получаю ошибку с кодом 500, а потом получаю код 200 и результат, который хочу.

Добавить разрешение на лямбда-функцию

Внизу моего шаблона я попытался сделать разрешение на основе нескольких других сообщений о переполнении стека, которые я видел по этой теме, но я не смог заставить их работать после нескольких часов попыток разных ответов и форматов. Я помещаю полный шаблон ниже.

AWSTemplateFormatVersion: 2010-09-09

Resources:
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument: 
        Version: '2012-10-17'
        Statement: 
        - Effect: 'Allow'
          Principal: 
            Service: 
              - 'lambda.amazonaws.com'
              - 'comprehend.amazonaws.com'
              - 'apigateway.amazonaws.com'
          Action:
            - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/ComprehendFullAccess'
        - 'arn:aws:iam::aws:policy/service-role/ComprehendDataAccessRolePolicy'
        - 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
      RoleName: LambdaRole

  SentimentFunction:
    Type: AWS::Lambda::Function
    DependsOn:
      - LambdaRole
    Properties: 
      Code:
        ZipFile: |
          import boto3
  
          client = boto3.client('comprehend')
          
          def lambda_handler(event, context):
            result = {
              'Sentiment': client.detect_sentiment(Text = event['inputTranscript'], LanguageCode='en')['Sentiment'],
              'SentimentScore': client.detect_sentiment(Text = event['inputTranscript'], LanguageCode='en')['SentimentScore']
            }
            return result
      FunctionName: 'SentimentFunction'
      Handler: index.lambda_handler
      Role: !GetAtt LambdaRole.Arn
      Runtime: 'python3.9'

  SentimentSchedule:
    Type: AWS::Events::Rule
    Properties:
      Description: "Schedule to trigger SentimentFunction every minute"
      ScheduleExpression: "cron(* * * * ? *)"
      Targets:
        - Arn: !GetAtt SentimentFunction.Arn
          Id: "SentimentFunction"

  SentimentAPI:
    Type: AWS::ApiGateway::RestApi
    Properties:
      EndpointConfiguration:
        Types:
        - REGIONAL
      Name: SentimentAPI

  RestApiDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - SentimentAPI
      - SentimentAnalysis
    Properties:
      RestApiId: !Ref SentimentAPI
      StageName: dev

  SentimentGatewayResource:
    Type: AWS::ApiGateway::Resource
    DependsOn:
      - SentimentAPI
    Properties:
      ParentId: !GetAtt SentimentAPI.RootResourceId
      PathPart: analysis
      RestApiId: !Ref SentimentAPI

  SentimentAnalysis:
    Type: AWS::ApiGateway::Method
    DependsOn:
      - SentimentGatewayResource
      - SentimentAPI
      - SentimentFunction
    Properties:
      ApiKeyRequired: false
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        IntegrationHttpMethod: GET
        IntegrationResponses:
          - StatusCode: '200'
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestTemplates:
            application/json : '{"inputTranscript": "I want something"}'
        Type: AWS
        Uri:
          !Join
          - ''
          - - 'arn:'
            - !Ref AWS::Partition
            - ':apigateway:'
            - !Ref AWS::Region
            - :lambda:path/2015-03-31/functions/
            - !GetAtt SentimentFunction.Arn
            - /invocations
      MethodResponses:
        - ResponseModels:
            application/json : Empty
          StatusCode: '200'
      ResourceId: !Ref SentimentGatewayResource
      RestApiId: !Ref SentimentAPI

  # vvvvvvvv This doesn't work vvvvvvvv
  GWAuth:
    Type: AWS::ApiGateway::Authorizer
    Properties: 
      AuthorizerUri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SentimentFunction.Arn}/invocations"
      RestApiId: !Ref SentimentAPI
      Type: "REQUEST"
      IdentitySource: method.request.header.authorization
      Name: custom_auth

  GWAuthPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt SentimentFunction.Arn
      Principal: "apigateway.amazonaws.com"
      SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SentimentAPI}/authorizers/${GWAuth}"

Я очень новичок в AWS, поэтому я уверен, что мой шаблон изначально плохо сформирован. Эта ошибка мешала мне добиться большего прогресса. Любая помощь очень ценится!

Сбой лямбда-вызова до предоставления разрешений вручную

Лямбда-вызов работает после предоставления разрешений вручную

Стек создан полностью

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У меня есть настройка API для лямбда, которая использует свойство events в лямбде:

RetrieverLambda:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          STAGE:
            Ref: Stage
          ACCOUNT:
            Ref: AWS::AccountId
          REGION:
            Ref: AWS::Region
      CodeUri:
        Bucket: {'Fn::If': ['UseBatsKey', 'BATS::SAM::CodeS3Bucket', {"Fn::ImportValue": {Ref: 'DeploymentBucketImportName'}}]}
        Key: BATS::SAM::CodeS3Key
      Events:
        APIG:
          Properties:
            Method: ANY
            Path: /
            RestApiId: {Ref: LambdaAPIDefinition}
          Type: Api
        proxy:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
            RestApiId: {Ref: LambdaAPIDefinition}
      Handler: ...
      ..... 

И шлюз Api определяется так же, как вы это сделали:

LambdaAPIDefinition:
    Type: 'AWS::Serverless::Api'
    Properties:
      StageName: {Ref: Stage}
      EndpointConfiguration: REGIONAL
      Auth:
        DefaultAuthorizer: AWS_IAM
        InvokeRole: NONE     # removal of this will cause deployment failure with the error
                             #'Caller provided credentials not allowed when resource policy is set'
        ResourcePolicy:
          CustomStatements:
            - Effect: 'Allow'
              Action: 'execute-api:Invoke'
              Resource: ['execute-api:/*/*/*']
              Principal:
                AWS:
                  - !Sub "arn:aws:iam::${AWS::AccountId}:user/ApiUser"

В приведенном выше примере я использую пользователя IAM вместо роли. Но я не думаю, что это имеет значение здесь.

Я думаю, добавление триггера события в вашу конструкцию Lambda должно это исправить.

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html

Другие вопросы по теме