From On-Prem Monolith to Modern AWS in 10 Weeks
A fast-growing healthcare services provider needed to migrate from an aging on-premises infrastructure to AWS — without disrupting the hospitals that depend on their services every day.
Growth Was Outpacing Infrastructure
Hospitals don’t get to go offline. When an anesthesia services company is managing care for surgical patients across multiple facilities, the systems supporting that work need to be available around the clock.
This company had grown fast. What started as a small operation had expanded to serve hospitals and surgery centers across the U.S. But their infrastructure told a different story. About 90% of their systems were still running on-premises in a monolith architecture. Their small IT team — skilled but stretched thin — had started experimenting with AWS by running a subset of their development environment in the cloud. But they’d carried the same monolith patterns with them, and the problems followed.
A Well-Architected assessment revealed the full picture — and made clear how much needed to change.
What We Found
The assessment uncovered serious gaps across security, reliability, and operational efficiency:
Security was the most urgent concern. The application code contained 19 hardcoded secrets — passwords and credentials embedded directly in the codebase. The code scanners also flagged 197 potential SQL injection vectors through string-based query construction. Nine production instances had public IP addresses, and one had every port open to the internet. Database encryption was inconsistent — some databases had it, others didn’t.
Reliability was fragile. No databases were configured for multi-availability-zone failover. There were no automated snapshots, no lifecycle management for backups, and no monitoring alarms. The basic monitoring logs were already showing degradation — HTTP 500 errors that could indicate application failures or system health issues, but nobody was being alerted.
Operations were manual and risky. There was no CI/CD pipeline — deployments were manual. No infrastructure-as-code meant every change was a one-off. A single AWS account was being used for both development and production, violating least-privilege principles. The team had no automated way to test, deploy, or roll back changes.
The existing infrastructure was expensive to maintain and actively putting the business at risk.
Nerd Talk: Assessment Details
The assessment followed the AWS Well-Architected Framework across all six pillars. Key technical findings:
- Compute: 12 provisioned instances (3 turned off but consuming resources), 5 different network firewall groups, no autoscaling configured
- Data: 4 PostgreSQL databases with low-capacity configs, inconsistent encryption, no multi-AZ, no enhanced monitoring, only 7-day backup retention
- Application code: Python-based main application with critical secrets-in-code violations, XML parsing vulnerabilities, and extensive technical debt in code complexity
- Networking: Security groups were inconsistent — some instances filtered by IP (but allowed all ports), others allowed any IP on specific ports. No standardized security posture.
The development environment running in AWS was dominated by EC2 and RDS spend — indicating the lift-and-shift approach was not leveraging managed services.
Three Phases, Assessment First
The engagement was structured as three distinct phases, each with its own scope and statement of work. This is how we approach migrations: you don’t start moving until you know exactly what you’re moving, where it’s going, and what needs to change along the way.
Phase 1 — Assessment (2 weeks). Well-Architected review of the existing on-premises environment and the AWS development environment. Produced a detailed findings report, a migration readiness assessment, and a prioritized recommendation plan. This phase surfaced the security and reliability issues that shaped everything that followed.
Phase 2 — Migration (6 weeks). The core migration: building the AWS landing zone, containerizing applications, establishing CI/CD, migrating databases with AWS DMS, and cutting over to the new production environment. Each step had defined acceptance criteria, test plans, cutover procedures, and rollback plans.
Phase 3 — Modernization (2 weeks). After migration, one of the applications needed to be enhanced to take proper advantage of the AWS-native services. This phase focused on optimizing the application architecture for the new environment.
Building a Modern Foundation
The migration wasn’t a lift-and-shift. The assessment had shown that simply moving the existing architecture to AWS would carry the same problems into the new environment. The goal was to modernize along the way.
Infrastructure as Code with Terraform. Every piece of the new environment was defined in Terraform — the landing zone, networking, security groups, IAM roles, database configurations, and deployment pipelines. This meant the environment was reproducible, auditable, and consistent across accounts. Changes were tracked in version control, not applied by hand.
AWS Organizations for proper account separation. We set up separate AWS accounts for development and production using AWS Organizations. The production account got full security controls and compliance policies. The development account had looser permissions for experimentation. This eliminated the single-account risk where a developer mistake could affect production.
Containerized with ECS Fargate. The applications were containerized and deployed to Amazon ECS using Fargate — no servers to manage, automatic scaling, and native integration with other AWS services. Docker images were built and pushed to Amazon ECR through automated pipelines.
Full CI/CD pipeline. AWS CodePipeline and CodeBuild were configured for both infrastructure (Terraform) and application deployments. Code was automatically scanned with SonarQube for quality and security issues. The pipeline handled everything from source to production, with the option for manual approval gates on production deployments.
Database migration with AWS DMS. The PostgreSQL databases were migrated to Amazon Aurora PostgreSQL using AWS Database Migration Service. The new databases were configured with multi-AZ deployment for high availability, encryption at rest, enhanced monitoring, and automated backups. Connection strings were updated through AWS Secrets Manager — eliminating the hardcoded credentials entirely.
Security overhaul. Every hardcoded secret was moved to AWS Secrets Manager with native ECS integration. IAM roles and policies enforced least-privilege access. Security groups were standardized. KMS encryption was applied consistently. CloudWatch and Container Insights provided real-time monitoring and alerting — the days of problems going unnoticed were over.
Nerd Talk: Architecture & AWS Services
The target architecture leveraged the following AWS services:
Compute & Containers: ECS Fargate (serverless containers), ECR (container registry), cross-account ECR sharing for deployment pipeline
Data: Aurora PostgreSQL (multi-AZ), S3 (object storage), AWS DMS (database migration), AWS Glue (data integration)
CI/CD & DevOps: CodePipeline, CodeBuild, SonarQube on EC2, Terraform for IaC, cross-account deployment roles
Security: Secrets Manager (credential management with rotation), IAM (identity and access management), KMS (encryption key management), security groups (standardized network access)
Monitoring & Reliability: CloudWatch (logs and metrics), Container Insights (ECS performance), CloudFront (CDN for multi-region delivery), Route 53 (DNS and health checks), multi-AZ deployment across all stateful services
Analytics: Amazon QuickSight for business intelligence reporting, connected to the new data warehouse
The landing zone was deployed using a multi-account strategy with shared networking (VPC peering) between accounts, standardized tagging for cost allocation, and centralized logging.
Secure, Scalable, and Self-Sufficient
The transformation went beyond infrastructure. The company’s IT team went from managing a fragile on-premises environment to operating a modern cloud platform with confidence.
Security posture transformed. All 19 critical credential vulnerabilities were resolved. The 197 SQL injection vectors were flagged for remediation with a structured technical debt plan. Every database was encrypted. Network access was locked down. The team had a clear, auditable security baseline for the first time.
Reliability built in. Multi-AZ databases meant a failure in one availability zone wouldn’t take down the system. Automated monitoring and alerting meant issues were caught before they became outages. The hospitals that depend on these services didn’t experience a single minute of unplanned downtime during or after the migration.
Deployments went from days to minutes. With the full CI/CD pipeline, the development team could push code through automated builds, quality scans, and deployments. What used to require manual coordination across teams now happened automatically with proper safeguards.
The IT team could manage it. This was a small team. The new environment was designed so they could operate it independently — infrastructure as code for consistency, automated pipelines for deployments, managed services that handle the undifferentiated heavy lifting. They weren’t locked into needing ongoing help to keep the lights on.
The Client
A fast-growing U.S. healthcare services company providing anesthesia, billing, and practice management to hospitals and surgery centers. With a small internal IT team and rapid business growth, their infrastructure couldn't keep pace with demand.
Details have been anonymized at our client's request. The technical substance of the engagement is preserved.
Key Results
Facing a similar challenge?
Let's discuss how we can help your organization achieve the same results.