BMC

BMC Control-M → Apache Airflow

Migrate BMC Control-M job flows, job streams, and scheduling policies to Apache Airflow DAGs.

BMC Control-M is one of the most widely deployed enterprise workload automation platforms. Its Folders, job flows, resource definitions, and cross-application dependencies represent years of business-critical scheduling logic. Control-M's modern, version-controllable definition format is JSON via the Control-M Automation API. BatchFoundry provides structured Control-M to Airflow migrations, converting Automation API JSON definitions, events, and calendars into idiomatic Airflow DAGs with proper dependency management, retry logic, and alerting.

Concept Mapping

Automation API JSON job definitionTask / Operator
FolderDAG
Job stream / Sub-folderTaskGroup
eventsToWaitFor (event condition)Upstream task dependency (>>)
eventsToAdd (event post)Downstream task dependency (>>)
Calendar / scheduling ruleschedule_interval / timetable
Do condition (OK/NOTOK)TriggerRule / BranchPythonOperator
Cyclic jobDAG with interval schedule
Global variable (%%VAR)Airflow Variable / Param
Control-M resourceAirflow Pool

The Hard Parts We Handle

  • Parsing Control-M Automation API JSON exports at scale
  • Translating eventsToAdd / eventsToWaitFor / eventsToDelete event chains
  • Mapping Control-M calendars to Airflow timetables
  • Converting %%VARIABLE substitution to Airflow templating ({{ }})
  • Global resource contention → Airflow Pools
  • Cross-datacenter job dependencies

Control-M Automation API JSON to DAG

Before

{
  "Defaults": {
    "Application": "DataPlatform",
    "SubApplication": "DailyETL",
    "RunAs": "ctmuser",
    "Host": "ctm-agent-01"
  },
  "DAILY_ETL": {
    "Type": "Folder",
    "ControlmServer": "CTMSRV01",
    "EXTRACT": {
      "Type": "Job:Command",
      "Command": "/etl/extract.sh",
      "eventsToAdd": {
        "Type": "AddEvents",
        "Events": [{ "Event": "EXTRACT-OK" }]
      }
    },
    "LOAD": {
      "Type": "Job:Command",
      "Command": "/etl/load.sh",
      "eventsToWaitFor": {
        "Type": "WaitForEvents",
        "Events": [{ "Event": "EXTRACT-OK" }]
      }
    }
  }
}

After (Airflow)

# Apache Airflow DAG
from airflow.decorators import dag
from airflow.operators.bash import BashOperator
from pendulum import datetime

@dag(schedule="@daily", start_date=datetime(2025,1,1), catchup=False)
def daily_etl():
    extract = BashOperator(task_id="extract", bash_command="/opt/etl/extract.sh")
    load = BashOperator(task_id="load", bash_command="/opt/etl/load.sh")
    extract >> load

daily_etl()

Ready to migrate from BMC Control-M?

Talk to a BatchFoundry engineer about your workload estate.

Talk to an Engineer

Related Migrations