This repo an example on how to migrate an Amplify App to CDK with a no modification of Amplify side and a minimum of CDK code.
- Amplify app setup
- CDK app init
- Migrate
Table of contents generated with markdown-toc
# here I use a public example but feel free to use yours directly
git clone https://github.com/aws-samples/aws-amplify-graphql.git amplifyApp
cd amplifyApp
amplify add auth
amplify add storage
amplify add api
If you want to test it and deploy it to your own env just run
amplify push
But if you just want to migrate it straight to CDK, just run the following command in order to generate the necessary files needed for the migration
amplify api gql-compile
cd ../
mkdir cdkApp
cdk init --language typescript
npm install
Amplify CLI will generate all it's necessary files under amplify/backend
folder. And the structure will follow a strict pattern:
├── amplify
│ ├── backend
│ │ ├── amplify-meta.json
│ │ ├── CATEGORY
│ │ │ └── INSTANCE_NAME
│ │ │ ├── parameters.json
│ │ │ ├── XXXX-cloudformation-template.json
Where
- CATEGORY is what you put after
amplify add
command when adding stuff such asamplify add auth
whereauth
will be your category. - INSTANCE_NAME is what you give as name in the first question asked by the CLI.
Here is the tree of the current app we are going to migrate:
.
├── amplify
│ ├── backend
│ │ ├── amplify-meta.json
│ │ ├── api
│ │ │ └── cdkdaydemo
│ │ │ ├── parameters.json
│ │ │ ├── resolvers
│ │ │ ├── schema.graphql
│ │ │ ├── stacks
│ │ │ │ └── CustomResources.json
│ │ │ └── transform.conf.json
│ │ ├── auth
│ │ │ └── cdkdaydemo5e0d5323
│ │ │ ├── cdkdaydemo5e0d5323-cloudformation-template.yml
│ │ │ └── parameters.json
│ │ ├── awscloudformation
│ │ │ └── nested-cloudformation-stack.yml
│ │ ├── backend-config.json
│ │ ├── storage
│ │ │ └── s31f5e069a
│ │ │ ├── parameters.json
│ │ │ ├── s3-cloudformation-template.json
│ │ │ └── storage-params.json
│ │ └── tags.json
│ ├── cli.json
│ └── team-provider-info.json
├── package-lock.json
├── package.json
├── public
...
├── schema.graphql
└── src
...
Few elements have to be highlighted here:
parameters.json
store the input paramaters comming from other stack or Amplify CLI input given atamplify add <CATEGORY>
stage*-template.json
or*-template.yml
are the cloudformation templates used byamplify push
to create the nested stack- the root stack is in
awscloudformation
/nested-cloudformation-stack.yml
- its a bit specific for api category api/cdkdaydemo
- cloudformation templates are in build/stacks
- resolvers are in build/resolvers
- appsync api schema is in build/schema.graphql
That are the files we will mainly have to deal with !
- Note your
backend
Amplify folder path from your cdkApp lib folder. We are going to make reference to those amplify files all along the migration
ls ../amplifyApp/amplify/backend
- import the key lib :
@aws-cdk/cloudformation-include
npm install @aws-cdk/cloudformation-include
If your Amplify app is only composed of "simple" categories (which means your backend/CATEGORY/INSTANCE
folder only contains cloudformation templates) then you can directly use the amplify root stack located under backend/awscloudformation/nested-cloudformation-stack.yml
.
Check cdkApp/lib/all-in-one-stack.ts for more details.
If you have "more complex" categories (containing more than cfn templates) then you need to rewrite init resources in CDK:
When running amplify init a stack is executed that create the following resources:
- AuthRole
- UnauthRole
- DeploymentBucket
First step would be to create equivalents in CDK: check cdkApp/lib/amplify-init-resources.ts
Storage is a "simple" category so it can be easily included with cloudformation-include construct: Check cdkApp/lib/storage-nested-stack.ts.
Auth is a "simple" category so it can be easily included with cloudformation-include construct: Check cdkApp/lib/auth-nested-stack.ts. But amplify cli
generated yml
template for this category and for some reason cdk might complains while deploying with an error like
Template format error: unsupported value for AWSTemplateFormatVersion.
The solution: cfn-flip
to convert it to json
cfn-flip ../amplifyApp/amplify/backend/auth/cdkdaydemo5e0d5323/cdkdaydemo5e0d5323-cloudformation-template.yml ../amplifyApp/amplify/backend/auth/cdkdaydemo5e0d5323/cdkdaydemo5e0d5323-cloudformation-template.json
(AppSync) Api is a "more complex" category: it's made of cloudformation, vtl files, potential lambda functions handlers etc. cloudformation-include construct is not enough to handle all that.
check cdkApp/lib/api-nested-stack.ts to see how to leverage s3-deployment
construct to upload the missing artefacts.
Amplify console is providing several services such web hosting and CI/CD.
For CI/CD, now that we are in a CDK app we can either continue using Amplify Console CI/CD and simply create an amplify.yml file to customize CI/CD to now deploy the resources through cdk deploy
CLI instead of amplify push
or we can embrasse CDK capability and move to CDK pipelines.
Same for Web Hosting ...
cdkApp/lib/cdk-frontend-hosting-nested-stack.ts shows a way to create and deploy your frontend to S3 + Cloudfront
cdkApp/lib/cdk-frontend-config-stack.ts shows how to pass backend config to frontend (check amplifyApp/src/index.js to see how the config is dynamically loaded on client side).
I didn't got to the point of adding CI/CD but it is quite easy with cdk pipelines construct but I might in the future.
cdkApp/lib/cdk_app-stack.ts contains the glue between all the element I described here.
After synthesizing your app running the following commands, you should be able to see that the cdkApp/cdk.out/CdkAppStack.template.json
looks a lot like the backend/awscloudformation/nested-cloudformation-stack.yml
, the only difference being the resources logical Ids and way to build nested stacks template Url.
npm run build
npm run cdk synth