Amplify2terraform
Proof-of-concept for replacing Amplify CLI with Terraform & Serverless
Install / Use
/learn @tgroshon/Amplify2terraformREADME
amplify2terraform
This repo is a proof-of-concept for using Amplify client libraries with Terraform (and serverless for Lambda functions) rather than Amplify CLI and Console.
See my blog for an explanation of why: https://tommygroshong.com/posts/appsync-cognito-cloudfront/
Prereqs
Install the following tools:
Setup AWS API credentials: aws configure
Build
The build workflow is as follows:
- Terraform infrastructure:
cd terraformterraform init(only needed the first time)terraform apply
- Deploy serverless function:
cd serverlessserverless deploy -v
- Build and push react app:
terraform output -state=terraform/terraform.tfstate aws-exports-file > src/aws-exports.jsyarn buildaws s3 sync build s3://<YOURBUCKET> --cache-control max-age=300
Overview
Infrastructure
My terraform scripts are in terraform/ and the resources are organized thusly:
main.tf: Variables, Outputs, and Data resourcesapi.tf: DynamoDB; AppSync API, Data Sources, and Resolvers; IAM permsauth.tf: Cognito Identity Pool, User Pool, User Groups, Clients, and IAM roleswebsite.tf: S3 website bucket, CloudFront distribution, Route 53 Record
Serverless functions are in services/. The code is just a dummy example. The serverless.yml
however shows a few useful examples:
- Giving access to DynamoDB tables
- Outputting your function ARNs so you can plug them into terraform as variables
When using these scripts in a non-toy app, I create multiple terraform workspaces
and separate <stage>.tfvars files for use with each. Not beautiful, but works.
Client
The client app was bootstrapped with Create React App.
It uses the AppSyncClientSDK which is an Apollo compatible client; just pass it to
your provider: <ApolloProvider client={client} />.
The pattern that Amplify and AppSync give you for configuring the Clients is having a
src/aws-exports.js file that is ignored from git and contains all your configuration
details for AppSync, Cognito, etc. My code does the same pattern except uses terraform
to generate that file:
terraform output aws-exports-file > ../src/aws-exports.js
That was a trick I picked up for generating Kubeconfig files after setting up Kubernetes.
So after creating your infrastructure with terraform, you should generate the latest
aws-exports.js file.
NOTE: Generate the latest aws-exports.js file for your target stage before bundling code!
Your bundled code will essentially be hardcoded to point at whatever stage/environment
was referenced by aws-exports.js at the time of bundling. Notice in the instructions
above on how to build and push react app it has you write the src/aws-exports.js
first. Those few lines are should go in a deploy script.
