Launching a new application should be exciting, but with all of the options available, the last thing you want to spend too much time on is configuration and infrastructure.
Tools like Heroku, AWS Elastic Beanstalk, Render, and others are great for getting started – but, in the long run, can lead to some tough decisions.
Migrating away to develop a new feature can be very difficult. There are also cost concerns with allowing someone else to manage your infrastructure, as a price change from your provider may hit your business with unsustainable expenses or a need to migrate immediately.
As DevOps consultants at Test Double, we often encounter applications where the growth is stunted because of the early selection of a cloud platform.
This post is designed to help take the first step into building a platform for a 3-tier application your team can own and modify on a cloud provider, in this case AWS, without having to staff a full DevOps team.
That way, your developers can stay focused on developing but still have the full set of available tools AWS provides available to them for future growth of the application.
Keys to choosing the right tools within AWS
As a consultant I've had multiple opportunities with various clients to help set up new infrastructure in areas where a full Infrastructure or DevOps team wasn't part of the near-term growth plans for the client.
I've come to understand that there are a few priorities when deploying a new application that help motivate my choices for which products and resources to use within AWS.
1. Costs need to be clearly communicated and easy to understand.
With some features provided to simplify application deployment in the cloud, it can be hard to understand where they're coming from or why you're paying for them.
It can be even more disheartening when your monthly bill goes from $10 to $1,000 with no warning – and even more so when understanding the course of that cost growth will take days to resolve, all while racking up new charges.
A few tips to make informed decisions about cost:
- Avoid using tools which obfuscate what clients are paying for.
- Create resources which can be easily tracked with predictable pricing structures
- Establish processes for reacting to cost changes quickly.
2. Look for resources with substantial existing documentation to minimize time developers need to solve their cloud problem.
Clients need to understand their application's infrastructure and be able to debug, develop, and upgrade without a significant time or knowledge investment in the infrastructure itself.
To that end, avoid all-in-one solutions. These can inhibit growth or impact decisions, which will restrict the rate of future growth of an application.
The ideal scenario is to choose a platform that is not likely to be deprecated.
Seek out DevOps tools with extensive existing documentation – and even other examples where possible – to minimize the time developers need to answer questions, solve the cloud problem and then get back to doing what they do best: developing applications.
3. Record any changes with clear and precise documentation.
No matter what cloud platform you choose, changes will be needed.
Documenting the why and how in a way that can be easily digested and modified are fundamental to helping an application grow and scale with you.
Don't just document the tools you're using. Document growth items, likely areas for cost growth, cost mitigation strategies, and similar tools.
Terraform architecture examples
With those goals in mind, I've built an example architecture using Terraform to give you a strong starting point and included some GitHub Actions workflows that will give a strong Continuous Integration/Continuous Deployment (CI/CD) framework.
Front End
AWS S3 Static Site Hosting serves as a great starting point for getting your page(s) into the world. They are cost effective, easy to maintain, easy to modify, and, with the addition of AWS CloudFront, can also help manage your SSL certificates keeping your site HTTPS compliant.
The provided template environment is also readily scalable and easy to expand to multiple testing environments in parallel to your production environment.
Backend
The backend is deployed on AWS ECS Fargate. Fargate allows a good balance of cost and management while integrating scalability and reliability to allow your developers to modify this to meet the demands of your customers. The environment also allows for a growth path and can be replaced by dedicated EC2 instances or Kubernetes as your organization grows. This container driven service allows for you to configure your application's environment to your needs. Containers also allow for easier testing and maintenance of your application. This container based backend is deployed across multiple availability zones, with a load balancer to distribute requests, health checks, and a template for auto-scaling.
The GitHub Actions workflow template also introduces Trivy, an open source security scanner, to validate the security of your containers.
Database
Amazon Relational Database Service (AWS RDS) offers an array of solutions to meet your database access requirements. Making sure you have the right configuration for your use case can save both time and money when deploying an application.
The provided template includes two example PostgreSQL database configurations. The development environment is configured to run on a single AWS RDS instance. This is designed to keep costs down while you develop your application. In order to maintain a more reliable environment for a production application, including backups, cross-availability zone integration, and failover databases, an AWS Aurora Environment is also included.
CI/CD
One of the keys to keep developers focusing on your application, and not on the infrastructure, is to have a clear and concise process from getting your code to the cloud. I've included templates for some of the more areas where developers may be less familiar: CI/CD Templates.
Environment deployment
In order to facilitate deployment of the cloud environment I've created a pipeline based on Andrew Walker's blog post to help make the Terraform release and update process more readable. Andrew does an excellent job explaining this entire process and I recommend reading that blog post as you venture into infrastructure as code workflows
Container creation and deployment
This workflow is a simple Docker build, security check, and push process. This can be modified to include testing or other steps as necessary.
Static Site Deployment
This workflow duplicates your application's build output to the S3 static bucket.
API Access
Site availability and security are two features core to the success of your application. When taking ownership of your own cloud environment it is important to know these targets are always changing. I've incorporated some AWS and other tools to keep your site online, and help you control access. The static site incorporates some basic WAF features using AWS Cloudfront, such as region blocking. I've chosen to use AWS's API gateway as the primary access point for the backend. API gateway provides additional resources for security and scalability.
Room to grow
There are challenges to owning your own cloud infrastructure, and, as with all software development, choosing the right tool is important.
This environment is designed to give you a head start to managing your own infrastructure allowing more room for growth without backtracking. This can also serve as a stepping stone from more managed environments to a fully owned cloud deployment.
Need DevOps help or to set up new infrastructure? Our consultants have worked with everyone from startups to Fortune 100 companies to some of the largest Rails codebases on the planet. [We offer free personalized business consultations. Schedule one here.