Blog
AWS
Cloud
Business
7
minutes

Implementing Microservices on AWS with the Twelve-factor App – Part 2

Welcome to the second post in a series of “Implementing Microservices on AWS with the Twelve-factor App”. In the first post, we covered the areas around the codebase, configuration, code packaging, code builds, and stateless processes.  This article will go through the remaining areas for best practices in microservices.  Let’s start the discussion with Port mapping!
Morgan Perry
Co-founder
Summary
Twitter icon
linkedin icon
Note that the best practices mentioned are from the perspective of containerized microservices, so some of the tips may apply exclusively to container-based applications.

Port mapping

One of the best practices for containerized applications is that the application should be a self-contained app and not dependent on the execution environment to provide web server capabilities. That means the application should have an innate capability to install the webserver and bind to a port on the container. The best way to accomplish that is by exporting HTTP as a service and binding it to a container port so that it starts listening for any incoming requests on that port. Its implementation is language-agnostic; however, the solution will use dependency declaration to include a web server library in the application. Note that we have already discussed in the previous article that dependencies should be installed along with the code as portable services.

Talking specifically of containerized applications, the binding can be achieved through the “Expose” command in the docker file. Through ECS task definition, you can map the container port with the host port. AWS ECS has provided support for dynamic port mapping as well. You can follow this official AWS article for details.

This solution can be further explained by the image below. If you look at it, you can see that, based on the URL, the request is routed to a particular service (distinguished by the port it has binding to). Multiple services with unique port bindings are running on a single container. And multiple containers can run on a single host (EC2 or Fargate). Note that the load balancer can divide the calls between different services listening on different ports. You do not necessarily specify the service name and port number; the ELB will automatically manage it through routing to the target group.

null

Concurrency

The area of concurrency is more about scalability than the concurrency itself. The guideline is that your application should be able to scale out instead of scale up and that too on the process level. So, instead of replicating your whole application, your individual microservices and the processes which are running the microservices should be able to scale individually, based on the load on that particular type of service.

In ECS, this can be achieved through ECS task count at the service level. You specify the minimum number of ECS tasks that should be running all the time to ensure it can handle the load. You should set the count to at least two so that if one task is failed, the other one can keep serving the requests, and the failed task will be automatically restarted as well.

The task count in each service can be increased or decreased based on the scalability needs.

If you look at the image below, you can see that this application has three kinds of processes: web, worker, and clock. Based on the workload, it should be perfectly possible to scale just one type of process i.e. Worker. It will be just another container running in its own process in the container world. That makes this solution scalable and self-contained, which results in more concurrent processing. Implicitly to say, the capacity of the host is also a factor regarding how much concurrent processing can be performed. The beefier the host is, the more processing it can perform.

Source: https://www.netsolutions/insights/wp-content/uploads/2021/02/co,currency-rule-of-12-factor-applications.jpg

Disposability

One advantage of containerized microservices is that the containers have built-in capability for disposability. That means the instances of a service (deployed in container) can be removed, scaled, and redeployed quickly without data loss. If you look at the point related to “Backing services” discussed in previous article, you can see that external data providers (database, cache etc. ) help you achieve that. The guideline states the following:

  • The shutdown should be graceful, and it should also handle abrupt termination. Please see this official article for achieving a graceful shutdown on AWS ECS. It is the responsibility of the container to finish any existing requests which are in progress. Also, it needs to stop accepting new requests as well.
  • You should be able to spin up and remove service instances quickly, without any delay. For fast startup of docker containers, you can follow this AWS article on achieving fast startup.
  • Service instance should be able to withstand sudden failure.

Dev/Prod Parity

The twelve-factor app recommends that all the production and non-production environments be as similar as possible. That means following should possibly be the same across all the environments:

  • Database. Ideally, the production database should be synced back to the staging or UAT database as frequently as possible, at least on a weekly basis. This is especially important in data-intensive applications.
  • Backing services. Apart from database, any caching solution or any cloud-based data store like firebase should also be used with a non-production environment same way it is used with production.
  • Integration. Third-party integrations should also be integrated into the staging and UAT environment in the same way as the production.
  • Tools. The tools used for production should also be used for the non-production environment. That includes the IDE, testing tools, scripts, etc.

The above measures will ensure that the testing in non-production environments is close to the testing in a real environment. Find below a brief comparison between a traditional app and a twelve-factor app in terms of Dev/production parity.

Source: https://spearkerdeck.com/astraya/how-to-build-2-factor-application-in-nodejs-using-docker

Once again, containerization provides a natural solution to handle this. In the previous article, we had mentioned single code base, one container image deployments to multiple environments. So building once, and deploying many times is the key here. The same docker image can be used across all the environments.

Logs

The application itself should not manage application logs. The process of processing and routing the logs should be separate from the application. Consider the scenario where the application process is terminated due to some reason, and if the same service/process manages logs, then the logging would also be terminated. So logging should be implemented as a separate service and should run in its own process, separated from the core application.

null

If you look at the image above, you will see that the logging agent is implemented as a separate process away from the application itself. The storage, capture, and archival are not the application's responsibility. The application will just transmit the logs to the logging agent as long as the application is running. In other words, the application has outsourced the logging features to another component (logging agent).

For AWS ECS, you can mention the awslogs log driver in your task definition under the logConfiguration object. This will transmit the stdout and stderr I/O streams to your desired log group in CloudWatch logs.

Admin Processes

Any admin or maintenance tasks should not be part of the core application; they should be in a separate process, preferably in an environment identical to the application itself. In containerized applications, one of the strategies to achieve this is through the use of sidecar patterns. Such tasks include data migration, daily email reporting, syncing data from production to staging, etc.

In ECS, you can make use of scheduled ECS tasks. This admin ECS task should be in its own container and run as a separate single process. After the Adhoc job is completed, it will gracefully exit.

Conclusion

In this article, we discussed areas of port binding, concurrency, disposability, dev/production parity, logging, and admin processes according to twelve-factor guidelines. Containerized microservices are becoming popular because of their built-in support for scalability, lightweight, reliability, resilience, etc. We also evaluated how to make the best use of AWS ECS to support these best practices. However, implementing containerized microservices on AWS requires more than basic knowledge and technical expertise. This is where Qovery comes in. You can take advantage of all the benefits of containerized microservices that too implement the twelve-factor methodology without worrying about the technical complexity of container-based microservices.

Share on :
Twitter icon
linkedin icon
Ready to rethink the way you do DevOps?
Qovery is a DevOps automation platform that enables organizations to deliver faster and focus on creating great products.
Book a demo

Suggested articles

DevOps
 minutes
The Top 10 Porter Alternatives: Finding a More Flexible DevOps Platform

Looking for a Porter alternative? Discover why Qovery stands out as the #1 choice. Compare features, pros, and cons of the top 10 platforms to simplify your deployment strategy and empower your team.

Mélanie Dallé
Senior Marketing Manager
AWS
Deployment
 minutes
AWS App Runner Alternatives: Top 10 Choices for Effortless Container Deployment

AWS App Runner limits control and locks you into AWS. See the top 10 alternatives, including Qovery, to gain crucial customization, cost efficiency, and multi-cloud flexibility for containerized application deployment.

Mélanie Dallé
Senior Marketing Manager
Kubernetes
 minutes
Kubernetes Management: Best Practices & Tools for Managing Clusters and Optimizing Costs

Master Kubernetes management and cut costs with essential best practices and tools. Learn about security, reliability, autoscaling, GitOps, and FinOps to simplify cluster operations and optimize cloud spending.

Mélanie Dallé
Senior Marketing Manager
AWS
GCP
Azure
Cloud
Business
10
 minutes
10 Best AWS Elastic Beanstalk Alternatives

AWS Elastic Beanstalk is often rigid and slow. This guide details the top 10 Elastic Beanstalk alternatives—including Heroku, Azure App Service, and Qovery—comparing the pros, cons, and ideal use cases for achieving superior flexibility, faster deployments, and better cost control.

Morgan Perry
Co-founder
Kubernetes
DevOps
7
 minutes
Kubernetes Cloud Migration Strategy: Master the Shift, Skip the Disaster

Master your Kubernetes migration strategy with this expert guide. Learn the critical planning phases, mitigate major risks (data, security, dependencies), and see how Qovery simplifies automation and compliance for a fast, successful, and reliable transition.

Morgan Perry
Co-founder
SecurityAndCompliance
DevSecOps
 minutes
Qovery Achieves SOC 2 Type II Compliance

Qovery is officially SOC 2 Type II compliant with an Unqualified Opinion. Get the highest assurance of continuously verified security controls for enterprise-grade application deployments and simplify due diligence.

Pierre Mavro
CTO & Co-founder
Product
Observability
 minutes
Troubleshoot Faster with the New Log Search and Filtering in Qovery Observe

Following the launch of Qovery Observe, we’re progressively adding new capabilities to help you better monitor, debug, and understand your applications. Today, we’re excited to announce a major improvement to the Logs experience: you can now search and filter directly within your application logs.

Alessandro Carrano
Lead Product Manager
Platform Engineering
DevOps
Terraform
7
 minutes
Top 5 Crossplane Alternatives & Competitors

Go beyond Crossplane. Discover Qovery, the #1 DevOps automation tool, and 4 other IaC alternatives (Terraform, Pulumi) for simplified multi-cloud infrastructure management and deployment.

Morgan Perry
Co-founder

It’s time to rethink
the way you do DevOps

Say goodbye to DevOps overhead. Qovery makes infrastructure effortless, giving you full control without the trouble.