Use CDK to add custom AWS resources
The Amplify CLI provides the ability to add custom AWS resources with AWS Cloud Development Kit (CDK). Running the amplify add custom
command in your Amplify project provides CDK starter stacks along with mechanisms to reference other Amplify-generated resources.
The AWS Cloud Development Kit (AWS CDK) is an open source software development framework to define your cloud application resources using familiar programming languages, such as Typescript.
amplify add custom
? How do you want to define this custom resource? … (Use arrow keys or type to filter)❯ AWS CDK AWS CloudFormation
A skeleton CDK stack is generated in the amplify/backend/custom/<resource-name>
directory. Edit the cdk-stack.ts
file to define the additional AWS resources. Add additional CDK constructs using the package.json
. Run amplify build
to download all npm dependencies for this custom resource and synthesize the CDK stack.
The following example creates an SNS topic whose notification messages are forwarded via email:
import * as cdk from 'aws-cdk-lib';import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';import { Construct } from 'constructs';import * as sns from 'aws-cdk-lib/aws-sns';import * as subs from 'aws-cdk-lib/aws-sns-subscriptions';
export class cdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) { super(scope, id, props); /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */ new cdk.CfnParameter(this, 'env', { type: 'String', description: 'Current Amplify CLI env name', });
const amplifyProjectInfo = AmplifyHelpers.getProjectInfo(); const snsTopicResourceName = `sns-topic-${amplifyProjectInfo.projectName}-${cdk.Fn.ref('env')}`; const topic = new sns.Topic(this, 'sns-topic', { topicName: snsTopicResourceName, });
topic.addSubscription(new subs.EmailSubscription('<your-email-address>')); new cdk.CfnOutput(this, 'snsTopicArn', { value: topic.topicArn, description: 'The arn of the SNS topic', }); }}
Note: Always append the Amplify environment name to a resource name to ensure correct behavior with Amplify's multi-environment workflows.
Reference Amplify project and environment name
Amplify provides you helper functions to get Amplify project information such as the project name and the current Amplify environment name.
Reference Amplify project name
Use the AmplifyHelpers.getProjectInfo()
function to retrieve the project name:
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
// ...
const projectName = AmplifyHelpers.getProjectInfo().projectName;
Reference Amplify environment name
There are two access patterns for the environment for two different use cases. Using the right access mechanism for the right use case is critical to ensure multi-environment workflows function properly.
If you want to use the environment name as a variable for a resource, use cdk.Fn.ref('env')
:
const role = new iam.Role(this, 'CustomRole', { assumedBy: new iam.AccountRootPrincipal(), roleName: `${roleResourceNamePrefix}-${cdk.Fn.ref('env')}` // Reference to Amplify "env" name})
If you want to apply conditional logic based on the current environment name, use AmplifyHelpers.projectInfo()
:
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
// ...
const envName = AmplifyHelpers.getProjectInfo().envName;
if (envName === "prod") { // ...} else { // ...}
Reference Amplify-generated resources
The CDK stack for custom AWS resources can reference Amplify-generated resources' CloudFormation outputs. To reference another resource, first add the resource as a dependency.
import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref";
const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this, amplifyResourceProps.category, amplifyResourceProps.resourceName, [{ category: "function", // api, auth, storage, function, etc. resourceName: "<resource-name>" // find the resource at "amplify/backend/<category>/<resourceName>" } /* add more dependencies as needed */] );
Then use the cdk.Fn.ref
function to create a dynamic reference of the dependencies' outputs.
const myFunctionArn = cdk.Fn.ref(dependencies.function.<resource-name>.Arn)
The dependencies
variable has the auto-generated AmplifyDependentResourcesAttributes
type which includes all Amplify-generated resource output. Run amplify build
to regenerate AmplifyDependentResourcesAttributes
if you don't see your category, resource, or parameters.