Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda function is missing trigger by websocket gateway when using CloudFormation

I am trying to set-up a websocket gateway to a Lambda function in AWS. When I do this manually I can successfully deploy the websocket and try it out using wscat. However I would like to build the architecture up using CloudFormation.

The structure of my CloudFormation yaml file looks like this:

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  lambdaRole:
    Type: String
    Default: ...
  backendRole:
    Type: String
    Default: ...
  lambdaImage:
    Type: String
    Default: ...
Resources:
    MyLambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
            Code:
                ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${backendRole}:${lambdaImage}
            Description: lambda connect function
            FunctionName: myLambdaFunction
            MemorySize: 128
            Role: !Sub arn:aws:iam::${AWS::AccountId}:role/${lambdaRole}
            Timeout: 3
            PackageType: Image
    MyWebSocket:
        Type: AWS::ApiGatewayV2::Api
        Properties:
            Name: MyWebSocket
            ProtocolType: WEBSOCKET
            RouteSelectionExpression: $request.body.action
    MyIntegration:
        Type: AWS::ApiGatewayV2::Integration
        Properties:
            ApiId: !Ref MyWebSocket
            Description: Lambda Integration
            IntegrationType: AWS_PROXY
            IntegrationUri: !Join
                - ''
                - - 'arn:'
                  - !Ref 'AWS::Partition'
                  - ':apigateway:'
                  - !Ref 'AWS::Region'
                  - ':lambda:path/2015-03-31/functions/'
                  - !GetAtt MyLambdaFunction.Arn
                  - /invocations
            IntegrationMethod: POST
    MyConnectRoute:
        Type: AWS::ApiGatewayV2::Route
        Properties:
            ApiId: !Ref MyWebSocket
            RouteKey: $connect
            Target: !Join
            - /
            - - integrations
              - !Ref MyIntegration
    MyDefaultRoute:
        Type: AWS::ApiGatewayV2::Route
        Properties:
            ApiId: !Ref MyWebSocket
            RouteKey: $default
            Target: !Join
            - /
            - - integrations
              - !Ref MyIntegration     
    MyResponseRoute:
        Type: AWS::ApiGatewayV2::Route
        Properties:
            ApiId: !Ref MyWebSocket
            RouteKey: add
            RouteResponseSelectionExpression: $default
            Target: !Join
            - /
            - - integrations
              - !Ref MyIntegration
    MyRouteResponse:
        Type: AWS::ApiGatewayV2::RouteResponse
        Properties:
            RouteId: !Ref MyResponseRoute
            ApiId: !Ref MyWebSocket
            RouteResponseKey: $default
    MyIntegrationResponse:
      Type: AWS::ApiGatewayV2::IntegrationResponse
      Properties:
        IntegrationId: !Ref MyIntegration
        IntegrationResponseKey: /201/
        ApiId: !Ref MyWebSocket
    testStage:
        Type: AWS::ApiGatewayV2::Stage
        DependsOn:
        - MyConnectRoute
        - MyDefaultRoute
        - MyResponseRoute
        Properties: 
            ApiId: !Ref MyWebSocket
            StageName: testStage
    MyDeployment:
        Type: AWS::ApiGatewayV2::Deployment
        Properties:
            ApiId: !Ref MyWebSocket
            Description: My Deployment
            StageName: !Ref testStage

The stack is build without any errors and (almost) everything looks like I intended. However other than in the manually build version the integration of the Lambda function into the websocket does not seem to add the required trigger for the Lambda function. When I manually add a Lambda function to an API Gateway, this automatically adds the trigger.

What do I need to change in my CloudFormation Yaml file to also add the trigger to the Lambda function?

Trigger automatically added to Lambda function when Lambda function is manually added to API Gateway: Trigger automatically added to Lambda function when Lambda function is manually added to API Gateway

No trigger added when Lambda function is added to API Gateway using CloudFormation: No trigger added when Lambda function is added to API Gateway using CloudFormation

like image 462
Axel Avatar asked Aug 13 '26 14:08

Axel


1 Answers

It looks like you may just need to include the Lambda permission for api gateway.

LambdaFunctionPermission:
  Type: "AWS::Lambda::Permission"
  Properties:
    Action: "lambda:InvokeFunction"
    Principal: apigateway.amazonaws.com
    FunctionName: !Ref MyLambdaFunction
  DependsOn: MyWebSocket

If you are having issues with Cloudformation creation it would probably be helpful to also create an account config for logging and chain the dependsOn order of the gateway resources like this.

  ApiGwAccountConfig:
    Type: "AWS::ApiGateway::Account"
    Properties:
      CloudWatchRoleArn: !GetAtt "rRoleForCloudtrail.Arn"
  rRoleForCloudtrail:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - apigateway.amazonaws.com
          Action:
          - sts:AssumeRole
      Policies:
        -
          PolicyName: "apigateway-cloudwatch"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: 
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                  - logs:PutLogEvents
                  - logs:GetLogEvents
                  - logs:FilterLogEvents
                Resource: "*"
  testStage:
    Type: AWS::ApiGatewayV2::Stage
    Properties: 
        ApiId: !Ref MyWebSocket
        StageName: testStage
    DefaultRouteSettings:
      DetailedMetricsEnabled: true
      LoggingLevel: INFO
      DataTraceEnabled: true
  DependsOn: ApiGwAccountConfig

  MyDeployment:
    Type: AWS::ApiGatewayV2::Deployment
    DependsOn:
    - MyConnectRoute
    - MyDefaultRoute
    - MyResponseRoute
    Properties:
        ApiId: !Ref MyWebSocket
        Description: My Deployment
        StageName: !Ref testStage
like image 95
Tj Kellie Avatar answered Aug 15 '26 08:08

Tj Kellie