diff --git a/packages/@aws-cdk/aws-appsync/lib/data-source.ts b/packages/@aws-cdk/aws-appsync/lib/data-source.ts index b7570be255fac..c89479c4ef69b 100644 --- a/packages/@aws-cdk/aws-appsync/lib/data-source.ts +++ b/packages/@aws-cdk/aws-appsync/lib/data-source.ts @@ -111,7 +111,8 @@ export abstract class BaseDataSource extends CoreConstruct { if (extended.type !== 'NONE') { this.serviceRole = props.serviceRole || new Role(this, 'ServiceRole', { assumedBy: new ServicePrincipal('appsync') }); } - const name = props.name ?? id; + // Replace unsupported characters from DataSource name. The only allowed pattern is: {[_A-Za-z][_0-9A-Za-z]*} + const name = (props.name ?? id).replace(/[\W]+/g, ''); this.ds = new CfnDataSource(this, 'Resource', { apiId: props.api.apiId, name: name, diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts index b714b0f28cef9..786937eaee629 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts @@ -65,6 +65,42 @@ describe('Lambda Data Source configuration', () => { }); }); + test('appsync sanitized datasource name from unsupported characters', () => { + const badCharacters = [...'!@#$%^&*()+-=[]{}\\|;:\'",<>?/']; + + badCharacters.forEach((badCharacter) => { + // WHEN + const newStack = new cdk.Stack(); + const graphqlapi = new appsync.GraphqlApi(newStack, 'baseApi', { + name: 'api', + schema: appsync.Schema.fromAsset(path.join(__dirname, 'appsync.test.graphql')), + }); + const dummyFunction = new lambda.Function(newStack, 'func', { + code: lambda.Code.fromAsset(path.join(__dirname, 'verify/iam-query')), + handler: 'iam-query.handler', + runtime: lambda.Runtime.NODEJS_12_X, + }); + graphqlapi.addLambdaDataSource(`data-${badCharacter}-source`, dummyFunction); + + // THEN + Template.fromStack(newStack).hasResourceProperties('AWS::AppSync::DataSource', { + Type: 'AWS_LAMBDA', + Name: 'datasource', + }); + }); + }); + + test('appsync leaves underscore untouched in datasource name', () => { + // WHEN + api.addLambdaDataSource('data_source', func); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { + Type: 'AWS_LAMBDA', + Name: 'data_source', + }); + }); + test('appsync errors when creating multiple lambda data sources with no configuration', () => { // THEN expect(() => {