Let's Talk

Centuro Global

Centuro Global runs a compliance and global-mobility platform used to set up entities, move staff and stay legal across more than 170 countries. We build and maintain its web application, own the AWS infrastructure it runs on, and support the annual ISO 27001 audit. The engagement started as delivery through a partner agency and became a direct relationship. It is still running.

YEAR

2024

CLIENT

Centuro Global

SCOPE

Front End, Infrastructure, Compliance

PLATFORM

Web

The Challenge

Compliance software has an unusual property: the rules change under you, in 170 jurisdictions, and the product has to keep shipping anyway. There is no quiet period to rebuild in. The front end had grown into a large Angular application carrying years of feature work, and it had reached the point where the build itself was the constraint — the runner was exhausting memory and stopping before it finished. A build you cannot reliably complete is a release you cannot reliably ship, which on a compliance product is not a developer inconvenience. Underneath, the platform ran on hand-managed Docker Compose hosts with nginx and Let's Encrypt certificates renewed by script. That was where it started, and it worked. It was also four environments' worth of configuration that lived in one team's memory, at a company heading into enterprise procurement and security review, where "how do you provision production" needs a better answer than a directory of compose files.

Challenge illustration

Objectives

  • Get the front end onto a current Angular and a build that finishes, without pausing feature delivery.
  • Move four environments from hand-managed hosts to infrastructure defined as code and reviewable in a pull request.
  • Make production behaviour observable rather than reported.
  • Support the security and diligence processes an enterprise SaaS is asked to pass.

Our Approach

Treat the build as a product problem

The Angular upgrade was not framed as housekeeping. It was taken on because the build runner was running out of memory and stopping, and it included moving from the legacy browser builder to the application builder specifically for build performance. The version number went up as a consequence of fixing that, not as the goal.

Upgrade in front of traffic, not beside it

A migration on a branch that lives for months is a migration that never lands. This one went through the same promotion path as everything else — feature, then qa, then uat, then pre-production, then production — with the fixes that surfaced after the version change shipped as ordinary work rather than held in a batch.

One module per resource, one directory per environment

The Terraform is deliberately boring: a module each for VPC, subnets, internet gateway, route tables, ECS cluster, ECS service, task definitions, RDS cluster and instance, database parameter groups, S3 and EC2 — and then dev, qat, uat and prod as four directories that compose them. Environments differ in variables, not in structure, which is what stops "it works in uat" from being an infrastructure question.

Add observability before you need it

Sentry for errors and performance tracing, PostHog for product events. Both went in deliberately, so a regression in a jurisdiction nobody on the team lives in shows up as a trace rather than a support ticket.

Turn up for the audit

ISO 27001 comes round every year and it asks about the things engineering owns: access, change control, how production is provisioned, what is logged. Infrastructure as code and a promotion path with review gates are the answer to most of those questions, which is the practical argument for building them that way. We have supported that audit annually, and supported technical due diligence during fundraising.

The Solution

The web application

A large Angular application on version 18, authenticating through Microsoft Entra with MSAL, translated with ngx-translate, taking payment through Stripe, and reporting through Chart.js and ExcelJS export. It is the surface through which customers run entity setup, immigration and compliance work across those 170-plus countries.

The infrastructure

The platform started on hand-managed Docker Compose hosts behind nginx, with certificates renewed by script. We moved it onto an ECS estate defined entirely in Terraform, with RDS behind it, across four environments that share their shape. That migration is ours, and it is the reason provisioning is now a reviewed change rather than an act of recall.

The operating support

Annual ISO 27001 audit support, and technical due diligence during a funding process. Both are engineering questions asked by non-engineers, and both are easier to answer when the infrastructure is already a text file.

Under the Hood

Frontend

Angular 18, MSAL for Entra authentication, ngx-translate, Stripe, Chart.js with annotation and datalabels plugins, ExcelJS, image compression in the browser.

Infrastructure

Terraform — modules for vpc, subnet, igw, route tables, ecs cluster, ecs service, ecs task definitions, rds cluster and instance, db parameter groups, s3, ec2; environments for dev, qat, uat, prod. Docker, nginx and Let's Encrypt on the preceding estate.

Delivery

Bitbucket Pipelines, promoting feature → qa → uat → pre-production → production.

Observability

Sentry error and performance monitoring, PostHog product analytics.

Centuro's platform publicly covers 170+ countries and won the FEM 2025 award for most innovative global mobility technology. Backend services are built by other teams; this describes the front end, the infrastructure, and the operating support we own.

The Decisions

The build failure was the reason, not the version number

Upgrading a framework because a newer one exists is how teams spend quarters and gain nothing. Upgrading because the build runner is dying gives you a finish line you can recognise. The builder migration was the actual fix; the version came along with it.

Environments differ in variables, never in structure

Four directories composing the same modules means a difference between uat and production is a value someone changed, visible in a diff. It costs more discipline up front and it removes an entire genre of incident.

We stayed after the agency engagement ended

This began as delivery through a partner agency and continued directly with Centuro. That is not a technical decision, but it is the one that produced everything above — infrastructure ownership, audit support and diligence work are things a team gets asked to do only after it has been around long enough to be trusted with them.

Outcomes

The platform is live and we are still on it. The front end is on a current Angular with a build that completes, production is provisioned from code across four environments, errors and product behaviour are instrumented, and the annual ISO 27001 audit has support from the people who own the infrastructure it asks about.

We have not put performance figures on this page. Centuro publishes its own claims about market-entry speed and cost; those are theirs, measured on their business, and it would be dishonest for us to present them as our outcome.