When a client’s parent company acquired them, the immediate challenge was migrating their entire MuleSoft estate — 100+ APIs, dozens of Anypoint MQ queues, and a forest of Azure DevOps pipelines — to the parent company’s VPC. With a tight deadline and a small team, manual migration was not an option.

This post walks through the automation strategy we used.

The Scope

Asset Type Count
Mule APIs (CloudHub 1.0) 112
Anypoint MQ Queues 43
Azure DevOps Pipelines 38

Each API needed its VPC association updated, properties re-mapped to the new environment, and deployment verified.

Step 1: Inventory with the CloudHub REST API

The first step was pulling a complete inventory using the CloudHub Management API:

// Postman pre-request script
const baseUrl = pm.environment.get("CLOUDHUB_BASE_URL");
const orgId   = pm.environment.get("ORG_ID");
const envId   = pm.environment.get("ENV_ID");

pm.sendRequest({
  url: `${baseUrl}/cloudhub/api/v2/applications`,
  method: "GET",
  header: {
    "Authorization": `Bearer ${pm.environment.get("ACCESS_TOKEN")}`,
    "X-ANYPNT-ORG-ID": orgId,
    "X-ANYPNT-ENV-ID": envId
  }
}, (err, res) => {
  const apps = res.json().data;
  pm.environment.set("APP_LIST", JSON.stringify(apps));
  pm.environment.set("APP_COUNT", apps.length);
  console.log(`Found ${apps.length} applications`);
});

Step 2: The Migration Script

With the inventory in hand, I wrote a Postman Collection runner script to iterate over each application and update its VPC binding:

// Test script — runs after each API response
const apps      = JSON.parse(pm.environment.get("APP_LIST"));
let   idx       = parseInt(pm.environment.get("CURRENT_IDX") || "0");
const targetVpc = pm.environment.get("TARGET_VPC_ID");

const current = apps[idx];
if (!current) {
  console.log("✅ All applications migrated.");
  return;
}

// Patch the app's VPC association
const patchBody = {
  deploymentUpdateSideEffects: { reassignDomain: false },
  application: {
    muleVersion: { version: current.muleVersion },
    vpcId: targetVpc,
    region: current.region
  }
};

pm.environment.set("CURRENT_APP_NAME", current.domain);
pm.environment.set("PATCH_BODY", JSON.stringify(patchBody));
pm.environment.set("CURRENT_IDX", idx + 1);

// Trigger next iteration
pm.execution.setNextRequest("Patch Application VPC");

Step 3: Validation

After migration, each app was validated automatically:

// Verify the app is running in the correct VPC
const res = pm.response.json();
pm.test("Application in correct VPC", () => {
  pm.expect(res.vpcId).to.eql(pm.environment.get("TARGET_VPC_ID"));
});
pm.test("Application status is STARTED", () => {
  pm.expect(res.status).to.eql("STARTED");
});

Anypoint MQ Migration

Anypoint MQ queues were migrated via the Anypoint MQ REST API, recreating each queue in the new environment with the same DLQ configuration, max retries, and TTL settings.

Azure DevOps Pipeline Updates

Pipelines were updated using variable group replacement — a PowerShell script iterated over all pipeline YAML files and substituted old VPC endpoint variables with the new ones.

Results

  • ✅ All 112 APIs migrated within the maintenance window
  • ✅ Zero production incidents post-migration
  • ✅ Full rollback script prepared (unused)
  • ⏱️ Total automation time: ~4 hours vs. estimated 3 weeks manual

The takeaway: investing a day in a well-structured automation script is almost always worth it over a week of repetitive manual work.