5 new Amplify features to take your app to any scale
Just before re:Invent 2021, AWS launched a set of new features for Amplify. Get a rundown of 5 new features from Michael Liendo of the AWS Amplify team.
Jun 08, 2023 • 7 Minute Read
Just before re:Invent 2021, AWS launched a set of features for Amplify that both simplify and enhance how customers build their applications while both prototyping and deploying to production. In this post, Michael Liendo (Senior Developer Advocate at AWS Amplify), talks about five of those features to better understand their use cases and how to get started!
Accelerate your career
Get started with ACG and transform your career with courses and real hands-on labs in AWS, Microsoft Azure, Google Cloud, and beyond.
What is AWS Amplify?
AWS Amplify is a suite of tools aimed at front-end developers wanting to create full stack applications on AWS. Using its CLI, customers can use terminal prompts to automate writing their application’s backend.
The Amplify libraries and pre-built components allow for a seamless frontend-to-backend solution, and applications can be hosted on Amplify Hosting with a few clicks.
Lastly, customers can ideate on their data models in our Admin UI without even having to have an AWS account.
The best part is that the suite of products integrate with one another so that they can be used as a whole, or as a single offering, depending on the needs of your team.
Here are five new Amplify features to help take your app to any scale.
1. Override Amplify generated resources
Many customers love that Amplify generates default configurations when adding resources like Cognito user or identity pools, or S3 buckets. However, we understand that organizations can have different compliance and governing standards. For that reason, we introduced a new command to the CLI: amplify override <category>
.
This takes in the specified category and creates a TypeScript file where the resource can then be accessed and reconfigured to your needs. Common scenarios we’ve heard from our customers include enabling a TTL on an AWS DynamoDB table items, and setting an existing function as the trigger to migrate Amazon Cognito users from one user pool to another.
In the case a user were to type amplify override storage
, with a few lines, bucket versioning can be enabled.
import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyS3ResourceTemplate) {
resources.s3Bucket.versioningConfiguration = {
status: 'Enabled',
}
}
It’s worth pointing out that the new @aws-amplify/cli-extensibility-helper
module seen in the above code snippet is automatically installed and the proper import statement is automatically handled by the CLI.
2. Add custom resources with the AWS CDK
Out of the box, Amplify supports adding AWS services such as AppSync, Lambda, S3, Cognito, Fargate, API Gateway, Amazon Location maps, and more all through its CLI. However, customers often want to add other services depending on the application they’re building and the requirements to build it.
Fortunately, instead of adding all 175+ services to our CLI, we instead introduced a new command: amplify add custom
This command supports resources created via the AWS CDK (TypeScript) and AWS CloudFormation.
Now, the simplicity of the Amplify ecosystem and the vastness of the AWS ecosystem to come together in a single project.
The below code snippet shows how an SNS topic can be created with a name that includes both the project name, and the Amplify environment.
import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import * as sns from '@aws-cdk/aws-sns';
import * as subs from '@aws-cdk/aws-sns-subscriptions';
export class cdkStack extends cdk.Stack {
constructor(scope: cdk.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 projectName = AmplifyHelpers.getProjectInfo().projectName;
const topic = new sns.Topic(this, 'sns-topic', {
topicName: `sns-topic-${projectName}-${cdk.Fn.ref('env')}`
});
topic.addSubscription(new subs.EmailSubscription("<your-email-address>"));
}
}
Pro tip: Combine custom resources with custom IAM policies for Lambda!
3. Lambda and container support for custom IAM policies
Amplify natively supports the creation of both Lambda functions, and Fargate containers via its CLI. Often times, customers will need to integrate preexisting resources, created outside of the Amplify ecosystem. For this reason, we now generate a custom-policies.json
file whenever a Lambda or container is created:
[
{"Action": ["s3:CreateBucket"],"Resource": ["arn:aws:s3:::${env}my-bucket"]},
{``"Action"``:`` ``[``"iam:GetPolicy"``]``,``"Resource"``:`` ``[``"arn:aws:iam:::policy/*"``]``}
]
This simple file takes in array of policies and automatically applies them to the execution role of the corresponding function or container.
It’s worth pointing out that while the Effect
is allow
by default, policies can be set to deny
as well. In addition, note that wildcards are supported as well as adding in the current Amplify environment, which is handy for multi-environment scenarios.
4. Custom command hooks
Whether it is ensuring a specific version of the Amplify CLI is used, or wanting to send out a slack notification to your team when a build succeeds or fails, custom command hooksare the solution.
When initializing a new Amplify project, we now generate an amplify/hooks
directory. In this directory, the filenames take a “when-what” approach. For example, a file named pre-push.js
will run before a project is pushed up to AWS. Additionally, a file named post-add-function.js
will run after a function has been successfully added to a project using the amplify add function
command.
Revisiting the use case of wanting to enforce a specific version of Amplify, the code to do so would look like this:
const fs = require('fs');
const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));
// Get the running Amplify CLI major version number
const currentCLIMajorVersion = parameters.data.amplify.version.split('.')[0]
console.log('Amplify CLI major version: ', currentCLIMajorVersion)
const MINIMUM_MAJOR_AMPLIFY_CLI_VERSION = 5
console.log('Minimum required Amplify CLI major version: ', MINIMUM_MAJOR_AMPLIFY_CLI_VERSION)
if (currentCLIMajorVersion < MINIMUM_MAJOR_AMPLIFY_CLI_VERSION) {
// Non-zero exit code will stop the Amplify CLI command's execution
console.log('Minimum CLI version requirement not met.')
process.exit(1)
} else {
console.log('Minimum CLI version requirement met.')
process.exit(0)
}
It’s worth noting that in addition to JavaScript, build hooks also support shell scripts by default, and custom scripting runtimes like python can be enabled as well!
5. Export your Amplify backend as a CDK stack
Our last item on the list!
This feature allows for the utmost flexibility, but I’ll add that it is advanced and was created with a particular customer in mind. So while most customers will never need this ability, it further strengthens the position that Amplify can be used for production applications.
amplify export
By running this command, the Amplify CLI will export your entire Amplify backend as a CDK stack. This can then be brought into an existing CDK pipeline, and deployed alongside the rest of your infrastructure.
Note that this is not ejecting out of Amplify. This command can be ran many times while an Amplify project is being iterated on.
Exporting an Amplify project is simple, though let’s see what it looks like to integrate the generated stack into an existing pipeline by looking at a sample stage:
import { CfnOutput, cfnTagToCloudFormation, Construct, Stage, StageProps } from '@aws-cdk/core';
import { AmplifyExportedBackend } from '@aws-amplify/cdk-exported-backend';
import * as path from 'path'
import * as cdk from '@aws-cdk/core'
export class AmplifyStage extends Stage {
constructor(scope: Construct, id: string, props?: StageProps) {
super(scope, id, props);
// ADD AMPLIFY EXPORTED BACKEND STACK HERE
const amplifyStack = new AmplifyExportedBackend(this, "amplifyexportedbackend", {
path: path.resolve(__dirname, '..', 'amplify-export-mytodoapp'),
amplifyEnvironment: "dev"
})
}
}
This should look familiar to CDK developers if they’ve deployed a pipeline before. Note that the @aws-amplify/cdk-exported-backend
package handles the necessary bindings.
More details can be found on the documentation page.
Conclusion
In this post we looked at the newly released features that allow Amplify applications to be more extensible. This is in addition to features such as the ability to import existing resources into your Amplify project.
Now, not only do customers have finer-grained control with features like custom build hooks, but the ability to override and add resources mean less time in the AWS Console, and more time focusing on building out your product.
For more information on AWS Amplify visit our docs page, and to stay up to date with me, you can follow me on Twitter.
About the author
Michael Liendo is a Senior Developer Advocate @ AWS Amplify. You can follow him on Twitter @mtliendo.
Keep up with all things cloud by following A Cloud Guru on Twitter and Facebook, subscribe to A Cloud Guru on YouTube for weekly updates, and join the conversation on Discord. You can also check out our current crop of free courses!