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