Now Amplify support CDK export : https://aws.amazon.com/blogs/mobile/export-amplify-backends-to-cdk-and-use-with-existing-deployment-pipelines/ !!!
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 apiIf you want to test it and deploy it to your own env just run
amplify pushBut 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-compilecd ../
mkdir cdkApp
cdk init --language typescript
npm installAmplify 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 addcommand when adding stuff such asamplify add authwhereauthwill 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.jsonstore the input paramaters comming from other stack or Amplify CLI input given atamplify add <CATEGORY>stage*-template.jsonor*-template.ymlare the cloudformation templates used byamplify pushto 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
backendAmplify 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