aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.34k stars 3.76k forks source link

apigatewayv2: stateMachineArn does not fit schema for Operation: StepFunctions-StartSyncExecution #26328

Open YishaqG opened 11 months ago

YishaqG commented 11 months ago

Describe the bug

I'm trying to create a ApiGatewayV2 route with AWS StepFunction integration. For this I'm using the L1 constructs but getting the following error message:

UPDATE_ROLLBACK_COMPLETE: Parameter: stateMachineArn does not fit schema for Operation: StepFunctions-StartSyncExecution. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException

Expected Behavior

The creation of the ApiGatewayV2 route with an AWS StepFunction integration

Current Behavior

Stack deployment failure and rollbacked:

UPDATE_ROLLBACK_COMPLETE: Parameter: stateMachineArn does not fit schema for Operation: StepFunctions-StartSyncExecution. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException

Reproduction Steps

const demoStateMachine = new StateMachine(scope, 'DemoStateMachine', {
    stateMachineType: StateMachineType.EXPRESS,
    definitionBody: 
        DefinitionBody.fromChainable( 
           new Pass(scope, 'PassState')
        ),
});

const role = new Role(scope, 'DemoStateMachineRole', {
    assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
});

const integration = new CfnIntegration(
    this.scope,
    "DemoStateMachineIntegration",
    {
        apiId: gateway.httpApiId,
        integrationType: HttpIntegrationType.AWS_PROXY,
        integrationSubtype: 'StepFunctions-StartSyncExecution',
        credentialsArn: role.roleArn,
        payloadFormatVersion: PayloadFormatVersion.VERSION_1_0.version,
        requestParameters: {
            stateMachineArn: demoStateMachine.stateMachineArn
        }
    }
);

new CfnRoute(this.scope, 'CheckoutRoute', {
    apiId: gateway.httpApiId,
    routeKey: `${HttpMethod.POST} demo`,
    authorizationType: 'NONE',
    target: `integrations/${integration.ref}`,
});

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.85.0

Framework Version

2.85.0

Node.js Version

16.18.0

OS

macOS 13.4.1

Language

Typescript

Language Version

4.9.5

Other information

No response

pahud commented 11 months ago

Looks like the stateMachineArn is invalid.

requestParameters: {
            stateMachineArn: demoStateMachine.stateMachineArn
        }

Are you able to CfnOutput the value of demoStateMachine.stateMachineArn for troubleshooting?

I guess this might related to https://github.com/aws/aws-cdk/issues/25395#issuecomment-1531840410 and a trailing .sync might be required.

YishaqG commented 11 months ago

What I was trying to do here is not related with https://github.com/aws/aws-cdk/issues/25395#issuecomment-1531840410 he is trying to use other services from the StepFunction. What I was trying to do was to invoke a StepFunction from ApiGatewayV2

Done, so it looks like you need to specify it as:

    requestParameters: {
        StateMachineArn: demoStateMachine.stateMachineArn,
        Input: '$request.body.input',
    }
Perminus-Gaita commented 2 months ago

Here is the full code with the imports and all the code that works.

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CfnIntegration, CfnRoute, HttpMethod, PayloadFormatVersion } from 'aws-cdk-lib/aws-apigatewayv2'
import { DefinitionBody, StateMachine, StateMachineType, Pass } from 'aws-cdk-lib/aws-stepfunctions';
import { Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { HttpIntegrationType, HttpApi } from 'aws-cdk-lib/aws-apigatewayv2';

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // ... (your existing code)
    const httpApi = new HttpApi(this, 'MyHttpApi');

    const demoStateMachine = new StateMachine(this, 'DemoStateMachine', {
      stateMachineType: StateMachineType.EXPRESS,
      definitionBody: DefinitionBody.fromChainable(
        new Pass(this, 'PassState')
      ),
    });

    const role = new Role(this, 'DemoStateMachineRole', {
      assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
    });

    const integration = new CfnIntegration(
      this,
      "DemoStateMachineIntegration",
      {
        apiId: httpApi.httpApiId,
        integrationType: HttpIntegrationType.AWS_PROXY,
        integrationSubtype: 'StepFunctions-StartSyncExecution',
        credentialsArn: role.roleArn,
        payloadFormatVersion: PayloadFormatVersion.VERSION_1_0.version,
        requestParameters: {
            StateMachineArn: demoStateMachine.stateMachineArn,
            Input: '$request.body.input',
        }
      }
    );

    new CfnRoute(this, 'CheckoutRoute', {
      apiId: httpApi.httpApiId,
      routeKey: `${HttpMethod.POST} /demo`,
      authorizationType: 'NONE',
      target: `integrations/${integration.ref}`,
    });
  }
}