Saltar a contenido

Migration From Camunda 8

Guía técnica completa para migrar desde Camunda 8 al MVP. Cubre: schema mapping (Postgres ↔ ES/RocksDB), BPMN element conversion table (40+ types mapped, supported/unsupported), variable migration, FEEL→CEL conversion, deployment workflow, process instance state migration, tooling needed (mvp-migrate CLI), phased migration strategy (parallel running → cutover → decommission), rollback plan. Realistic effort: ~2-3 weeks por org tier (small/medium/large).

Audience

Esta guía es para teams que actualmente operan Camunda 8 (SaaS o Self-Managed) y consideran migrar al MVP. NO es marketing — es technical reality assessment.

Spoiler: migration es feasible pero non-trivial. Camunda 8 features that MVP no soporta requieren BPMN rework. Plan para 2-3 weeks de migration trabajo per process complejo, dependiendo de feature usage.

Compatibility matrix overview

Category Compatibility Notes
BPMN core elements 80-90% Service/User tasks, gateways, events, sub-processes work
DMN decision tables 0% (Phase 1) Use external decision engine or convert to gateway logic
FEEL expressions 60-80% via conversion CEL via conversion tool (per ADR-022)
Forms 30% JSON Schema vs Camunda forms — manual conversion
Connectors 0% (Phase 1) Rewrite as workers using SDK
Process modification 0% Out of scope MVP
Process migration 0% Out of scope MVP (manual)
Multi-tenancy 100% Mapped
Identity (OIDC) 100% Standard
Authorization Partial 3 roles vs 20 resource types — semantic remapping
Webhooks (inbound) 0% Write own webhook handlers
Job workers 100% Same pattern (gRPC → REST conversion)

BPMN element conversion

Fully supported (drop-in)

Camunda 8 element MVP support Notes
bpmn:startEvent (none) ✅ Full
bpmn:startEvent (message) ✅ Full
bpmn:startEvent (timer) ✅ Full Timer durations/cycles supported
bpmn:startEvent (signal) ✅ Full
bpmn:endEvent (none) ✅ Full
bpmn:endEvent (terminate) ✅ Full
bpmn:endEvent (error) ✅ Full
bpmn:serviceTask ✅ Full Same job worker pattern
bpmn:userTask ✅ Full Forms via JSON Schema
bpmn:sendTask ✅ Full Equivalent to serviceTask
bpmn:receiveTask ✅ Full Maps to message intermediate catch
bpmn:scriptTask ✅ Limited CEL expressions only
bpmn:exclusiveGateway ✅ Full CEL conditions
bpmn:parallelGateway ✅ Full Fork + join
bpmn:eventBasedGateway ✅ Full
bpmn:intermediateCatchEvent (message) ✅ Full Message correlation
bpmn:intermediateCatchEvent (timer) ✅ Full
bpmn:intermediateCatchEvent (signal) ✅ Full
bpmn:intermediateThrowEvent (message) ✅ Full
bpmn:intermediateThrowEvent (signal) ✅ Full
bpmn:boundaryEvent (timer) ✅ Full
bpmn:boundaryEvent (message) ✅ Full
bpmn:boundaryEvent (error) ✅ Full
bpmn:subProcess (embedded) ✅ Full Scope handling correct
bpmn:callActivity ✅ Full Input/output mappings
bpmn:multiInstanceLoopCharacteristics (parallel) ✅ Full
bpmn:eventSubProcess (interrupting) ✅ Full

Partial / requires conversion

Camunda 8 element MVP Phase 1 Conversion strategy
bpmn:businessRuleTask (DMN) ❌ → Manual Convert decision table to exclusive gateway + CEL, or call external decision service
bpmn:multiInstanceLoopCharacteristics (sequential) ❌ Phase 2 Convert to sub-process called N times in loop
bpmn:inclusiveGateway ❌ → Manual Convert to multiple exclusive gateways
bpmn:complexGateway ❌ → Manual Restructure with explicit gateways
bpmn:boundaryEvent (escalation) ❌ Phase 2 Convert to error event
bpmn:boundaryEvent (compensation) ❌ → Manual Implement saga pattern manually in workers
bpmn:boundaryEvent (conditional) ❌ Phase 2 Convert to message-based pattern
bpmn:eventSubProcess (non-interrupting) ❌ → Manual Restructure
bpmn:adHocSubProcess ❌ Phase 2 Restructure as multi-instance or explicit flow
bpmn:transaction ❌ → Manual Use saga pattern

Not supported (rework required)

Camunda 8 feature Strategy
Camunda-specific extensions (zeebe:*) Rewrite using MVP extensions
Camunda forms (zeebe:formDefinition con formId desde Camunda) Convert to JSON Schema
Camunda connectors (zeebe:taskDefinition con type de connector) Rewrite as worker
Process modification API Not available — cancel + recreate
Process migration API Not available — let v1 finish, start v2

FEEL → CEL conversion

Per ADR-022, MVP uses CEL. FEEL expressions need conversion.

Auto-conversion (mvp-cli tool)

mvp-cli bpmn convert --from=camunda --to=mvp \
        --feel-engine=cel \
        process.bpmn

# Output: process.bpmn.converted with CEL expressions
# Output: process.bpmn.report.txt with conversion notes

Conversion patterns

FEEL CEL
=amount > 100 amount > 100
=customer.email customer.email
=count(items) items.size()
=upper case(name) name.upperAscii()
=substring(name, 1, 5) name.substring(0, 5) (note: 0-indexed)
=date and time("2025-01-01T00:00:00") timestamp("2025-01-01T00:00:00Z")
=duration("PT1H") duration("1h")
=customer.tier = "premium" customer.tier == "premium"
=items[item.price > 100] items.filter(i, i.price > 100)
=sum(items.price) items.map(i, i.price).sum()
=if score > 80 then "A" else "B" score > 80 ? "A" : "B"
=every i in items satisfies i.valid items.all(i, i.valid)
=some i in items satisfies i.invalid items.exists(i, i.invalid)

NOT auto-convertible (manual)

  • DMN-specific FEEL constructs (boxed expressions)
  • Custom FEEL functions (no equivalent en CEL)
  • Some date/time complex (different APIs)
  • FEEL boxed lists with custom evaluation

Manual review needed. Tool flags these explicitly.

Schema mapping

Camunda 8 (Elasticsearch indices) → MVP (Postgres tables)

Camunda 8 ES index MVP Postgres table Notes
operate-list-view process_instances + element_instances joined Camunda denormalizes via join relation
tasklist-task user_tasks Direct mapping
operate-incident incidents Direct mapping
operate-variable variables Direct mapping
zeebe-record-process-instance Reconstruct from event_log Camunda raw record stream
operate-flow-node-instance element_instances Same concept
operate-decision-instance N/A Phase 1 DMN out of scope
tasklist-form forms Schema conversion needed
operate-batch-operation batch_operations Same concept
operate-process-definition process_definitions BPMN XML stored

Field mapping example

Camunda 8 ListViewTemplate (process instance):

{
  "key": 2251799813685250,
  "processDefinitionKey": 2251799813685249,
  "bpmnProcessId": "order-approval",
  "processName": "Order Approval",
  "processVersion": 3,
  "startDate": "2025-05-01T10:00:00.000Z",
  "endDate": null,
  "state": "ACTIVE",
  "parentProcessInstanceKey": null,
  "treePath": "PI_2251799813685250",
  "incident": false,
  "tenantId": "<default>",
  "businessId": "ORD-789"
}

MVP Postgres:

INSERT INTO process_instances (
    process_instance_key,           -- 2251799813685250
    process_definition_key,         -- 2251799813685249
    bpmn_process_id,                -- 'order-approval'
    process_definition_version,     -- 3
    start_date,                     -- '2025-05-01T10:00:00Z'
    end_date,                       -- NULL
    state,                          -- 'ACTIVE'
    parent_process_instance_key,    -- NULL
    has_incident,                   -- FALSE
    tenant_id,                      -- '<default>'
    business_id                     -- 'ORD-789'
) VALUES (...);

Straightforward field-to-column mapping. Some fields renamed (camelCase → snake_case).

Migration tooling: mvp-migrate

Conceptual tool spec:

# 1. Discover Camunda 8 environment
mvp-migrate discover --camunda-url=https://my.camunda.io \
                     --client-id=$CID \
                     --client-secret=$CSECRET \
                     --output=discovery.json

# Lists: processes, instances, tasks, deployments, etc.

# 2. Plan migration
mvp-migrate plan --discovery=discovery.json \
                 --output=migration-plan.yaml

# Output: 
#   - BPMN files identified
#   - Compatibility analysis
#   - Manual rework items
#   - Estimated effort

# 3. Convert BPMN files
mvp-migrate convert-bpmn --input-dir=./bpmn-files/ \
                         --output-dir=./mvp-bpmn/

# Conversion report per file

# 4. Migrate state (instances, tasks)
mvp-migrate migrate-state --from-camunda \
                          --to-mvp=https://mvp.example.com \
                          --batch-size=100 \
                          --tenant=acme

# Iterates over active instances:
# - Cancel in Camunda
# - Create in MVP with same business state
# - Map variables
# - Resume from equivalent element

# 5. Validate
mvp-migrate validate --instance-keys-file=migrated.txt

Process instance state migration

The hard part: in-flight instances cannot be paused mid-execution easily.

Strategy 1: Drain + cutover (recomendado)

T-30 days:  Deploy v2 in MVP (parallel)
            Some new instances go to MVP
            Camunda 8 continues with active instances

T-7 days:   Stop creating new instances in Camunda
            All new traffic to MVP

T-0:        Cancel all remaining Camunda instances
            Notify users to recreate if business-critical
            Decommission Camunda

Pros: simple, no in-flight migration risk
Cons: some lost work, business disruption

Strategy 2: State migration (complex)

# Pseudo-code
async def migrate_instance(camunda_pi):
    # 1. Cancel in Camunda
    await camunda.cancel_instance(camunda_pi.key)

    # 2. Determine current state
    current_element = camunda_pi.current_element_id
    variables = camunda_pi.variables

    # 3. Create new instance in MVP
    mvp_pi = await mvp.create_instance(
        bpmn_process_id=camunda_pi.bpmn_process_id,
        variables=variables,
        start_instructions=[{
            "elementId": current_element  # resume from same point
        }]
    )

    # 4. Recreate user tasks if any
    for task in camunda_pi.user_tasks_pending:
        # MVP creates task automatically via BPMN
        # But assignment needs to be preserved
        await mvp.assign_task(
            task_key=find_equivalent_task(mvp_pi, task.element_id),
            assignee=task.assignee
        )

    return mvp_pi.key

Limitations: - Cannot perfectly reconstruct mid-execution state (e.g., partial sub-process completion) - Variables timing may differ (different timestamps) - Some BPMN features (compensation history) not migratable

Best for: long-running processes (loans, customer onboarding) where Strategy 1 unacceptable.

Strategy 3: Parallel running (most expensive)

Run Camunda 8 + MVP concurrently for 3-6 months
New work goes to MVP
Old instances drain naturally in Camunda
Eventually Camunda has 0 instances → decommission

Pros: zero disruption, zero data risk Cons: double cost during overlap

User & tenant migration

Camunda 8 Identity → MVP Identity:

# Tenants
for camunda_tenant in camunda.list_tenants():
    await mvp.create_tenant(
        tenant_id=camunda_tenant.id,
        name=camunda_tenant.name
    )

# Users (from Identity IdP)
# Camunda 8 typically uses Keycloak/OIDC
# Same IdP can be used by MVP (per ADR-014)
# No user migration needed if same IdP

# Authorization mapping
# Camunda 8 fine-grained → MVP 3 roles
mapping = {
    'TENANT_OWNER': 'admin',
    'PROCESS_DEFINITION_DELETE': 'admin',
    'PROCESS_INSTANCE_CANCEL': 'operator',
    'PROCESS_INSTANCE_READ': 'operator',
    'JOB_COMPLETE': 'worker',
    # ...
}

for user_role in camunda.list_user_roles():
    role = highest_permission(user_role.permissions, mapping)
    await mvp.assign_role(
        user_id=user_role.user_id,
        tenant_id=user_role.tenant_id,
        role=role
    )

Worker migration

Camunda 8 workers use gRPC. MVP uses REST.

Conversion pattern

// Before (Camunda 8 worker - Java)
@JobWorker(type = "send-email")
public void sendEmail(@Variable Map<String, Object> vars) {
    // ...
}

// After (MVP worker - same logic, different SDK)
import { JobWorker } from '@mvp/sdk';

const worker = new JobWorker({
    client: mvpClient,
    jobType: 'send-email',
    handler: async (job) => {
        // Same business logic
    }
});

Connection string change:

- ZEEBE_CLIENT_BROKER_GATEWAY_ADDRESS=zeebe.camunda.io:443
- ZEEBE_CLIENT_ID=...
- ZEEBE_CLIENT_SECRET=...
+ MVP_ENDPOINT=https://mvp.example.com
+ MVP_API_KEY=...

Variables, headers, retries — semantically same. 80% of worker code unchanged.

Form migration

Camunda forms (JSON, custom schema):

{
  "type": "default",
  "components": [
    {
      "type": "textfield",
      "key": "customerName",
      "label": "Customer Name"
    },
    {
      "type": "number",
      "key": "amount",
      "label": "Amount"
    }
  ]
}

MVP forms (JSON Schema, per ADR-012):

{
  "schema": {
    "type": "object",
    "properties": {
      "customerName": { "type": "string", "title": "Customer Name" },
      "amount": { "type": "number", "title": "Amount" }
    },
    "required": ["customerName", "amount"]
  },
  "ui_schema": {
    "customerName": { "ui:widget": "text" }
  }
}

Conversion is mechanical. Tool can automate most:

mvp-migrate convert-form --from=camunda --to=jsonschema input.form

Complex forms (custom widgets, validations) may need manual review.

Migration effort estimate

For typical organization:

Small (1-5 processes, < 1000 instances/day)

  • Discovery + plan: 1 day
  • BPMN conversion (tool + manual review): 2-3 days
  • Worker migration: 2-3 days
  • Form conversion: 1 day
  • State migration (strategy 1 or 3): 1-2 weeks
  • Testing + validation: 3-5 days

Total: 2-3 weeks

Medium (10-50 processes, 10K-100K instances/day)

  • Discovery + plan: 1 week
  • BPMN conversion (more complex flows): 2-3 weeks
  • Worker migration: 2-4 weeks (more workers)
  • Form conversion: 1 week
  • State migration: 2-4 weeks (more instances)
  • Testing + validation: 2 weeks
  • Stakeholder training: 1 week

Total: 2-3 months

Large (100+ processes, > 1M instances/day)

  • Multi-quarter project
  • Dedicated team (3-5 engineers)
  • Phased per-process migration
  • Significant DMN migration work
  • Custom tooling extensions

Total: 3-6 months

Rollback plan

If migration fails or issues emerge:

During phased migration (Strategy 1 or 3)

1. Stop sending new traffic to MVP
2. Re-enable creating instances in Camunda 8
3. Migrate any MVP instances back (reverse direction)
4. Investigate failure cause
5. Plan re-migration

Camunda 8 not decommissioned until migration complete.

After cutover

1. Restore Camunda 8 from backup (pre-migration snapshot)
2. Restore data from migration backup
3. Re-route traffic to Camunda
4. Validate

Required: maintain Camunda 8 + backups for at least 30 days post-migration.

Risk mitigation checklist

  • Inventory of all processes (BPMN + usage frequency)
  • Compatibility report run (see #Compatibility matrix overview)
  • Manual rework items identified + estimated
  • Form library cataloged
  • Worker code review for SDK compatibility
  • Test environment with MVP running (mirror of Camunda)
  • Pilot migration of 1-2 non-critical processes
  • Stakeholder sign-off on UX changes (Tasklist different)
  • Rollback plan documented + tested
  • Communication plan to end users
  • Camunda support contract maintained during migration period

Features that prevent migration

If your org heavily uses these, migration is not viable (yet):

  1. DMN decision tables — MVP Phase 1 doesn't support. Plan: external decision engine or Phase 2.
  2. Process modification API — Used heavily? Stay on Camunda.
  3. Optimize (process mining) — MVP doesn't replace. Use Grafana + SQL or stay.
  4. Camunda forms with custom widgets — Significant rework.
  5. Camunda Connectors ecosystem heavy — Rewrite all as workers.

Don't migrate if these block. Wait for MVP feature expansion or use hybrid.

Decision framework

flowchart TD
    Start[Should we migrate?]
    Start --> SaaS{Camunda 8 SaaS?}
    SaaS -->|Yes| TCO[Calculate TCO + real-time advantage]
    SaaS -->|No| DMN
    TCO --> DMN
    DMN{Heavy DMN usage?}
    DMN -->|Yes| StopDMN[Don't migrate Phase 1]
    DMN -->|No| Opt
    Opt{Use Optimize for analytics?}
    Opt -->|Yes| GrafanaPlan[Plan Grafana migration]
    Opt -->|No| Mod
    GrafanaPlan --> Mod
    Mod{Process modification workflows?}
    Mod -->|Yes| StopMod[Don't migrate - MVP doesn't support]
    Mod -->|No| Lang
    Lang{Workers in supported languages?}
    Lang -->|Java/Python/TS/Go| SDKReady[SDK available, easy migration]
    Lang -->|Other| WaitSDK[Wait for SDK or build via OpenAPI]
    SDKReady --> Team
    WaitSDK --> Team
    Team{Team willing 2-3 month project?}
    Team -->|Yes| Proceed[Proceed]
    Team -->|No| StopTeam[Defer]

Migration timeline template

Week 1-2:  Discovery + planning
Week 3-4:  BPMN conversion + worker code review
Week 5-6:  Pilot migration (1 non-critical process)
Week 7-8:  Pilot validation + lessons learned
Week 9-12: Phased migration of remaining processes
Week 13:   Cutover (Strategy 1) or continued drain (Strategy 3)
Week 14-16: Post-migration monitoring + optimization
Week 17+:  Decommission Camunda 8 (if Strategy 1)