Engagements

The work, and how it actually goes

Sixteen engagements I take on regularly — what the situation usually looks like, how I'd approach it, and the part that tends to cause trouble. A few include the case for not doing the project at all, because that's sometimes the right answer.

These describe project types rather than specific clients. The patterns, constraints and failure modes come from a decade of enterprise architecture work; client engagements themselves stay confidential. On a call I can go considerably deeper on anything relevant to your situation.

Cloud & Modernization
Product teams, in-house development, software vendors· 4–6 weeks

Setting up DevOps from nothing, for a .NET and Angular team

The situation

The team writes good code and ships it badly. The API gets published from Visual Studio by whoever is around, the Angular build runs on one developer's machine, and the person who knows the deployment steps is the constraint on every release. Connection strings sit in appsettings.json in the repository. Nobody can say with certainty which commit is currently in production, and rollback means restoring a backup and hoping.

How I'd approach it

Start with the parts that unblock everything else. A branching model the team will actually follow — for a small team that's usually short-lived branches off trunk, because Gitflow's ceremony costs more than it returns below a certain headcount. Then the build: restore, test, publish artifacts for the API and the SPA in one pipeline. The Angular app gets built once and configured at runtime, so the identical artifact promotes from staging to production rather than being rebuilt per environment — rebuilding per environment means the thing you tested is not the thing you shipped. Infrastructure moves to Bicep, secrets to Key Vault accessed through managed identity, and database migrations become a deliberate gated step in the release rather than something that happens on app startup.

What usually bites

Two things, reliably. The first is EF Core migrations running automatically at startup — fine on one instance, a race the moment you scale out, and impossible to roll back cleanly under pressure. The second is that the test suite you want to gate the pipeline on frequently does not exist yet, and a quality gate that everybody learns to override is worse than no gate at all. That needs to be said in the first week, because it changes what the engagement can honestly promise.

What I'd cut first

Full infrastructure-as-code coverage on day one. Get the application pipeline working against the infrastructure that already exists, then bring environments under Bicep one at a time. Blue-green deployments, multi-region and automated performance gates all come later, if ever.

When I'd tell you not to

A two-person team releasing once a month to a single environment can get most of the benefit from a documented script and a checklist. Pipelines earn their keep when release frequency or team size makes coordination the bottleneck — I'd rather say that than build ceremony nobody needs.

Azure DevOps / GitHub ActionsBicep.NET 8AngularAzure App ServiceKey VaultManaged IdentityApplication Insights
Cloud & Modernization
Manufacturing, internal line-of-business apps· 6–8 weeks

Getting a monolith onto Azure without rewriting it

The situation

An application that runs the business and that nobody wants to touch. .NET Framework 4.x on a Windows Server VM, SQL Server sitting on the same box, deployed by remoting in and copying files. The developer who built it left years ago. Patching is a scheduled ordeal, and the disaster recovery plan is realistically a backup job someone hopes is still running.

How I'd approach it

Resist the rewrite. The goal for this phase is to get the thing somewhere you can deploy to safely and recover from — nothing more. Retarget the framework, pull connection strings and secrets into App Configuration and Key Vault, move session state out of process memory into Redis so it can run on more than one instance, and lift the database to Azure SQL. Then it goes onto App Service behind a pipeline. Modernization comes after, once deploying stops being frightening.

What usually bites

It is never the framework version that holds this up. It is the small local assumptions — writes to a path on the C: drive, Windows integrated auth, an SMTP relay that only accepts connections from that subnet, and a handful of jobs living in Task Scheduler that nobody documented. A real portion of the timeline goes to finding those, and the estimate should say so.

What I'd cut first

The microservices conversation. It comes up in every kickoff for this kind of project and it does not belong in this phase.

.NETAzure App ServiceAzure SQLKey VaultAzure Cache for RedisGitHub Actions
Cloud & Modernization
Platforms with multiple delivery teams· 8–12 weeks for the first extraction

Decomposing a .NET monolith, one seam at a time

The situation

Different project from a lift to Azure, and worth doing only for a concrete reason — several teams contending over one deployment, a module whose load profile looks nothing like the rest, or a release cadence held hostage by the slowest-moving part of the codebase.

How I'd approach it

Strangler pattern, not a rewrite. Find seams along transaction boundaries rather than along nouns — 'Customer' is a tempting service and usually a bad one. Extract exactly one, put API Management in front so callers don't need to know the logic moved, and keep the monolith as system of record until the seam proves out under real traffic. CQRS with MediatR inside the extracted service where the read and write paths genuinely diverge; not everywhere, because it costs clarity when applied by default. Service Bus for async work, correlation IDs from the first commit.

What usually bites

The shared database. Every microservices project is a database decomposition project in disguise, and the moment two services need the same table inside one transaction, the seam was drawn in the wrong place — that's a signal to redraw it, not to reach for a distributed transaction.

What I'd cut first

Extracting a second service in phase one. One, properly, with the operational tooling around it. Then decide whether the second is still worth it.

When I'd tell you not to

If none of those three pressures apply, the monolith is fine. I've talked more than one team out of this, and the money went further elsewhere.

.NET 8Azure API ManagementAzure Service BusAKSCQRS / MediatRApplication Insights
Cloud & Modernization
Retail, finance, operations reporting· 6–10 weeks

Migrating ETL packages nobody has looked at in years

The situation

A server running SSIS or Informatica workflows, orchestrated by SQL Agent, with a couple of jobs triggered by a recurring reminder in somebody's calendar. Failure notification consists of a person noticing a report looks stale — usually after the meeting where the report was used.

How I'd approach it

Inventory before anything else. In estates of this age a meaningful fraction of the workflows are dead and can be switched off after a watching period, which is the cheapest win available. Lift the survivors via the SSIS Integration Runtime to buy breathing room, then rewrite the ones carrying real business weight as native Data Factory pipelines with Mapping Data Flows and proper alerting. Business logic too gnarly for a data flow goes into a custom activity rather than being contorted into one.

What usually bites

Undocumented ordering dependencies between packages, and hardcoded UNC paths pointing at a share that has been migrated twice. Both tend to surface at cutover rather than during analysis, which is what the rehearsal is for.

What I'd cut first

Rewriting the full estate in one pass. Migrate what earns it, lift the rest, revisit in six months with real usage data.

Azure Data FactorySSIS Integration RuntimeAzure Data Lake Gen2Mapping Data FlowsAzure Monitor
Cloud & Modernization
Operations that run around the clock· 5–8 weeks

Moving a database to Azure SQL without a maintenance window

The situation

An on-premises SQL Server that needs to be in Azure, and a business that cannot take an outage — either because operations run continuously or because the only quiet window falls during month-end close.

How I'd approach it

Assess compatibility first with Data Migration Assistant. Cross-database queries, linked servers and SQL Agent jobs are the usual blockers, and they decide whether the target is Managed Instance or Azure SQL Database — a choice that is expensive to reverse. Then Database Migration Service in online mode with continuous sync. Encryption at rest and private networking get configured during the build, not retrofitted, because retrofitting them means a second migration. The cutover is rehearsed at least twice against a copy of production, and so is the rollback.

What usually bites

Stored procedure volume drives the timeline more than data volume does. A large procedure estate needs review, not just replication, and any plan that treats a thousand-table database and a two-hundred-table database as the same amount of work is not a plan.

What I'd cut first

Schema improvements. Move as-is, verify, then improve. Changing two variables during a cutover makes any problem twice as hard to diagnose at two in the morning.

Azure SQL Managed InstanceDatabase Migration ServiceData Migration AssistantPrivate EndpointsKey Vault

What drives the number

Why two similar projects quote differently

Four variables account for most of the difference. Understanding them is also how you reduce the number — several are things you control.

How many systems have to talk

One system in, one system out is straightforward. Each additional integration adds its own auth, its own failure modes, and its own vendor documentation of variable quality. This is the single biggest driver on most projects.

The state of the data

Clean, consistently structured source data makes a build predictable. Twelve years of inconsistent records, duplicate masters and undocumented columns turns a five-week project into an eight-week one — and that work happens whether or not it was scoped.

Which decisions are already made

If your team already agrees what an active customer is, or how a sync conflict resolves, the build starts immediately. If not, that agreement has to be reached first, and it needs a decision-maker rather than an engineer.

Who takes it over

Handing to an internal team who will maintain it is cheaper than building something that has to run untouched for two years. The latter needs more documentation, more defensive handling, and more thought about the failure modes nobody will be watching for.

I quote a fixed price after the mapping session, not before. An estimate given without seeing your systems is a guess with a margin baked in for being wrong, and you end up paying for that margin whether or not it was needed. Indicative starting points for each type of engagement are on the pricing page.

The engagement model

Four phases, no surprises

Same shape whether it's a three-week automation or a fourteen-week application build. Each phase has a defined output you can hold me to.

01

Map the actual problem

A working session on your process — where time goes, where errors creep in, what a fix is worth. You leave with a written opportunity map whether or not we go further.

→Opportunity map + rough effort estimate
02

Scope one narrow thing

One workflow, one measurable outcome, fixed price. Deliberately small — a scope you can judge in weeks beats a roadmap you have to take on faith.

→Fixed-price proposal + success metric agreed upfront
03

Build in the open

Weekly working software, not status decks. You see the real thing in your own environment and redirect while it's still cheap to redirect.

→Working system in production, deployed to your infra
04

Hand over properly

Documentation, a walkthrough with your team, and source in your repository. You are never locked into me — that constraint keeps the work honest.

→Docs, handover session, full source ownership

What you own at the end

Full source code in your own repository. Infrastructure in your own cloud account, under your billing. Documentation written for the next engineer, not for me. No proprietary runtime, no per-seat licence, no dependency on my continued involvement.

If you want ongoing support afterwards, that's a separate conversation — never a condition of the build.

Recognise your situation in one of these?

The mapping session is free and yields something useful even if we never work together.

Book a Free Consultation