AWS Partner Network (APN) Blog

How Contino Helped Modernize a Multi-Tier Web Application from On-Premises to Containers Running on AWS

By Matthew Gillard, Lead Consultant – Contino
By Murty Chappidi, Sr. Partner Solutions Architect – AWS

Connect with Contino-1

Contino is an AWS Premier Consulting Partner that helps enterprise customers in their cloud transformation by delivering programs which migrate and modernize their workloads on Amazon Web Services (AWS).

A Fortune 500 customer asked Contino to provide consulting assistance with the migration of an internal-facing, traditional line of business. They wanted to migrate a three-tier web application onto AWS to satisfy key business metrics around resiliency and availability.

Key outcomes for this engagement were to help ramp up the development team’s knowledge of AWS with knowledge transfer, provide a staged migration plan, and kick-start the migration process with a successful proof of concept (PoC) with the expectation the product team would complete the migration.

In this post, we’ll show you how Contino helped modernize this multi-tier web application from being hosted in the customer’s data center to running on AWS. We’ll also cover limitations with the current state, key considerations around the AWS architecture, how to stage the migration approach, and the business benefits post-migration.

Application Overview

Contino’s customer has a traditional three-tier application consisting of a frontend Angular webserver with Windows-integrated authentication, mid-tier .NET API services, and a backend Microsoft SQL database shared with other applications.

This application is used by line of business users in the field for tracking and optimizing critical vehicle location operations and metrics, aggregating business data points from internal data sources, and providing operational shift planning functionality.

The internally-accessed production application is deployed on a single virtual machine (VM) which has a replica disaster recovery VM in a second data center. RabbitMQ is used for communication between mid-tier components and for incoming business-derived data from an external data source.

Figure 1 - Application overview.

Figure 1 – Application overview.

The as-is deployment of the application suffers from several issues, including:

  • The application is hosted on a single virtual machine, so there’s a large scope of impact potentially affecting application availability during code releases, operating system patch deployments, reboots, and operational issues such as low disk space.
  • Because the database is on a shared cluster, it’s prone to unexpected downtime or performance issues if one of the shared database tenants consumes too many resources.
  • Application environment inconsistencies are present, as the different environments run on different versions of Windows Server.
  • Developers execute manual steps during deployments, slowing release velocity.
  • The disaster recovery (DR) environment is passive, so developers need to periodically ensure this backup environment is usable prior to use.

Requirements for Migration

The modernization approach needed to address several key criteria included:

  • It needed to be incremental and low-risk with a low complexity backout, if required.
  • The development team needed to be able to release new features in parallel to the refactoring work for modernization.
  • Components that were tightly coupled needed to be migrated together, as there were aspects of the application that were sensitive to latency.
  • Internal corporate staff needed to retain access though a strategic identity provider.

A common approach to form early decision making around migrating to AWS is to review the six Rs for application migration strategy: re-host, re-platform, re-factor/re-architect, re-purchase, retire, and retain.

After consideration, re-platform was the most flexible and best fit for the requirements. Utilizing managed services where possible moved much of the undifferentiated heavy lifting to AWS and allowed the modernization effort to happen in two independent stages.

Figure 2 – Stage 1: Migration of the mid-tier and database.

Figure 2 – Stage 1: Migration of the mid-tier and database.

Stage 1

Migrate Mid-Tier and MS-SQL Database

Stage 1 of the project involved moving the mid-tier .NET API into Amazon ECS on AWS Fargate and the backend Microsoft SQL server database into Amazon Relational Database Service (Amazon RDS).

The migration team chose to use RDS MS SQL as the database tier in Multi-Availability Zone mode. All technical requirements of the application were satisfied by the RDS offering, and choosing a managed database removed the undifferentiated heavy lifting of running a database platform and operating system.

Because the application could be unavailable for a certain amount of time, the migration of the database was performed by exporting from the existing production database, transferring the SQL data dump file to Amazon Simple Storage Service (Amazon S3) over the AWS Direct Connect link using the new AWS PrivateLink for Amazon S3 released earlier this year.

When the database file is in S3, it’s a simple procedure to import the data into Amazon RDS. Performing these steps though multiple dry-runs ensured the team was comfortable fitting within the business approved outage window.

Alternatively, AWS Database Migration Service (DMS) is a great option for more complex scenarios where outage windows are in seconds or minutes rather than hours.

The customer’s application was written in ASP.NET and all state persists to the database, so running the code in a Fargate-managed container platform where the compute is abstracted and managed by AWS made a lot of sense.

Using AWS Fargate allows each ASP.NET component to run in its own container located in separate AWS Availability Zones (AZs) with its own dedicated vCPU and memory. This also loosens application coupling by separating each component into separately deployable discrete units, which ultimately reduces the scope of impact should a deployment go wrong and need to be rolled back.

One consideration to be aware of when adding extra instances of backend code components is that you need to ensure events are not processed multiple times, so some refactoring may be required depending on your specific requirements.

Writing code in an idempotent manner is important as you scale out. Refer to The Twelve-Factor app for best practices around this topic.

Amazon ECS on AWS Fargate provided integration with the Application Load Balancer, which provides host- and path-based routing services the team used for easy routing of requests to the correct backend microservice.

TLS Certificates

The Application Load Balancer allows for integration with AWS Certificate Manager. This gives you the ability to centrally manage and automatically renew AWS-issued certificates, but the feature we needed was to import a corporate-issued certificate for the application.

Application Message Queues

The customer’s application relies heavily on message passing between frontend, mid-tier, and external services using a self-managed instance of RabbitMQ.

The application developers could have rewritten the entire application to use a combination of Amazon Simple Queue Service (SQS) and Amazon Simple Notification Service (SNS) to get similar functionality as RabbitMQ. For simplicity, the team migrated to the AWS managed Amazon MQ for RabbitMQ, which makes the modernization less complex with no major architectural changes.

Amazon MQ for RabbitMQ also provided out-of-the-box high availability through automatic deployment to multiple AZs.

Figure 3 – Stage 2: Migration of the front end

Figure 3 – Stage 2: Migration of the front end.

Stage 2

Migrating the Frontend

With the backend running on AWS, the team’s focus moved to the frontend.

Like many corporate business applications, the Angular frontend of the application used Windows-integrated authentication with a small backend API which orchestrates tasks with the application mid-tier that’s now running on AWS.

The user authentication was moved to Azure AD with refactoring of the application to allow for this change.

The frontend Angular website and backend API was also moved into containers orchestrated by Amazon ECS on AWS Fargate, and the business addressable DNS name was updated with a CNAME pointing to the front-end container DNS name.

Continuous Improvement

A modernization effort like this is never “done.” As the development team matures in their confidence and expertise with AWS, there are multiple streams of possible future work:

  • Migrate from an MS-SQL database to Amazon Aurora Postgres. This would be a good way to further reduce costs while providing a managed resilient and highly available database platform. Using tools like the AWS Schema Conversion Tool and Babelfish (in preview as of the time of writing) can help with this effort.
  • With this modernized application foundation, over time the application can move business logic to a more serverless model of AWS Step Functions and AWS Lambda functions to further decouple application components. This, in turn, further reduces the scope of impact should problems with a particular business flow occur.
  • Migrate queues from the managed RabbitMQ to more cloud-native SQS- and SNS-based message flows to further reduce costs.

Customer Benefits

In this post, we have shown that it’s possible to modernize a traditional on-premises hosted application by moving it to AWS in a staged and de-risked manner.

With dedicated and flexible compute resources for both Amazon ECS on AWS Fargate and Amazon RDS, application performance was significantly improved and easily scalable to cater for future needs. Application features can be added incrementally without having to deploy the entire application.

Using managed services removes customer operational overhead and shifts this responsibility to AWS, allowing the application developers to focus on improving business features.

Modernizing the application using AWS cloud-native constructs provides the application high availability and removes the operational overhead in managing a DR failover node.


Contino provided AWS expertise and a low-risk staged modernization blueprint to a large enterprise customer’s line of business developers so they could successfully migrate an on-premises application to AWS.

This de-coupled the customer application using managed services while providing improved availability with multiple Availability Zones and resiliency for end users.

Approaching a modernization with these principals sets the team up for success and provides business results sooner. It also gives the development team time to gain the experience necessary to re-factor and improve the modernized application over time.


Contino – AWS Partner Spotlight

Contino is an AWS Premier Consulting Partner that helps enterprise customers in their cloud transformation by delivering programs which migrate and modernize their workloads on AWS.

Contact Contino | Partner Overview

*Already worked with Contino? Rate the Partner

*To review an AWS Partner, you must be a customer that has worked with them directly on a project.