The Challenge
An online recruitment platform needed to decommission its legacy, high-maintenance on-premises datacenter in Ireland and retire an aging .NET monolith. More than 50 critical business services running on mixed Linux/Windows fleets had to be moved into a multi-account AWS setup (separate production and QA/staging accounts). The primary constraints were zero downtime for end-users, no transactional data loss during database migration, and breaking the monolith apart into independently deployable services without disrupting ongoing sprint delivery.
The Solution
Directed a multi-account AWS migration (EC2, ASG, Terraform, Route 53) across separate production and QA accounts; built golden AMIs with HashiCorp Packer and pushed them to a ~40-instance .NET fleet through AWS CodeDeploy rolling updates so releases never took the site offline. In parallel, decomposed the .NET monolith into Docker-based microservices on Kubernetes (EKS), with images stored in a private Amazon ECR registry. Databases were migrated from the Ireland datacenter to AWS RDS over AWS Direct Connect using AWS Database Migration Service (DMS), with Amazon Redshift maintained for downstream analytics. Delivery was automated through GoCD pipelines enforcing semantic versioning, coordinated with Agile sprint planning, and validated in dedicated QA environments running automated Selenium test suites. Dynatrace was rolled out across the new AWS estate for full-stack observability. Once the AWS environment reached parity, all DNS records were cut over and the Ireland datacenter was fully decommissioned.
Key Business Outcomes
- Zero Downtime Cutover: Successfully migrated all 50+ business services and cut over all DNS records with 0 minutes of user-facing downtime.
- Monolith to Microservices: Decomposed the legacy .NET monolith into containerized microservices running on Kubernetes (EKS), improving deployment independence.
- Automated VM Image Builds: Cut base OS patching and VM configuration times significantly via automated Packer pipeline templates across ~40 ASG-managed instances.
- Database & Analytics Migration: Migrated production databases via Direct Connect and AWS DMS into RDS, with Redshift maintained for BI/analytics workloads.
- Full-Stack Observability: Rolled out Dynatrace across the new AWS estate, replacing legacy on-prem monitoring.
- Release Governance: Established GoCD pipelines with semantic versioning and automated Selenium-driven QA environments, aligned to sprint planning cadence.
Core Technologies
Image & Build Automation
HashiCorp Packer, AWS AMI, Auto Scaling Groups (ASG), .NET, Windows Server Sysprep
Containers & Modernization
Kubernetes (EKS), Docker, Amazon ECR, Monolith Decomposition, Microservices
IaC & Multi-Account
HashiCorp Terraform, AWS Organizations (Multi-Account), AWS Route 53
Database Migration
AWS Direct Connect, AWS DMS, AWS RDS SQL Server (Multi-AZ), Amazon Redshift
CI/CD & QA
GoCD Pipelines, AWS CodeDeploy, Semantic Versioning, Selenium, Agile Sprint Planning
Observability
Dynatrace APM, AWS CloudWatch Alerts, RPO/RTO Verification
Multi-Account Migration & Monolith-to-Microservices Architecture
The diagram below illustrates the full migration: databases moved from the legacy Ireland datacenter into AWS RDS over Direct Connect via AWS DMS; the .NET monolith split into an ASG-managed instance fleet and an EKS microservices tier across separate production and QA/staging AWS accounts; GoCD driving semantically-versioned, Selenium-validated releases; Dynatrace providing full-stack observability; and a final Route 53 DNS cutover retiring the Ireland datacenter.
Packer Template for Golden CentOS AMI
The following Packer HCL configuration demonstrates how golden CentOS images were built, hardened, and pushed to AWS for deployment.
packer {
required_plugins {
amazon = {
version = ">= 1.2.0"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "centos" {
ami_name = "centos-golden-{{timestamp}}"
instance_type = "t3.medium"
region = "eu-west-1"
source_ami_filter {
filters = {
name = "CentOS Stream 9*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["123456789012"] # AWS Account ID
}
ssh_username = "centos"
}
build {
sources = ["source.amazon-ebs.centos"]
provisioner "shell" {
inline = [
"sudo dnf update -y",
"sudo dnf install -y htop wget curl epel-release",
"sudo systemctl enable firewalld"
]
}
}
Route 53 Weighted Record (Terraform)
Terraform code used to declare weighted routing rules for canary releases during the database switchover.
resource "aws_route53_record" "app_canary_old" {
zone_id = var.route53_zone_id
name = "app.enterprise-services.com"
type = "A"
ttl = "60"
weighted_routing_policy {
weight = 90
}
set_identifier = "legacy-ireland-datacenter"
records = [var.legacy_datacenter_public_ip]
}
resource "aws_route53_record" "app_canary_new" {
zone_id = var.route53_zone_id
name = "app.enterprise-services.com"
type = "A"
ttl = "60"
weighted_routing_policy {
weight = 10
}
set_identifier = "aws-dublin-cloud"
records = [aws_lb.production_alb.dns_name]
}