Monorepo Amplify Project with Shared Backend

Luke McCampbell
7 min readOct 18, 2020

--

How to setup a monorepo amplify project with multiple front ends and a shared backend.

Overview

This is a brief walk-through of how to setup a monorepo with 2 amplify front end projects and a shared backend. The project being built is not setup for production, and is built just to show how to setup the repo and push it to Amplify/AWS.

Assumptions

  • Have Amplify CLI installed and configured with a profile. (If you haven’t just do the quickstart (https://docs.amplify.aws/start/q/integration/vue). It’s quick and will get you up on the basics.
  • Know how to setup a git repo in your online hosting service of choice.
  • Have AWS setup and have a basic understanding of Amplify and Amplify Console. (Just having worked through the Quickstart from the docs is enough).

Notes

  • This walkthrough is not touching Auth. Again this app is insecure and shouldn’t be used for a production site.
  • The code for this project is at https://github.com/huntsfromshadow/amplify-monorepo-example
  • There were a number of articles and docs that helped me figure this out. They’ll be all credited at the end though I’ll put references in the text.

What is being built?

The project will build a small project. One will be a VueJs message board wall that will allow displaying and submitting messages. The other will be a Gridsome static site that will just show the messages.

1. Setup Your Monorepo Repository

Create an empty git repo for your monorepo. In our case this is called amplify-monorepo-example. Create and clone it to your local system.

In our case we are using the branch main, but it dosen’t matter as we will only have 1 branch for this example.

2. Install needed npm packages

We will need VueJS cli and Gridsome CLI. As of the time of this writing vue/cli is version 94.5.7 and gridsome cli is version v0.3.4.

npm install -g @vue/clinpm install -g @gridsome/cli

3. Setup the VueJS App and Backend

First we build the vuejs app. vue create vue-example
For the options use: Default ([Vue 2] babe, eslint.)

Next go into the vue-example directory and setup amplify by runningamplify init. For the options use the defaults and whatever editor you use. It should autodetect you are using Vue. For profile use whatever profile you have setup.

Lets get the graphql API setup.

Go ahead and add api to the backend. Remember to run this in the vue-example directory.amplify add api
For the options use the default except for the ones mentioned below:

  • Description for key — Your choice
  • Do you want to edit the scheme? — Your choice either have amplify load your editor or edit it after the script is done.

Now if you haven’t already edited the shcmea file, edit (or replace)
vue-example/amplify/backend/api/vueexample/schema.graphql with the file or schema from — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/project-schema.graphql

When that is done run amplify push from the vue-example directory. Accept all the defaults.

Congrats you have the backend setup.

4. Get the VueJS App working

All this code is really simple and actually is modified from the Quickstart. For the sake of ease we aren’t going to delete any files from the starter project just override the parts with our code.

First you’ll need to install the aws-amplify package. npm install --save aws-amplify

After that installs replace the following files with the code below.

For src/main.js — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/vue-example/src/main.js

For src/App.vue — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/vue-example/src/App.vue

The App is good to go. You can test it with npm run serve to bootup the vuejs and test it.

A webpage with a single message on it saying Hello from User 1. Two text fields and a ‘create post’ button.
The VueJS example app running

5. Setting up the Gridsome App and tying it to the Backend

Return to the root of the repo and run gridsome create gridsome-example

Now we are going to tie this project to the backend app we made earlier.¹

Once it is done from inside the gridsome-example directory run amplify pull
Use the default options with the specific changes below:

Do you want to use an AWS profile — Yes
Which Profile — Pick the profile you used in Step 3.
Which App — Pick the app you named in Step 3 (likely vueexample)
This is the important one:
Do you plan on modifying this backend - No

Before you scroll off the screen look at the ID code amplify printed when you picked the app. Take a note of that you’ll need it below.

Now we add codegen. Use that app ID code in place of the XXXXX.

From the gridsome-example directory.

cp ../vue-example/src/graphql/schema.json .
amplify codegen add --apiId XXXXX

For the options use the default except for framework say None.

Okay you’ve got the schema transferred to the app.

Make sure you setup aws-amplify npm install --save aws-amplify

Replace the following files in the gridsome app.

gridsome-example/gridsome.config — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/gridsome-example/gridsome.config.js(This is to fix an issue with mjs compiling )²

gridsome-example/src/main.js — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/gridsome-example/src/main.js

gridsome-example/src/pages/Index.vue — https://github.com/huntsfromshadow/amplify-monorepo-example/blob/main/gridsome-example/src/pages/Index.vue

Finally run gridsome develop and the app will be up and running. It should show any messages you submited in the VueJs app.

Finally as the gridsome app is going to be a frontend only app. We need to submit our aws-exports file into git. Their may be a way to have the CI system generate it, but I haven’t figured it out yet.

So edit gridsome-example/.gitignore and comment out or remove the line with aws-exports.js. Add and recommit to git and you should see aws-exports.js added.

WARNING: The exports file has the endpoint for your app, and your API Key. Be aware of that if you are submitting that file into a public repo. Unforuntley though this data needs to be available to the front end grindsome app so it can run. A solution may be using amplify pull in headless mode during the ci build script, but I haven’t worked that out yet.

6. Pushing up to AWS

We need to make sure the monorepo is up to date as the amplify continuions build system will pull from that to deploy.

First make sure your mono repo is committed and pushed up to your git host. Then go into AWS Amplify console.

At this point you should only see your vueexample app. If you go in you’ll see it is backend only.

From the front-end tab do the following.

  1. Pick your git hosting provider and click the connect branch button.
  2. Pick your monorepo (in this case amplify-monorepo-example).
  3. Pick your main branch.
  4. Click the checkbox and for ‘connecting a monorepo’.
  5. In the root directory textbox put vue-example and click the ‘Next’ button.
  6. Accept the default build settings (we’ll replace them with a single one later), and click the ‘Next’ button. Depending on your AWS setup you may need to make a service role. Just follow the instructions it is pretty straight forward.
  7. Click ‘Save and Deploy’.

Let AWS work. It should deploy and start running. The project in the amplify console will have a link you can use to test the app.

Now get the Gridsome app build and deply up to AWS. Go back to ‘All Apps’ in the amplify console and click the ‘Connect App’ button.

Go through all the steps again but change the following 2 things.

  1. For the root directory field entergridsome-example
  2. For the build settings edit them so the prebuild command, the build command, and the base directory match the suggested gridsome settings. (https://gridsome.org/docs/deploy-to-amplify/)

Let AWS work and deploy the app.

And you can test it with the link in the console.

7. Done

That is it. The repos are up and running and work. If you make a push it will trigger a CI for both and it will build and deploy both. You can fix this by placing a common amplify.yml file in the root directory of the repo.

That way the CI system will launch a build and stop after provision when it realizes their are no changes. It still though increments the build counter showing a build was ‘canceled’.

NOTE: As of writing this article you must put the shared build file AFTER both apps are deployed. Doing it before will cause the console to assume both apps are the 1st app listed in the file. This has been marked as a design issue with the current monorepo approach.³

A amplify.yml file for this project is in the code repo as amplify.yml.old.

8. Cleanup

It is AWS so their are parts of this app sitting throughout the account.

To cleanup you can delete the gridsome app from the aws console. To delete the vue app from the vue-example directory run amplify delete and that should remove most of the items.

I would still suggest checking the following areas in the aws web console for anything delete missed (or couldn’t delete).

  • IAM Roles
  • AppSync
  • Dynamo DB
  • S3
  • Cloud Formation

Summary

So with that we have 2 apps running linked through 1 repo and a shared backend. Thanks for the various articles linked below (and the amplify docs and AWS docs) let me merge this into a single set of instructions.

References

[1] Swaminator’s gist showed me how to setup the backend sharing. https://gist.github.com/swaminator/6270806f38048552af9ce699a568a581

[2] Thanks to this post by Nobuyuki Ukai I was able to solve a webpack issue with not compiling the mjs files. https://blog.u-chan-chi.com/post/gridsome-amplify-auth/

[3] The link to the information about needing to put the amplify.yml after the apps are deployed. https://github.com/aws-amplify/amplify-console/issues/827

--

--