Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve the error message caused by the failure of cdk synthesis #2354

Open
zxkane opened this issue Dec 19, 2024 · 1 comment
Open

improve the error message caused by the failure of cdk synthesis #2354

zxkane opened this issue Dec 19, 2024 · 1 comment
Labels
bug Something isn't working deploy Issues related to ampx pipeline-deploy command

Comments

@zxkane
Copy link

zxkane commented Dec 19, 2024

Environment information

System:
  OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
  CPU: (8) x64 Intel(R) Xeon(R) Platinum 8488C
  Memory: 21.59 GB / 30.82 GB
  Shell: /usr/bin/zsh
Binaries:
  Node: 20.18.0 - ~/.nvm/versions/node/v20.18.0/bin/node
  Yarn: 1.22.19 - ~/.linuxbrew/homebrew/bin/yarn
  npm: 10.8.2 - ~/.nvm/versions/node/v20.18.0/bin/npm
  pnpm: 9.6.0 - ~/.nvm/versions/node/v20.18.0/bin/pnpm
NPM Packages:
  @aws-amplify/auth-construct: 1.5.1
  @aws-amplify/backend: 1.9.0
  @aws-amplify/backend-auth: 1.4.2
  @aws-amplify/backend-cli: 1.4.3
  @aws-amplify/backend-data: 1.2.2
  @aws-amplify/backend-deployer: 1.1.11
  @aws-amplify/backend-function: 1.9.0
  @aws-amplify/backend-output-schemas: 1.4.0
  @aws-amplify/backend-output-storage: 1.1.4
  @aws-amplify/backend-secret: 1.1.5
  @aws-amplify/backend-storage: 1.2.4
  @aws-amplify/cli-core: 1.2.1
  @aws-amplify/client-config: 1.5.3
  @aws-amplify/deployed-backend-client: 1.4.2
  @aws-amplify/form-generator: 1.0.3
  @aws-amplify/model-generator: 1.0.9
  @aws-amplify/platform-core: 1.3.0
  @aws-amplify/plugin-types: 1.6.0
  @aws-amplify/sandbox: 1.2.7
  @aws-amplify/schema-generator: 1.2.6
  aws-amplify: 6.10.3
  aws-cdk: 2.173.1
  aws-cdk-lib: 2.173.1
  typescript: 5.6.3
No AWS environment variables
No CDK environment variables

Describe the feature

Got below log for a failure build in Amplify's deployment.

2024-12-15T16:01:40.764Z [INFO]: FileConventionError: File name or path for backend definition are incorrect.
Resolution: Ensure that the amplify/backend.(ts|js) file exists
Cause: Amplify backend",resolution:"Remove all but one `defineData` call"})}DataFactory.factoryCount++}getInstance=__name(props=>{const{constructContainer,outputStorageStrategy,importPathVerifier,resourceNameValidator}=props;importPathVerifier?.verify(this.importStack,path.join("amplify","data","resource"),"Amplify Data must be defined in amplify/data/resource.ts");if(this.props.name){resourceNameValidator?.validate(this.props.name)}if(!this.generator){this.generator=new DataGenerator(this.props,(0,import_convert_authorization_modes.buildConstructFactoryProvidedAuthConfig)(props.constructContainer.getConstructFactory("AuthResources")?.getInstance(props)),props,outputStorageStrategy)}return constructContainer.getOrCompute(this.generator)},"getInstance")}class DataGenerator{static{__name(this,"DataGenerator")}props;providedAuthConfig;getInstanceProps;outputStorageStrategy;resourceGroupName="data";name;constructor(props,providedAuthConfig,getInstanceProps,outputStorageStrategy){this.props=props;this.providedAuthConfig=providedAuthConfig;this.getInstanceProps=getInstanceProps;this.outputStorageStrategy=outputStorageStrategy;this.name=props.name??"amplifyData"}generateContainerEntry=__name(({scope,ssmEnvironmentEntriesGenerator,backendSecretResolver,stableBackendIdentifiers})=>{const amplifyGraphqlDefinitions=[];const schemasJsFunctions=[];const schemasFunctionSchemaAccess=[];let schemasLambdaFunctions={};try{const schemas=(0,import_convert_schema.isCombinedSchema)(this.props.schema)?this.props.schema.schemas:[this.props.schema];schemas.forEach(schema=>{if((0,import_convert_schema.isDataSchema)(schema)){const{jsFunctions,functionSchemaAccess,lambdaFunctions}=schema.transform();schemasJsFunctions.push(...jsFunctions);schemasFunctionSchemaAccess.push(...functionSchemaAccess);schemasLambdaFunctions={...schemasLambdaFunctions,...lambdaFunctions}}amplifyGraphqlDefinitions.push((0,import_convert_schema.convertSchemaToCDK)(schema,backendSecretResolver,stableBackendIdentifiers))})}catch(error){throw new import_platform_core.AmplifyUserError("InvalidSchemaError",{message:error instanceof Error?error.message:"Failed to parse schema definition.",resolution:"Check your data schema definition for syntax and type errors."},error instanceof Error?error:void 0)}let authorizationModes;try{authorizationModes=(0,import_convert_authorization_modes.convertAuthorizationModesToCDK)(this.getInstanceProps,this.providedAuthConfig,this.props.authorizationModes)}catch(error){if(import_platform_core.AmplifyError.isAmplifyError(error)){throw error}throw new import_platform_core.AmplifyUserError("InvalidSchemaAuthError",{message:error instanceof Error?error.message:"Failed to parse authorization modes.",resolution:"Ensure the auth rules on your schema are valid."},error instanceof Error?error:void 0)}try{(0,import_validate_authorization_modes.validateAuthorizationModes)(this.props.authorizationModes,authorizationModes)}catch(error){throw new import_platform_core.AmplifyUserError("InvalidSchemaAuthError",{message:error instanceof Error?error.message:"Failed to validate authorization modes",resolution:"Ensure the auth rules on your schema are valid."},error instanceof Error?error:void 0)}const sandboxModeEnabled=(0,import_convert_authorization_modes.isUsingDefaultApiKeyAuth)(this.providedAuthConfig,this.props.authorizationModes);const propsFunctions=this.props.functions??{};const functionNameMap=(0,import_convert_functions.convertFunctionNameMapToCDK)(this.getInstanceProps,{...propsFunctions,...schemasLambdaFunctions});let amplifyApi=void 0;let modelIntrospectionSchema=void 0;const isSandboxDeployment=scope.node.tryGetContext(import_platform_core.CDKContextKey.DEPLOYMENT_TYPE)==="sandbox";try{const combinedSchema=(0,import_convert_schema.combineCDKSchemas)(amplifyGraphqlDefinitions);modelIntrospectionSchema=(0,import_graphql_generator.generateModelsSync)({schema:combinedSchema.schema,target:"introspection"})["model-introspection.json"];amplifyApi=new import_data_construct.AmplifyData(scope,this.name,{apiName:this.name,definition:combinedSchema,authorizationModes,outputStorageStrategy:this.outputStorageStrategy,functionNameMap,translationBehavior:{sandboxModeEnabled,allowDestructiveGraphqlSchemaUpdates:true,_provisionHotswapFriendlyResources:isSandboxDeployment}})}catch(error){throw new import_platform_core.AmplifyUserError("AmplifyDataConstructInitializationError",{message:"Failed to instantiate data construct",resolution:"See the underlying error message for more details."},error)}const modelIntrospectionSchemaBucket=new import_aws_s3.Bucket(scope,"modelIntrospectionSchemaBucket",{enforceSSL:true,autoDeleteObjects:true,removalPolicy:import_aws_cdk_lib.RemovalPolicy.DESTROY});new import_aws_s3_deployment.BucketDeployment(scope,"modelIntrospectionSchemaBucketDeployment",{memoryLimit:1536,destinationBucket:modelIntrospectionSchemaBucket,sources:[import_aws_s3_deployment.Source.data(modelIntrospectionSchemaKey,modelIntrospectionSchema)]});import_aws_cdk_lib.Tags.of(amplifyApi).add(import_platform_core.TagName.FRIENDLY_NAME,this.name);if(isSandboxDeployment){import_aws_cdk_lib.Aspects.of(amplifyApi).add(new ReplaceTableUponGsiUpdateOverrideAspect)}(0,import_convert_js_resolvers.convertJsResolverDefinition)(scope,amplifyApi,schemasJsFunctions);const ssmEnvironmentEntries=ssmEnvironmentEntriesGenerator.generateSsmEnvironmentEntries({[`${this.name}_GRAPHQL_ENDPOINT`]:amplifyApi.resources.cfnResources.cfnGraphqlApi.attrGraphQlUrl,[`${this.name}_MODEL_INTROSPECTION_SCHEMA_BUCKET_NAME`]:modelIntrospectionSchemaBucket.bucketName,[`${this.name}_MODEL_INTROSPECTION_SCHEMA_KEY`]:modelIntrospectionSchemaKey});const policyGenerator=new import_app_sync_policy_generator.AppSyncPolicyGenerator(amplifyApi.resources.graphqlApi,`${modelIntrospectionSchemaBucket.bucketArn}/${modelIntrospectionSchemaKey}`);schemasFunctionSchemaAccess.forEach(accessDefinition=>{const policy=policyGenerator.generateGraphqlAccessPolicy(accessDefinition.actions);accessDefinition.resourceProvider.getInstance(this.getInstanceProps).getResourceAccessAcceptor().acceptResourceAccess(policy,ssmEnvironmentEntries)});return amplifyApi},"generateContainerEntry")}const REPLACE_TABLE_UPON_GSI_UPDATE_ATTRIBUTE_NAME="replaceTableUponGsiUpdate";class ReplaceTableUponGsiUpdateOverrideAspect{static{__name(this,"ReplaceTableUponGsiUpdateOverrideAspect")}visit(scope){if(import_data_construct.AmplifyDynamoDbTableWrapper.isAmplifyDynamoDbTableResource(scope)){scope.addPropertyOverride(REPLACE_TABLE_UPON_GSI_UPDATE_ATTRIBUTE_NAME,true)}}}const defineData=__name(props=>new DataFactory(props,new Error().stack),"defineData");0&&(module.exports={DataFactory,defineData});
2024-12-15T16:01:40.764Z [WARNING]: ampx pipeline-deploy
Command to deploy backends in a custom CI/CD pipeline. This command is not intended to be used locally.
Options:
--debug Print debug logs to the console
[boolean] [default: false]
--branch Name of the git branch being deployed
[string] [required]
--app-id The app id of the target Amplify app[string] [required]
--outputs-out-dir A path to directory where amplify_outputs is written. If not provided defaults to current process working directory. [string]
--outputs-version Version of the configuration. Version 0 represents classic amplify-cli config file amplify-configuration and 1 represents newer config file amplify_outputs
[string] [choices: "0", "1", "1.1", "1.2", "1.3"] [default: "1.3"]
--outputs-format amplify_outputs file format
[string] [choices: "mjs", "json", "json-mobile", "ts", "dart"]
-h, --help Show help [boolean]
2024-12-15T16:01:40.918Z [ERROR]: !!! Build failed

Spent too much time trying to identify the root cause of the deployment failure in Amplify due to an unclear error message.

Use case

The backend was deployed well via the cli cmd npx ampx sandbox. However, it failed in Amplify Host deployment.

I discovered that the issue was caused by an escape character error when synthesizing the CDK app by overriding the default build command with the --debug switch in the Amplify console. Different environment variables were used in sandbox and production builds which caused the issue.

The CDK clearly indicated the underlying error, but enhancing the error message with additional root causes would expedite troubleshooting.

AmplifyError [InvalidSchemaError]: Syntax Error: Invalid character escape sequence: \'.
at DataGenerator.generateContainerEntry (/codebuild/output/src1506344480/src/game-match-playground/node_modules/@aws-amplify/backend-data/src/factory.ts:172:13)
at SingletonConstructContainer.getOrCompute (/codebuild/output/src1506344480/src/game-match-playground/node_modules/@aws-amplify/backend/src/engine/singleton_construct_container.ts:51:19)
at DataFactory.getInstance (/codebuild/output/src1506344480/src/game-match-playground/node_modules/@aws-amplify/backend-data/src/factory.ts:116:31)
at <anonymous> (/codebuild/output/src1506344480/src/game-match-playground/node_modules/@aws-amplify/backend/src/backend_factory.ts:117:68)
@zxkane zxkane added the pending-triage Incoming issues that need categorization label Dec 19, 2024
@ykethan
Copy link
Member

ykethan commented Dec 19, 2024

Thank you for reporting this. Marking as bug for error improvements.

@ykethan ykethan added bug Something isn't working deploy Issues related to ampx pipeline-deploy command and removed pending-triage Incoming issues that need categorization labels Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working deploy Issues related to ampx pipeline-deploy command
Projects
None yet
Development

No branches or pull requests

2 participants