
Moving more than twelve applications from GCP to Azure, behind one identity system
A two-month migration, driven by a firm-wide tightening of access control, that put every application on Azure under Microsoft Entra ID, defined in Pulumi, with secrets in Doppler and Key Vault.
- Partner
- A multinational advisory firm
- Period
- 2 months
- Applications migrated
- 12+
- Python applications moved from GCP to Azure App Service
- Identity system
- 1
- Every application behind Microsoft Entra ID
- Delivery
- 2 months
- Audit, cleanup, migration and handover
The challenge
The firm was tightening access control across the organization, and IT wanted every internal application governed by the same identity and policies as Microsoft 365. Its applications ran on Google Cloud, deployed by hand, with no infrastructure as code, no complete record of resources, and secrets shared informally.
What we built
An audit and cleanup, then a migration of more than twelve Python applications to Azure, all defined in Pulumi. Applications run in containers on Azure App Service with private databases, secrets flow from Doppler into Azure Key Vault, and Cloudflare Access with Microsoft Entra ID protects every application.
What was delivered
- Every in-scope application on Azure, defined in code and deployed through CI/CD
- One identity system and one set of access policies for all applications
- Secrets held in Doppler and Key Vault instead of shared informally
Partner background
Our partner is a multinational advisory firm with more than 1,000 employees, working across several regions for high-profile organizations. Its people already worked in Microsoft 365 and signed in with Microsoft Entra ID. As part of a firm-wide push to tighten access control, IT asked for every internal application to move to Azure, next to that identity system, so that one set of policies and one audit trail would cover them all.
The challenge
Two clouds, two access models
Applications on Google Cloud sat outside the identity and conditional access policies that governed the rest of the firm's systems, so their access had to be managed and reviewed separately.
Fragmented cloud management
Resources on Google Cloud were created without a shared system for documentation and management, so it was hard to know what existed and why.
Informal secrets
API keys and credentials were shared informally, a risk that grew with the team.
Manual deployments
With no infrastructure as code and no specialist, every environment was set up by hand, which lengthened lead times for new projects.
Rising costs
Unused and redundant resources accumulated, with no clear view of what was driving spend.
Objectives
- Bring every internal application under Microsoft Entra ID and the firm's access policies
- Manage infrastructure in code the existing team could read and maintain
- Automate provisioning of new environments
- Remove legacy deployments and unused resources before moving
- Replace informal secret sharing with central secrets management
Our role
CharCentric planned and carried out the audit, cleanup, migration and handover over two months.
Scope and timeline
The project migrated more than twelve Python applications from a non-containerized GCP setup to containers on Azure, with their databases, caches and queues, all managed through Pulumi. It was delivered in two months.

Approach
One identity for everything
Moving to Azure placed every application next to Microsoft Entra ID. Cloudflare Access uses Entra ID as its identity provider, so the same accounts, groups and conditional access policies decide who reaches each application.
Infrastructure as code in a familiar language
Pulumi lets infrastructure be written in TypeScript, a language the partner's developers already used, so the team can read, review and extend it after handover.
Clean before moving
An audit identified redundant and unused resources first, so only what was needed was migrated.
Implementation

Audit and cleanup
Redundant GCP resources were identified and removed before the migration, so nothing unused was carried across.
Compute and data
Each application was containerized and moved to Azure App Service. Databases moved to Azure Database for PostgreSQL on a private virtual network, alongside Azure Cache for Redis and Service Bus, with Application Insights for monitoring.
Access
Every application sits behind Cloudflare Access with Microsoft Entra ID, so access is granted by group and checked against the firm's conditional access policies. Each App Service accepts traffic only from Cloudflare and validates the Access token, so no application can be reached around it.
Secrets
A custom Pulumi provider, written in TypeScript, reads secrets from Doppler and writes them into Azure Key Vault. Applications read them through Key Vault references, so application settings hold only a Key Vault reference, never the secret value.
Frontend integration
Frontends hosted on Vercel were brought into the Pulumi codebase, so all environments are managed in one place.
Automation
Pulumi Cloud is connected to the CI/CD pipelines. Every infrastructure pull request shows a preview of its changes, and production changes need approval.
Tools and technologies
| Tool | Purpose |
|---|---|
| Pulumi and Pulumi Cloud | Infrastructure as code and deployment automation |
| Azure App Service | Container hosting |
| Azure Database for PostgreSQL | Private managed databases |
| Doppler | Central secrets management |
| Azure Key Vault | Secrets read by applications |
| Cloudflare Access | Identity-based access to every application |
| Microsoft Entra ID | Identity provider and conditional access |
| Vercel | Frontend hosting, managed through Pulumi |
What was delivered
- Applications migrated
- 12+
- Identity system
- 1
- Migration phases
- 4
- Delivery
- 2 months
- All in-scope applications running on Azure under Pulumi management
- Every application behind Microsoft Entra ID and the firm's access policies
- Unused and redundant cloud resources removed before migration
- Secrets managed centrally and read from Key Vault
Why it matters
A cloud move is worth most when it changes how the estate is governed, not only where it runs. Putting every application behind one identity system, defined in code, means access is reviewed in one place and the next project starts from a known base.
If your organization is facing a similar challenge, we would be glad to discuss it.