export const meta = { title: `Override Amplify-generated AppSync resources`, description: `The "amplify override api" command generates a developer-configurable "overrides" TypeScript file which provides Amplify-generated AppSync resources as CDK constructs. For example, developers can set api settings that are not directly available in the Amplify CLI workflow, such as X-Ray tracing.`, }; ```bash amplify override api ``` Run the command above to override Amplify-generated GraphQL API resources including AWS AppSync API, Amazon DynamoDB table, Amazon OpenSearch domain, and more. If you need to customize a specific Amplify-generated VTL resolver, review [Override Amplify-generated resolvers](/cli/graphql/custom-business-logic/#override-amplify-generated-resolvers) first. The command creates a new `overrides.ts` file under `amplify/backend/api//` which provides you the Amplify-generated resources as [CDK constructs](https://docs.aws.amazon.com/cdk/latest/guide/home.html). ## Customize Amplify-generated AppSync GraphQL API resources Apply all the overrides in the `override(...)` function. For example to enable X-Ray tracing for the AppSync GraphQL API: ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.api.GraphQLAPI.xrayEnabled = true } ``` You can override the following GraphQL API resources that Amplify generates: |Amplify-generated resource|Description| |-|-| |[GraphQLAPI](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-graphqlapi.html)|AWS AppSync GraphQL API resource| |[GraphQLAPIDefaultApiKey](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-apikey.html)|API Key resource for the AppSync GraphQL API| |[GraphQLAPITransformerSchema](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-graphqlschema.html)|The GraphQL schema that's being deployed. (The output of the GraphQL Transformer)| |[GraphQLAPINONEDS](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|A "none" data source that is used for requests that don't exit the AppSync API| |[AmplifyDataStore](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html)|The delta sync table used for Amplify DataStore's conflict resolution| |[AmplifyDataStoreIAMRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role used to access the delta sync table for DataStore| |[DynamoDBAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to access the DynamoDB resources from AppSync| ## Customize Amplify-generated resources for @model directive Apply all the overrides in the `override(...)` function. Pass in the @model type name into `resources.models[...]` to modify the resources generated for that particular @model type. For example, to enable time-to-live on the Todo `@model` type's DynamoDB table: ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.models["Todo"].modelDDBTable.timeToLiveSpecification = { attributeName: "ttl", enabled: true } } ``` You can override the following @model directive resources that Amplify generates: |Amplify-generated resource|Description| |-|-| [modelStack](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html)|The nested stack containing all resources for the @model type| [modelDDBTable](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html)|The DynamoDB table containing the data for this @model type| [modelIamRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role to access the DynamoDB table for this @model type| [modelIamRoleDefaultPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to access the delta sync table for this @model type in case DataStore is enabled| [dynamoDBAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|Default policy associated with the IAM role to access the DynamoDB table for this @model type| [modelDatasource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|The AppSync DataSource to representing the DynamoDB table| [invokeLambdaFunction](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy for Lambda-based conflict resolution function| For example, you can override a model generated DynamoDB table configuration. ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.models["Todo"].modelDatasource.dynamoDbConfig['deltaSyncConfig']['baseTableTtl'] = '3600' } ``` ### Example - Configure DynamoDB table's billing mode Set the [DynamoDB billing mode](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html#cfn-dynamodb-table-billingmode) for the DynamoDB table. Either "PROVISIONED" or "PAY_PER_REQUEST". ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.models['Post'].modelDDBTable.billingMode = 'PAY_PER_REQUEST'; } ``` ### Example - Configure provisioned throughput for DynamoDB table or Global Secondary Index Override the default [ProvisionedThroughput](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html#cfn-dynamodb-table-provisionedthroughput) provisioned for each `@model` table and its Global Secondary Indexes (GSI). Only valid if the "DynamoDBBillingMode" is set to "PROVISIONED" ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.models['Post'].modelDDBTable.provisionedThroughput = { readCapacityUnits: 5, writeCapacityUnits: 5 } /** * When billing mode is set to "PROVISIONED", it is necessary to specify `provisionedThroughput` for every Global Secondary Index (GSI) that exists in the table. */ resources.models["Post"].modelDDBTable.globalSecondaryIndexes[0].provisionedThroughput = { readCapacityUnits: 5, writeCapacityUnits: 5 }; } ``` ### Example - Enable point-in-time recovery for DynamoDB table Enable/disable [DynamoDB point-in-time recovery](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-pointintimerecoveryspecification.html) for each `@model` table. ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.models['Post'].modelDDBTable.pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true } } ``` ## Customize Amplify-generated resources for @searchable (OpenSearch) directive Apply all the overrides in the `override(...)` function. For example, to modify the OpenSearch instance count: ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig = { ...resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig, instanceCount: 6 } } ``` You can override the following @searchable directive resources that Amplify generates: |Amplify-generated resource|Description| |-|-| [OpenSearchDataSource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|The AppSync data source representing the OpenSearch integration| [OpenSearchAccessIAMRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role to access OpenSearch domain| [OpenSearchAccessIAMRoleDefaultPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to access OpenSearch domain| [OpenSearchDomain](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticsearch-domain.html)|OpenSearch domain containing the @searchable data| [OpenSearchStreamingLambdaIAMRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role to stream DynamoDB data to OpenSearch domain| [OpenSearchStreamingLambdaIAMRoleDefaultPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to stream DynamoDB data to OpenSearch domain| [CloudwatchLogsAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy for granting CloudWatch logs access| [OpenSearchStreamingLambdaFunction](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)|Lambda function to stream DynamoDB data to OpenSearch domain| [OpenSearchModelLambdaMapping](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html)|Event source mapping for DynamoDB table stream to Lambda function| ### Example - Configure Runtime for Streaming Lambda You can define the runtime for the `@searchable` by setting the runtime value on the function object itself. This can be done to resolve a deprecated runtime in the event that you cannot upgrade your version of the Amplify CLI. ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchStreamingLambdaFunction.runtime = 'python3.9'; } ``` ### Example - Configure OpenSearch Streaming function name Override the name of the AWS Lambda searchable streaming function ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchStreamingLambdaFunction.FunctionName = 'CustomFunctionName'; } ``` ### Example - Configure OpenSearch instance version Override the `elasticsearchVersion` in the OpenSearch domain created by `@searchable` ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchDomain.elasticsearchVersion = 'OpenSearch_1.3'; } ``` ### Example - Configure OpenSearch instance type Override the type of instance launched into the OpenSearch domain created by `@searchable` ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig = { ...resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig, instanceType: "m3.medium.elasticsearch", }; } ``` ### Example - Configure OpenSearch instance count Override the number of instances launched into the OpenSearch domain created by `@searchable` ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig = { ...resources.opensearch.OpenSearchDomain.elasticsearchClusterConfig, instanceCount : 2 }; } ``` ### Example - Configure OpenSearch EBS volume size Override the amount of disk space allocated to each instance in the OpenSearch domain created by `@searchable` ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.opensearch.OpenSearchDomain.ebsOptions={ ...resources.opensearch.OpenSearchDomain.ebsOptions, volumeSize:10 } } ``` ## Customize Amplify-generated resources for @predictions directive Apply all the overrides in the `override(...)` function. For example, to add a Path to IAM role that facilitates text translation: ```ts import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'; export function override(resources: AmplifyApiGraphQlResourceStackTemplate) { resources.predictions.TranslateDataSourceServiceRole.path = "/my/organization/" } ``` You can override the following @predictions directive resources that Amplify generates: |Amplify-generated resource|Description| |-|-| |[RekognitionDataSource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|AppSync HTTP data source to connect to Amazon Rekognition service| |[RekognitionDataSourceServiceRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|AppSync service role to connect to Amazon Rekognition| |[TranslateDataSource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|AppSync HTTP data source to connect to Amazon Translate service| |[translateTextAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to connect to Amazon Translate| |[LambdaDataSource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html)|AppSync Lambda data source to connect to Amazon Polly| |[LambdaDataSourceServiceRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|AppSync service role to connect to Lambda function calling Amazon Polly| |[LambdaDataSourceServiceRoleDefaultPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy for AppSync to connect to Lambda function calling Amazon Polly| |[TranslateDataSourceServiceRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|AppSync service role to connect to Amazon Translate| |[predictionsLambdaIAMRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role for Lambda function calling Amazon Polly| |[predictionsLambdaFunction](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)|Lambda function calling Amazon Polly| |[PredictionsLambdaAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy for Lambda function to access Amazon Polly| |[predictionsIAMRole](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)|IAM role to access s3 bucket used by @predictions| |[PredictionsStorageAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to access S3 bucket used by @predictions| |[identifyTextAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to enable Identify Text| |[identifyLabelsAccess](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html)|IAM policy to enable Identify Text| ## Place AppSync Resolvers in Custom-named Stacks If you have a particularly large GraphQL schema, you may run into issues with too many resources defined in a stack. The most common case where this happens is in the ConnectionStack which contains the resolvers for all of the relational directives in the schema. Creating a stack mapping does not create an additional root stack for the Amplify environment. All mapped stacks will still be placed under the existing Amplify environment root stack. To map a resolver to a different stack, update `/amplify/api//transform.conf.json` with a "StackMapping" block. The StackMapping defines a map from resolver logical ID to stack name. ```json { "Version": 5, "ElasticsearchWarning": true, "StackMapping": { "": "Custom stack name", } } ``` The easiest way to determine a resolver logical ID is to run `amplify api gql-compile` and note the resolver logical ID in the list of Resources in the generated CloudFormation stack. Resolvers for model operations will be of the form `Resolver`. Resolvers for relational directives are of the form `Resolver`. ### Example Given the following schema: ```graphql type Blog @model { id: ID! name: String! posts: [Post] @hasMany } type Post @model { id: ID! title: String! content: String blog: Blog @belongsTo } ``` To map the CreatePostResolver and the relational resolvers to a stack named 'MyCustomStack', add the following in `transform.conf.json`: ```json "StackMapping": { "CreatePostResolver": "MyCustomStack", "BlogpostsResolver": "MyCustomStack", "PostblogResolver": "MyCustomStack", } ```