About our client
A European company that specializes in energy efficiency solutions for small and mid-sized businesses approached us once again. Their services include IoT-based monitoring, energy optimization, and automation of industrial processes. We’ve already had successful cooperation cases before: our dedicated development team designed cloud-ready pipelines for Azure IoT Hub monitoring, helping streamline energy tracking and boost operational efficiency.
The business problem: the need for seamless transition between cloud providers
Our European client offers tools for measuring, monitoring, controlling, and improving energy consumption across various types of buildings. They initially deployed their software on a dedicated on-premise server and Microsoft Azure Cloud. Later, the tech lead wanted the code to be easily portable across different cloud providers, with the ability to migrate to the new provider’s native services. The reason: limitations of their current pricing plan, and negotiating better terms with different cloud providers.
The client needed to switch from Azure to AWS to meet short-term scaling and cost needs. Later, they decided to switch from on-premises to Azure Cloud to unify services, simplify integration with Power BI and other Microsoft tools, and prepare for cloud-native ETL workflows. Despite these cloud shifts, core apps continued running in containers hosted on the dedicated server.
How we solved it: code refactoring for a modernized, flexible architecture
To build a modernized backend based on the microservices architecture approach for a complex energy project, we adopted a clear separation of concerns (SoC) by spaniding the system logic into workers and infrastructure components, avoiding a costly rewrite of the entire codebase.
Architecture refactoring
We started by decoupling system components from Azure-specific configurations. This allowed us to redesign the architecture around modular services using .NET Core, a reliable, cross-platform foundation for performance-critical backend tasks.
- Workers encapsulate the core business logic, ensuring that application rules remain isolated from platform dependencies.
- Infrastructure components manage cloud integrations, file storage, job scheduling, and other environment-specific operations.

You can apply management settings at different levels. The level you choose decides how broadly the setting applies. Lower levels inherit settings from higher ones.
For example: If you apply a policy to a subscription, it covers all resource groups and resources inside it. If you apply it to a resource group, it affects that group and everything in it.
Containerization
Each component was encapsulated within Docker containers, providing environment isolation and enabling seamless migration between cloud platforms. This approach ensured consistent cloud deployment for energy without altering core application logic.
Both Azure and AWS use resource groups to organize and manage resources. But they work a bit differently:
- In AWS, deleting a resource group doesn't delete the resources inside. In Azure, it does remove the group, and all its resources go with it.
- In Azure, you have to create a resource group before you add any resources. Each resource must belong to one group only.
- Azure lets you track costs by resource group. In AWS, you use cost allocation tags to track spending on specific resources.
Minimal code changes
Thanks to this architecture, migration required updates to only a single class, which was responsible for infrastructure abstraction. There’s no need to modify thousands of lines throughout the codebase.
This strategic separation significantly reduced both the migration timeline and associated costs, demonstrating a practical and efficient approach to cloud migration that aligns with industry best practices.
.jpg)
The business impact: reduced costs when switching to different cloud providers
Digital transformation gives businesses a lot of benefits, both operational and strategic:
- Significant cost reduction when migrating or switching between cloud providers, thanks to minimized rework and streamlined processes.
- Readiness for global growth with cloud freedom when scaling to new regions, which often requires multi-cloud infrastructure.
- Cloud provider independence gives greater flexibility to choose or change vendors based on evolving business needs and technology trends.
- Lower ongoing support and migration expenses, achieved by decoupling infrastructure from core business logic.
- Faster delivery of new features and updates without system downtime or disruption, enabling continuous innovation.
- Enhanced service stability and reliability, supported by robust abstraction layers and containerization.
- Mitigated vendor lock-in risks, empowering the business to adapt swiftly to market changes and avoid dependency on a single cloud provider.
Migration to another cloud now takes 4x less time. It goes into savings of tens of thousands of dollars on labor hours, system downtime, and technical support when migrating infrastructure between Microsoft Azure, AWS, or on-prem environments.
As we’ve seen in our practice earlier, if a typical migration takes 12 weeks and costs around $60,000, after refactoring for cloud migration, it can cost as little as $15,000 or less, thanks to the simplified architecture and automated processes.
Cloud migration architecture
At NetLS, we’ve helped clients in telecom, finance, and public infrastructure smoothly migrate between different providers. We focus on what matters: keeping your system stable, portable, and running without disruption. Our job was to match each AWS service with the right Azure tool, so the application could keep running exactly as it should, only better. And here are key principles and distinctions we considered:
- AWS Elastic Beanstalk → Azure App Service
Azure App Service offers a fully managed hosting platform for deploying and scaling web apps. It’s easy to use and built for speed.
- Amazon API Gateway → Azure API Management
These services let you publish APIs to internal teams or external customers, with full control, security, and analytics.
- Amazon CloudFront → Azure Front Door
Deliver content faster and more securely with Azure Front Door — a global CDN with high performance and built-in threat protection.
- AWS Global Accelerator → Azure Front Door
Use Azure Front Door to unify distributed microservices under one global application with smart routing, autoscaling, and regional failover.
- AWS Global Accelerator → Azure cross-regional load balancer
Get high availability with a static global IP address that distributes traffic across Azure regions for redundancy and performance.
- Amazon Lightsail / AWS Amplify → Azure App Service
Azure App Service handles everything from code to cloud — ideal for quick deployment, scaling, and simplified management.
- AWS App Runner → Azure Web App for Containers
Easily run containerized apps on Azure using a fully managed service for both Windows and Linux environments.
Module identification and assessment
First, at NetLS, we identify all subject modules. We review the components that might be removed, updated, or migrated. At this stage, we evaluate which modules are critical, which are optional, and which are cloud-dependent.
Database migration can be particularly painful, especially when switching between different types. If the job/module is cloud-agnostic, migration is easier. However, the client must validate whether migration is worth the effort and introduces actual value.
At NetLS, we map each AWS service to its Azure equivalent and treat each one as a standalone architectural feature. This ensures clear separation of responsibilities, improved access control, and simplified management at scale.
Here’s how the mapping works:
- AWS IAM Identity Center / IAM → Microsoft Entra ID
Centralized identity and access management. Create and manage users and groups, assign roles, and control access to Azure services and resources with improved security and compliance.
- AWS IAM → Azure Role-Based Access Control (RBAC)
Define who can access what — and what they can do. Azure RBAC lets you assign permissions at a granular level across Azure subscriptions, resource groups, and inspanidual resources.
- AWS Organizations → Azure Management Groups
Manage policies and access across multiple Azure subscriptions. Azure Management Groups mirror AWS Organizations and provide a unified structure for role and policy enforcement at scale.
- MFA for IAM → Microsoft Entra ID with MFA
Protect user sign-ins with multi-factor authentication. Entra ID integrates MFA directly into the access flow, helping to secure sensitive resources with minimal user friction.
- AWS Directory Service → Microsoft Entra Domain Services
A fully managed domain service compatible with Active Directory. Supports domain join, group policies, LDAP, and Kerberos/NTLM — ideal for legacy applications and hybrid scenarios.
- Amazon Cognito → Microsoft Identity Platform / Entra External ID
Manage external users and enable “bring your own identity” scenarios. Entra External ID supports sign-ins from Google, Facebook (Meta), Microsoft accounts, and more — perfect for customer-facing apps.
Each of the six authentication and authorization records has its own architectural feature. As a result, it enables us to isolate responsibility, ensure scalability, and align security boundaries with Azure’s native capabilities.
By the end of this stage, we have a clear view of what stays, what moves, and what needs to be redesigned, with risks, priorities, and expected value documented for every module.
Internet of Things (IoT)
At NetLS, we guide IoT migration from AWS to Azure with precision and care. Each AWS service is paired with a corresponding Azure solution. For every pairing, we create a dedicated architectural feature. As a result, the system remains flexible, secure, and easy to manage.
The transition looks like this:
- AWS IoT Core → Azure IoT Hub
A secure cloud gateway for two-way communication with billions of IoT devices. Azure IoT Hub ensures reliable device-to-cloud and cloud-to-device messaging at scale.
- AWS IoT Greengrass → Azure IoT Edge
Enables on-device intelligence. Azure IoT Edge pushes cloud capabilities to the edge, supporting offline and real-time scenarios across distributed environments.
- Amazon Firehose / Kinesis → Azure Event Hubs + Stream Analytics
These services handle high-volume event ingestion from devices and sensors. Event Hubs captures data streams, while Stream Analytics processes them in real time or micro batches.
- AWS IoT TwinMaker → Azure Digital Twins
Build digital replicas of real-world environments, including buildings, production lines, cities. Azure Digital Twins helps simulate behavior, detect anomalies, and optimize systems.
- AWS IoT Device Management / FleetWise → Azure IoT Central
A fully managed platform for connecting and managing fleets of IoT devices. Azure IoT Central supports both general-purpose and automotive use cases, like vehicle telemetry.
- AWS IoT ExpressLink → Azure Sphere
Build custom, internet-connected hardware with built-in security. Azure Sphere provides secure device modules, software, and updates. This is ideal for OEMs and embedded systems.
Abstraction of infrastructure-dependent modules
Why it matters: Tightly coupled systems are difficult and risky to migrate.
What we do: We start by identifying all cloud- or platform-specific components, such as file storage, messaging systems, or identity services.
- We introduce an abstraction layer using interfaces or service wrappers.
- Each abstraction has separate implementations for the relevant cloud providers (AWS S3 vs. Azure Blob Storage).
- Business logic interacts only with the interface, not with the infrastructure itself.
This approach ensures high portability and simplifies future platform changes.
Application-level abstraction
Infrastructure-agnostic applications are easier to deploy, manage, and migrate.
We also abstract the launch and deployment logic:
- App launchers and orchestrators are abstracted to support multiple cloud environments or container platforms (AWS EKS vs. Azure AKS).
- Configuration files or environment variables are used to switch contexts, without rewriting application logic.
Before transition:
- Every abstraction is tested automatically using Gherkin, Cypress, and Jest and validated in the target environment.
- Feature flags or configs are used to toggle infrastructure context safely.
This enables confident migrations and minimizes the need for manual intervention during deployment.
Migration planning and rollback strategy
Planning reduces risk. So, rollback ensures resilience.
We develop a migration plan that includes:
- Resource provisioning schedules
- Cutover timeline and checkpoints
For a successful migration and ongoing management, we map key AWS tools to their Azure equivalents:
- AWS Organizations → Azure Management Groups
Organize resources and subscriptions into a unified hierarchy for centralized management.
- AWS Well-Architected Tool → Azure Well-Architected Review
Assess workloads across key dimensions: reliability, security, efficiency, and cost.
- AWS Trusted Advisor → Azure Advisor
Receive recommendations on best practices for security and resource configuration.
- AWS Billing and Cost Management → Microsoft Cost Management
Control and optimize spending, and monitor your budget.
- AWS Systems Manager → Azure Monitor
Collect and analyze telemetry for proactive monitoring.
- AWS Config → Azure Policy
Automate compliance checks and manage configuration changes.
- AWS CloudTrail → Azure Activity Log
Track changes and events at the subscription and resource level.
This set of tools helps maintain transparency, control costs, and ensure security standards during migration and cloud operations.
Data copying and dual-version support
Data integrity and service continuity are absolutely necessary. We support two approaches:
- Immediate switch. Go live as soon as all data is copied and validated.
- Dual-version support. Temporarily run both environments (AWS + Azure), with active data sync and routing logic.
Practically validated through our projects, dual running is often the safest option. It enables phased migration, issue isolation, and real-time testing.
Containerization
Containerized services are easier to test, scale, and migrate. We containerize every service using Docker and deploy via Kubernetes clusters.
DevOps takes over the process
DevOps configures the resources, tests, launches, and handles rollback. The following is the comprehensive suite that supports end-to-end DevOps and monitoring needs.
- Amazon CloudWatch & AWS X-Ray → Azure Monitor
Azure Monitor collects and analyzes telemetry from cloud and on-premises environments. Its Application Insights feature provides deep application performance monitoring, combining the roles of CloudWatch and X-Ray in AWS.
- AWS CodeDeploy, CodePipeline, CodeBuild, CodeConnections → Azure DevOps, GitHub, GitHub Actions
Azure DevOps offers a complete CI/CD and collaboration platform, integrating code testing, artifact management, and security scanning. GitHub and GitHub Actions automate workflows and support code hosting and collaboration. AWS no longer offers new code repositories but integrates with external platforms via CodeConnections.
- AWS CLI, AWS Tools for PowerShell, AWS SDKs → Azure CLI, Azure PowerShell, Azure SDKs
Both platforms provide command-line tools and SDKs to interact programmatically with cloud services, simplifying automation across multiple languages.
- AWS CloudShell → Azure Cloud Shell
A browser-based interactive shell for managing cloud resources, supporting both Bash and PowerShell environments.
- AWS Systems Manager → Azure Automation
Automate configuration and management tasks using templates and runbooks for various resource types.
- AWS CloudFormation, Cloud Development Kit (CDK) → Azure Resource Manager, Bicep, VM extensions, Azure Developer CLI, Automation
These Infrastructure-as-Code tools allow developers and admins to define, deploy, and manage repeatable cloud environments using declarative syntax or programming languages.
Security
At NetLS, we ensure your security remains uncompromised during migration by mapping essential AWS security tools to their Azure counterparts:
- Amazon Inspector → Microsoft Defender for Cloud
Automated vulnerability and compliance assessment to strengthen your application security posture.
- AWS Certificate Manager → Azure Key Vault Certificates / Microsoft Cloud PKI
Secure creation and management of certificates and cryptographic keys.
- Amazon GuardDuty → Microsoft Sentinel
Advanced threat detection and investigation across cloud and on-prem environments.
- AWS Artifact → Microsoft Service Trust Portal
Centralized access to audit reports, compliance guides, and trust documentation.
- AWS Shield → Azure DDoS Protection
Robust defense against distributed denial-of-service attacks to safeguard your infrastructure.
NetLS: an extensive experience in delivering app migration to cloud services
With years of hands-on experience across energy, healthcare, real estate, telecom, finance, big e-commerce, and public sector projects, we help businesses migrate their applications to the cloud. Our clients have already benefited from our services that guarantee:
- Technology consulting tailored to your infrastructure and business goals
- Scalable, stable system architecture
- Faster rollout of new features
- Independence from any single provider
- Compliance with security and regulatory standards
- Cost efficiency, as you pay only for resources you use, so hardware and energy expenses are minimal
- Cloud guarantees high availability through reliable, uninterrupted service for your applications
- Easy adjustment of resources to meet growing business demands
- Cloud providers guarantee advanced data protection
- Accelerated deployment and updates with improved performance
- Greater flexibility and innovation, allowing for quick adoption of new technologies.
Explore our app migration to cloud success stories. Ready to start your own? Book an intro call to get a personalized strategy.