Gatsby: automating builds with AWS Amplify
What is Gatsby?
Gatsby is a static site generator that uses React as its main underlying technology. It has attracted the attention of many people very quickly because of its main characteristic: performance.
And Gatsby is snappy, really fast. Just navigate through the Gatsby website to see for yourself. Since it works as a PWA, it loads just the files needed to render the current page and prefetches the ones around so you don't wait long for their load.
Even though I primarily considered Gatsby for building blogs (for now), its use could be extended to almost any other types of websites and apps because it is managed by React.
As we are looking for alternatives to eventually rewrite and migrate our blog section and website, we’ve given it a go.
Decoupled by nature
This representant of the (relatively new) known like JAMStack provides out-of-the-box the tools needed to interact with your backend app through GraphQL.
It didn’t take me long to build a Drupal 8 site in Pantheon that I would use to write my blog posts making use of a Wysiwyg editor and excellent tools like Paragraphs to work as data source of my Gatsby app!
Another great point about Gatsby is the amazing work they’ve done to offer literally hundreds of plugins of any type that makes any integration extremely easy, and the creation of code examples to use them.
So, at this point - and after a few hours - I had finished my blog prototype with…
- Drupal jsonapi module to provide API access to my data (blogs).
- Gatsby source-drupal plugin to pull the data from the Drupal API through the built-in GraphQL plugin.
...and some blog posts!
As any other client app the deploy will just involve the upload of the files to a Static web host. In our case, we used a S3 bucket and AWS amplify.
Automating build with Amplify
But… performance comes at a price. The JAMStack is based in markup prebuilding at deploy time. That means once your Gatsby site has been built, any new article or change within an existing one won’t be reflected unless you deploy your app again...
What can we do?
- Using a plugin or standard React components and routing to create dynamically rendered pages. This would mean jumping to a different approach (hybrid apps) and losing some of the benefits of the stack (performance).
- Manual builds and deploys after any change in the content we want publish. Probably the worst option, especially if the content builders don’t have easy access to the tools to build and deploy (or they shouldn’t).
- Using a Continuous Delivery tool (eg. Jenkins) to automate the build and deploy of the app when updated content is detected. This way, we can keep the advantages explained so far without having to involve further resources other than writing posts. Our choice ;)
Finally, we opted for AWS Amplify Console, another tool part of the AWS world ecosystem, to set our automation plan as it is really easy to configure and use, and it met our requirements perfectly. Amplify Console is a CD and hosting service specially designed for JAMStack (and generally any modern) apps. You just need to connect to your app through your repo (hosted in Bitbucket, GitHub, etc) and it will automatically detect your app settings, previously configured with the Amplify CLI. Besides, it provides other cool features like atomic deployments and screenshots of your app in different devices to make sure everything works as intented. Another advantage of this approach is you don't need to keep constantly running a server to host a CD tool like Jenkins for sporadic deployments.
Once we've connected our app with the Amplify Console we just need a click to build and deploy the latest version of our blog with up to date content. Now, we can programatically trigger the job to build our app in the Amplify console making use of a Lambda function and the AWS SDK:
Though the lambda function isn't intrinsically needed, it will give us more control over the process (e.g. we'll be able to check when the last job was run and avoid carrying out multiple deploys in a too short period of time) and it could be used as a gateway for any of our Amplify apps in the future.
Now, in our Drupal backend we can create a small custom module to call our lambda function when a blog content update takes place. We'll be able to whether we request the function as an API endpoint with an API Gateway or directly invoking it with the SDK again:
When the job triggered by our Drupal site is finished, the content will be updated in our Gatsby site :)