Having built a personalized Todo App with a GraphQL API in Part 1 and Part 2 with the help of the AWS Amplify CLI using Angular and the tools of Nx we have actually quite a lot of time on our hands.
We didn't have to build Authentication and Authorization, we did not have to think about how to set up a workspace for additional future apps or team-mates in mind, we saved on writing lengthy GraphQL schemas with pagination, filtering, input objects, resolvers and ownership and we wrote everything in code to easily push an entire backend environment to the cloud.
Personal Growth with Git Flow and AWS Amplify Console - Part 3
We feel good about our life's choices! Free time to concentrate on our health and personal growth! So, we go to a seminar on the weekend to listen to a famous life coach. It is a great speech, were we learn how to be thankful and appreciate everything in life. He encourages everyone to tell the group about the things we are thankful for. So, as we are feeling good, we actually stand up and tell everyone about our achievements. About writing a personalized todo-app, thinking big about future plans and other team mates. We also shared our thoughts about our plans on publishing the app worldwide, adding git flow and continuous integration. Of course, we couldn't leave out the concept of "You build, you own it" and how we can iterate fast by easily spinning up service-full cloud environments by writing a few powerful Amplify and Angular commands.
Talking about "two-pizza-teams" crosses our minds, but we quickly dismiss the thought, not wanting to go down the rabbit-whole of healthy nourishment.
We're not sure how much we made sense to everyone in the room, but the coach was extremely excited! Setting personal goals for ourselves and checking them off, when completed is a great way to empower us for greater things. Building things and taking the responsibility for it, while continuously integrating that flow into our lives will connect us to our environment in the "here and now" and beyond the clouds. Staying service-full while giving commands will amplify our personal growth.
Wow, we did not expect this response at all! Being experienced in hallway chats on summits and conferences we stay to talk to the speaker afterwards. He lets us in on his plans to build an online life coaching platform to share videos, articles and documents. Chat groups between paying members and an app to track personal goals should also be a part of this offering.
He sais, he likes the way we are thinking ahead. Having a production ready todo-app with these wonderful tools in our belt, we are the perfect candidates to build up a small team to take up this endeavor.
After exchanging our social media contact information, we promise to send him a link to our web app. On our way home we start to think about how to quickly get our todo-app published worldwide. We could use the amplify hosting
command to simply setup a static website, but since we feel like we will need to publish several staging environments and branches in the future, we decide on using the git-flow workflow.
Setting up a complete CI/CD pipeline is usually a non-trivial task, but since the introduction of Amplify Console it got cut down to a few minutes.
Preparing the repo
OK, let's start where we last left off. We have a GIT repository hosted at GitHub with a single master branch. We have a single Amplify environment called 'master', when we previously ran amplify init
and amplify push
.
We want to end up with two permanent git branches 'master' and 'develop'. These branches should be each connected to a similar named amplify stack in the cloud. The information about our cloud resources should be stored in each branch.
We can add a new cloud environment by typing amplify init
and choosing No when asked, if we want to use an existing environment and develop as the new name. The next question will be about our AWS profile we want to use, so we choose the one we used for master as well.
Working in a non-open-source-team, we should revert the change we made in part one, where we put team-provider-info.json in .gitignore
. Looking into this file, we will see our newly created develop environment added.
So far, we have
- one 'master' git branch locally and on origin
- two backend environments 'master' and 'develop' in
team-provider-info.json
- one 'master' backend environment stack pushed to the cloud ('develop' env only locally so far)
Creating another app in our workspace
We don't have a requirement for another app yet, but as we created a workspace, that supports multiple apps connected to one backend, we feel the urge in our belly to test this out anyways.
We make it quick (remembering that we covered the process quite thoroughly in part 1) by typing ng g app second-app
and accepting all defaults. A few more adjustments are needed:
- Adding 'global' to
polyfills.ts
- Importing the css theme in
styles.css
- Concatinating the AppsyncModule to the imports array in
app.module.ts
- Prepending the content of
app.component.html
with<amplify-authenticator></amplify-authenticator>
on line one - Appending another build command to
package.json
's scripts section:"build:second": "npm run rename:aws:config || ng build second-app --prod; ng build second-app --prod"
Once we make sure this runs locally with ng serve second-app
and npm run build:second
, we commit and push the changes to the 'master' branch.
Adding Git-Flow
Since we decided to use git-flow and like to have an opinionated workflow, we agree to install a helper library for guidance on our Mac. We can come back to this cheat sheet at any point, if we run into unknown git-flow territory.
brew install git-flow-avh
and being on the root level of our workspace we run
git flow init
while keeping all defaults. Doing this, we end up on a new develop branch, which we can push to our source control provider by using this command
git push -u origin develop
Not much changed here. We simply have a new branch 'develop' without any new commits.
AWS Amplify Console
We are ready to start our CI/CD pipeline. We go to AWS Amplify Console and click on the CONNECT APP button.
Four simple steps to set up our build and deploy pipeline:
Step 1 - Add repository service
Selecting our GIT provider and giving Amplify Console read-only permission
Step 2 - Add repository branch
Picking our repository and the 'master' branch from the dropdown options
Step 3 - Configure build settings
As App name we like 'amplified'. Both backend environments from team-provider-info.json
should be detected. We have an option to create a new environment right here, which we could reuse in Amplify CLI by importing it later on, but we set up our two environments earlier. So, we pick the 'master' environment in this step.
We need to select a service role in our AWS account. If we don't have existing one, we can create a new one so Amplify Console may access our resources.
We can edit the yaml build settings file and set custom Environment variables for any secrets, that don't belong in source control. AWS offers some variables for usage in our build scripts, like
- AWS_JOB_ID
- AWS_APP_ID
- AWS_BRANCH
Step 4 - Review
Well, ... we review and click Save and deploy
Adding the 'develop' branch
Completing these four steps should have started our build for 'master'. And while waiting for it to finish, we can take a deep breath or two and behold the powers of our fingertips.
Feeling calm and refreshed we return to connect our second branch 'develop' to the equally named backend. This time only needing to go through two steps:
Step 1 - Add repository branch
Step 2 - Review
So far, our todo-app's branches master and develop are connected to Amplify Console. Anytime we git push
to either of those branches, we will see our frontend update at the edge and our backend resources synced with our code from our repo.
Amplify Console region support
What if Amplify Console does not support our region yet? Depending on when we are trying this, the region we chose when we configured the Amplify CLI might not be supported by the Amplify Console yet. No Biggy, choosing a supported region of Amplify Console, we can add a line right before the amplify push
command in the build script:
backend:
phases:
build:
commands:
# replace {our-region} with the previously used region
- echo -e "[default]\nregion={our-region}" > ~/.aws/config
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
This will set our region in the default AWS profile on the current build container instance.
Deploying a second app
Looking at the build script in Amplify Console, we see a way to specify a single frontend app and a single backend stack per git branch. The frontend app will end up at a URL unique to a specific branch, like https://master.ourappid.amplifyapp.com
and the backend stack will create unique resources in a region with a similar naming schema. But we would like a URL for each app on the same branch, i.e.
https://master.app-one.ourappid.amplifyapp.com
https://master.app-two.ourappid.amplifyapp.com
https://master.app-x.ourappid.amplifyapp.com
Unfortunately, this is currently not possible.
Amplify Console seems to be designed so that we can connect an "Amplify Console"-App to a git repository very simply. Different frontends and backend stacks are configured or connected via git branches. This allows us to deploy our full stack app to various staging environments, like production, develop, test or feature sandboxes.
What about creating a new Amplify-Console-App-Connection to the same repo?
Trying to connect another app in Amplify Console, we will quickly see, that we can't choose the same repository again. Picking a different region and connecting an app from the same repo is a workaround, that would work, but we are not very happy with managing this in the future.
But there's another option to connect an app, which we can explore to see if it could help us:
One-Click Deploy Button
Very recently AWS added a new feature, the One-Click Deploy Button to deploy a GitHub repository to Amplify Console. A single click on a button and the repo is deployed in our AWS account. We can use it to share our open source project with the world or onboard a new team mate in minutes! Depending on how quickly our todo-app grows, this might come quite handy, when new recruitments arrive.
We can put it in README.md files or in blog posts, so here is our button to the corresponding repo:
Clicking this button opens a new browser tab with our region and GitHub link encoded in the URL:
https://{aws-region}.console.aws.amazon.com/amplify/home#/deploy?repo={github-url}
When clicking the Connect to GitHub button, we type the name 'amplified-again' and after reviewing almost nothing, we will have our GitHub repo's default branch connected to a new backend environment stack called 'amplify'. Indeed, very simple and quick!
Reusing the newly created 'amplify' backend
Once the connection and the build #1 completed, we could tell our Amplify CLI about this new backend environment, so we could reuse it. Or as in our case, since we want our existing backends, we want to delete the newly created stack.
Finding the Backend build step in the Build activity will reveal the needed information and instructions:
Selecting the 'More Info' button will give us an amplify cli command to run in the root of our project:
After we do this, the 'amplify' backend environment will end up in our team-provider-info.json
file ready to be chosen on our command line.
$ amplify env list
| Environments |
| ------------ |
| amplify |
| master |
| *develop |
The copied command includes the aws profile 'default', so we should remember to adjust this to our profile name, if needed
We could just use it and commit the changes to GitHub, but we want to delete this backend stack in the cloud and locally.
amplify env remove amplify
This looks a little bit weird, asking amplify to remove itself... Well, the result is in, nothing broke!
$ amplify env list
| Environments |
| ------------ |
| master |
| *develop |
Almost nothing, if we would run the build in the Amplify Console, we would see it fail, having removed the backend under its nose.
Reusing our previous 'master' backend
So where we're at right now? We have a second "Amplify Console"-App connected to the same repo. The default master branch uses the newly created (and secretly deleted) 'amplify' backend environment, but we want to reuse the same 'master' and 'develop' backend environments as in our original "Amplify Console"-App.
To do this, we have to disconnect the master branch in App settings: General:
Once done, we can connect our 'master' and 'develop' branches to the equally named environments.
One-Click Deploy the second app
The build-settings are still building our first app. To change this, we go to App settings: Build settings to see, that we have to grant access to our GitHub repository.
And this is where we realize that we can actually deploy repositories from others without the necessity to fork them first!
To build and deploy the second frontend app, we edit two lines in the yaml file:
version: 0.1
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build:second # <-- Change to second app
artifacts:
baseDirectory: dist/apps/second-app # <-- Change to second app
files:
- '**/*'
cache:
paths:
- node_modules/**/*
After saving the build settings and hitting the Redeploy this version button in both branches, we're all set!
Violà!
Adding another frontend app works with the help of the one-click-deploy-button! When we push new code to either our 'master' or 'develop' branch, both apps will build and deploy everything.
Playfully exploring new features of Amplify Console showed us a way we can add further frontend apps to our backend. Apps like admin-consoles, customer-views, support-tickets, manager-charts and so on are possible. Even if we might find this route too complicated or limiting in the future, we still have the means to use the build-settings in our first-app to install, build and deploy anything, like we were used to before Amplify Console came out.
Recap
We feel confident to pursue further development with AWS Amplify. We understand the connection between our repo, the branches and the backend environments. Onboarding new team mates will be a joy.
We could have used the pipeline functionality of our favorite git provider to continuously deploy our static websites to S3 and CloudFront and manually writing the commands to deploy the backends. We would still benefit from the typical AWS features like
- Globally available CDN hosting
- Free SSL certificates
- Serverless backends
Having created and built several build pipelines in the past, we can appreciate the simplicity of using Amplify Console to host our serverless full stack app, but what else have we gained?
- Easy custom domain setup with Route53
- Atomic deployments
- CDN invalidation
- Password protected feature branches
- Screenshots of the app on different mobile resolutions
Ok, we're getting excited - time to calm down, close our eyes, picture a big smile on our face and take a deep breath or two...
Top comments (0)