Skip to content

bug: eventbridge input transformer with string replacement in json #11126

@vladshoob

Description

@vladshoob

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

  • using PROVIDER_OVERRIDE_EVENTS=v2
  • eventbridge rule is set to transform with
InputTransformer:
  InputPathsMap:
    "userId" : "$.detail.id"
    "body" : "$.detail"
  InputTemplate: |
    {
      "method" : "PUT",
      "path" : "users-service/users/<userId>",
      "body": <body>
    }
  • fails while sending aws events put-events command with error
{
    "FailedEntryCount": 1,
    "Entries": [
        {
            "ErrorCode": "InternalException",
            "ErrorMessage": "Expecting ',' delimiter: line 3 column 34 (char 55)"
        }
    ]
}
  • but works if "path" is set to constant - "path" : "users-service/users/123456789",

Expected Behavior

InputTransform replaces a variable within a string in JSON object. The same way AWS Eventbridge native implementation does.

How are you starting LocalStack?

With a docker-compose file

Steps To Reproduce

Given localstack is running from docker compose.yml

version: "3.8"

services:
  localstack:
    image: localstack/localstack:3.5.0
    environment:
      - PROVIDER_OVERRIDE_EVENTS=v2
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./tmp/localstack}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

And given resources are created from Cloudformation template

Resources:
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: /aws/lambda/AwsLambdaMinimalExample

  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: AwsLambdaMinimalExample
      Handler: index.handler
      Runtime: nodejs20.x
      Role: !GetAtt LambdaFunctionRole.Arn
      MemorySize: 256
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            console.log('method', event.method);
            console.log('path', event.path);
            console.log('body', event.body);
            return {
              statusCode: 200,
              body: JSON.stringify(event),
            }
          }

  LambdaFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: AppendToLogsPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  EventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: input-transformer-rule
      EventPattern:
        detail-type:
          - "myDetailType"
      Targets:
        - Id: transform-and-invoke-lambda
          Arn: !GetAtt LambdaFunction.Arn
          InputTransformer:
            InputPathsMap:
              "userId" : "$.detail.id"
              "body" : "$.detail"
            InputTemplate: |
              {
                "method" : "PUT",
                "path" : "users-service/users/<userId>",
                "body": <body>
              }

  PermissionForEventToInvokeLambda:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !GetAtt LambdaFunction.Arn
      Action: "lambda:InvokeFunction"
      Principal: "events.amazonaws.com"
      SourceArn: !GetAtt EventRule.Arn

And deployed using aws cloudformation create-stack --stack-name minimal-example --capabilities CAPABILITY_NAMED_IAM --template-body file://cloudformation.yaml --endpoint-url http://localhost:4566 --region us-east-1

On dispatching eventbridge events - aws events put-events --endpoint-url http://localhost:4566 --region us-east-1 --entries file://event.json with event.json containing

[
  {
    "EventBusName": "default",
    "Source": "com.mycompany.myapp",
    "Detail": "{ \"id\": \"987654321\", \"name\": \"John Doe\" }",
    "Resources": [
      "resource1",
      "resource2"
    ],
    "DetailType": "myDetailType"
  }
]

fails with mentioned error.

Validation for successful lambda invocation is performed with simple log info and monitored by watching tail of a log group via
aws logs tail /aws/lambda/AwsLambdaMinimalExample --endpoint-url http://localhost:4566 --region us-east-1 --follow command.

Environment

- OS: Ubuntu 20.04
- LocalStack: 3.5.0

Anything else?

Related issue - 10287.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions