React Build Settings on Amplify

man jumping on intermodal container

The technology stack that was inherited from the prior tech team at Research Blocks came with some outdated methodologies. One of those areas was in the deployment of React applicationa on EC2 instances. For Single Page Applications (SPAs), like React, there are better options for rapidly deploying a scalable production app. The Amplify environment also makes it very easy to stand up multiple instances of the application container. These canrepresent different builds such as a development, staging, or test environments.

While there is plenty of documentation available on how to go about building an React app, there is very little on problem solving or details on what is going on “inside the black box”. This article is a collection of notes on what was found delving deeper into the AWS tech stack for Amplify.

Amplify Hosting

The first thing to know about Amplify is it is a hosting service for STATIC WEB ASSETS; as they like to say “Amplify Hosting provides a git-based workflow for hosting full-stack serverless web apps with continuous deployment.”. In other words, it does not work like a traditional web service such as Apache or nginx.

Amplify uses CI/CD to continually monitor your repo, clone that code when a branch changes, run commands specified in the Amplify console Build settings, and copies the files out to a CDN. From here, Amplify serves up the entire thing as a static web page. For React apps that typically means it zips up your build folder including an index.html loader and stack of JavaScript files compiled via a utility such as webpack.

This also means it is not going to do well with actively listening to incoming web request. Amplify is not going to play a good host as an Express server. There are ways to do it using Lambda functions and some additional configuration that will be content for another article.

Build settings and Amplify.yml

Build settings determine what commands are run to build your app after the code repo has been cloned. Normally this includes the install command to install a million mostly-useless node files into your project; These files are necessary so it can leverage twenty-lines of actual useful functions needed to make your JavaScript app work. The build command then links all that code together, runs through something like Webpack to rip out lot of that useless previously-downloaded Node code, and ends up with a somewhat useful app for your customers.

While you can enter the various commands in the YML formatted Build settings on the Amplify console, learn from my mistakes and instead put an amplify.yml file in your source root directory. That way when you inadvertently tell it to start the node server within the build file you can go back and look at an older commit and revert to the working copy of the file.

Regardless of which method you use, a simple Amplify.yml (Build settings) should look similar to the following image.

What To Put In Build Settings

The build settings should only contain the commands that are needed to download required code libraries and subsequently compile the code into a set of static files. This is where your React app’s package.json comes into play; package.json will tell Node which modules are needed for the yarn install command (we use yarn vs. npm) as well as how to build the static files for the SPA with the yarn build command. In our case, run webpack and set some environment parameters.

What NOT To Put In Build Settings

Do NOT put in any commands that START a node server into the build settings. The build manager for Amplify looks for any specified commands to finish executing. Starting a node server runs a command that , as far as the “build monitor” is concerned, never finishes.

The following is an ASSUMPTION about how Amplify works. I have yet to see official documentation that states the following…

LC

Remember, Amplify is going to stand up a static website for you. Along the way it will setup an https/http listener and route traffic to your Single Page Application accordingly. There is no need for a node server in this situation. Amplify is going to take over the responsibility for the apps it hosts.

Artifacts

Not super well documented, but again based on observations and assumptions, the main setting here is the baseDirectory. This tells the Amplify build manager “copy all the files under the specified directory and go through them out on the CDN as a static file set”. The subsequent files specification is a ‘stack’ of file paths you want included where the **/* specification means “any file in this directory and anything under it”.

Amplify’s build manager seems to us this setting to execute a zip command which grabs all the files in the directory and files list specified, zips them up and distributes it to the CDN.

Cache

The cache section tells Amplify which directories and files to carry over from one build to the next. While most of the building/distribution manager services on Amplify start with a fresh container, anything in the cache appears to be copied from one build to the next.

Almost all the Amplify documentation cites putting node_modules/**/* in this list to save the previously-mentioned yarn install command from having to download the same million-plus node files on every build. Instead it copies them from one container to the next saving all those electrons from flying around Internet servers to recreate the files every time. Instead the electrons all stay within Amazon’s borders and maybe speeds things up a bit.

On to bigger & better things… next up trying to see if we can trick Amplify into hosting an Express server WITHOUT lambda proxy functions.

AWS LEMP Stacks and EFS Issues

Lesson learned — if you are using EFS on production systems you want to be using provisioned throughput mode.

But, before we get into that, let’s go over the details of this implementation…

Service Configuration

We utilize AWS EC2 instances to run multiple WordPress sites hosted in different directories. The configuration is fairly standard: 2+ servers configured as part of an load-balanced cluster. The servers run from the same image meaning they use the same underlying software stack.

Part of that image includes a mounted EFS (Elastic File Storage) directory , used to share WordPress resources between all nodes in the cluster. The original architecture was designed to host not only the typically-shared wp-content/uploads folder of WordPress via this EFS mount but also the code. The thought was that sharing the code in this way would allow a system admin to easily update WordPress core, plugins, or themes from the typical wp-admin web login. Any code updates would immediately be reflected across all nodes.

EFS Web App Code Hosting – A Bad Idea

Turns out this is a bad idea for a few reasons. First of all, EFS volumes are mounted using the NFS4 (network file storage) protocol — this defines how the operating system handles file read/write operations for a network mounted drive. While NFS4 is fairly robust, the throughput of ANY network drive, even on a high speed AWS data center backbone, is much slower than a local drive such as an EBS volume.

That means that even on a good day every PHP file, JavaScript file, or anything else needed to serve up that WordPress web page are going to be a bit slower than normal.

However, the bigger problem comes to light if you happen to choose the default, and pushed as “the mode to use” by Amazon, EFS throughput mode known as “Burst mode”.

Read More

Converting A Standalone Instance Into An EC2 Load Balanced Cluster

Creating a new web application that resides on an AWS load balanced cluster is easy with the Elastic Beanstalk assistant. That is a great solution if you want to run every web service or application on their own instances. It is not a great fit for complex environments like the one being used for Store Locator Plus®.

Store Locator Plus® has several environments running within the same master domain. Multiple servers and load balancers creates a security certificate nightmare. Not too mention it starts racking up EC2 server fees quickly if they each became their own cluster. The better option is to retain a server instance that allows us to run our SaaS offering, our buy-and-own plugin store, our documentation site, and our demo site from a single disk image. We want to setup a full EC2 Load Balanced Cluster to gain the benefits of horizontal scaling on a server hosting multiple domains and web apps.

While this is easy to do with a single EC2 instance that hosts multiple host names for the storelocatorplus.com domain, making it scalable under load is the trick. It turns out Elastic Beanstalk is not a good fit. Instead we need to build a load balanced cluster “from scratch”. We’ll need to combine a machine image from a running server with a Launch Template. We will need an Application Load Balancer that will have instances attached and detached automatically from an Auto Scaling Group that we will also create.

Our environment also has a configured EC2 instance to run the web application stacks, mostly WordPress, locally on an EBS volume that uses an Amazon Aurora MySQL RDS database in multiple zones for performance and reliability. These two features make it easy to replicate the disk image for the software portion and maintain a persistent DB store across all instances.

Read More

Alibaba An AWS Threat? Not Quite

A recent Seeking Alpha article proposes the theory that Alibaba could threaten Amazon’s AWS cloud services.

Amazon has been my best investment by far.

The article has some great information about the cloud services industry. It includes a lot of facts and figures that ring true. I disagree with this article’s overall assessment, however.

Alibaba will erode AWS market share in Asia but few other regions. They are a Chinese company. I would never use them myself nor recommend the Alibaba cloud solution to my clients because of this.

China has a history of banning content and restricting the free flow of information — especially on the Internet. Shutting down a business on the Alibaba cloud and taking over the assets of anything they deem “inappropriate” or “propaganda” is well within the realm of possibility. Why would any business add that to their risk factors when you have AWS as an alternative.

Not too mention Amazon continues to innovate and introduce services at a dizzying pace. The dollars spent on investment only matters if it yields results. Based on the service offerings alone, Amazon is 10 times further ahead in this space than the closest competitor.

I’m maintaining a hold position on AMZN despite the growing popularity of Azure, Google Cloud, and Alibaba.

seekingalpha.com/article/4202935-amazons-aws-faces-another-threat

Install A Name.com SSL Cert On Amazon Linux

Get Your Certificate Signing Request (CSR)

From Amazon Linux:

cd /etc/ssl
openssl req -new -key vim <domain>.<tld>.key -out <domain>.<tld>.csr

Buy Your Certificate

From Name.com purchase a cert for either a wildcard or single-host fully-qualified domain name.  It must match the domain identifier . used when creating your CSR.

You’ll need the contents of the .csr file and private key you created above.

Read More

%d bloggers like this: