Based on the MLA-C01 exam guideReport an error
The pipelines, Registry, and CI/CD so far all rested on the premise that "infrastructure is laid down somewhere." If that infrastructure is built by clicking by hand in the console, it cannot be reproduced and drift appears between environments.
| Comparison axis | CloudFormation | AWS CDK |
|---|---|---|
| How it is written | YAML/JSON declarative templates | Programming languages such as Python and TypeScript |
| Loops and conditions | Limited expression through built-in functions | Freely, with the language's for, if, and functions |
| Abstraction | Lists resources as they are | Bundle into components (Constructs) for reuse |
| Final output | The stack definition itself | Synthesizing (synth) yields a CloudFormation template |
| Learning curve | Simple syntax, verbose at scale | Fast if you know the language, but you must understand the abstractions |
| When to choose it | Simple, static infrastructure; a team comfortable with YAML | Multi-environment setups with a lot of repetition; developer-centered teams |
With CloudFormation, you write the "desired state" in a template and it builds it as a stack. An example of defining a SageMaker endpoint as IaC:
# CloudFormation: declare a SageMaker endpoint as code
Resources:
MyModel:
Type: AWS::SageMaker::Model
Properties:
ExecutionRoleArn: !Ref SageMakerRoleArn
PrimaryContainer:
Image: !Ref InferenceImageUri
ModelDataUrl: !Ref ModelArtifactS3Uri
MyEndpointConfig:
Type: AWS::SageMaker::EndpointConfig
Properties:
ProductionVariants:
- ModelName: !GetAtt MyModel.ModelName
VariantName: AllTraffic
InstanceType: ml.m5.large
InitialInstanceCount: 1
MyEndpoint:
Type: AWS::SageMaker::Endpoint
Properties:
EndpointConfigName: !GetAtt MyEndpointConfig.EndpointConfigNameCDK writes the same thing as code (an advantage for loops, conditions, and abstraction).
# AWS CDK (Python): synthesizing generates CloudFormation equivalent to the above
from aws_cdk import aws_sagemaker as sagemaker
model = sagemaker.CfnModel(self, "MyModel",
execution_role_arn=role_arn,
primary_container={"image": image_uri, "modelDataUrl": model_s3_uri},
)!Ref, you can redeploy by swapping only the model version in the same template. This is exactly what the Deploy pipeline does.💡 Related theory: The core value of IaC is idempotency and reproducibility. Applying the same template any number of times ends in the same resulting state, and drift between environments disappears. This is also why SageMaker Projects uses CloudFormation internally. In the exam, "manage infrastructure as reproducible code" means CloudFormation/CDK.
SageMaker Pipelines centers on SageMaker jobs. AWS Step Functions, on the other hand, orchestrates workflows that span multiple AWS services — Lambda, Glue, SageMaker, ECS, SNS, and others — as a state machine. If an ML workflow contains many steps outside SageMaker (for example, notification via Lambda, ETL via Glue, updating DynamoDB), Step Functions is a good fit.
{
"Comment": "State machine linking ETL → training → notification",
"StartAt": "GlueETL",
"States": {
"GlueETL": { "Type": "Task", "Resource": "arn:aws:states:::glue:startJobRun.sync", "Next": "TrainModel" },
"TrainModel": { "Type": "Task", "Resource": "arn:aws:states:::sagemaker:createTrainingJob.sync", "Next": "Notify" },
"Notify": { "Type": "Task", "Resource": "arn:aws:states:::sns:publish", "End": true }
}
}| State type | What it does |
|---|---|
Task | Calls the actual work (Lambda, Glue, SageMaker, etc.) |
Choice | Conditional branching |
Parallel | Runs several branches at the same time |
Map | Repeats the same processing for each element of an array |
Wait | Waits for a set time or until a point in time |
Retry / Catch | Retry policy and error handling |
.sync integration lets you wait until the job completes. Without it, the training job is only started and execution moves on to the next state immediately.Amazon EventBridge is an event bus that receives events and routes them to targets according to rules. Its uses in ML:
import boto3
events = boto3.client("events")
# A schedule rule that triggers the retraining pipeline every day at 02:00 (UTC)
events.put_rule(
Name="nightly-retrain",
ScheduleExpression="cron(0 2 * * ? *)",
)
# (Connect a Lambda that runs the SageMaker Pipeline, or Step Functions, as the target)EventBridge is the glue that "starts a workflow when something happens (or at a set time)." It does not define the workflow itself; it sends the start signal.
| Rule component | What it does |
|---|---|
| Event pattern | Describes in JSON which events to react to (source, detail-type, detail) |
| Schedule expression | A time-based trigger. cron(...) or rate(...) — the reference time is UTC |
| Target | What to invoke when an event matches (Lambda, Step Functions, CodePipeline, etc.) |
| Target invocation role | The IAM role EventBridge uses when calling the target. Without it, it fails silently |
[New data in S3] [Model Approved] [Every day 02:00]
│ │ │
└────────────────┼────────────────┘
▼
EventBridge rule
(pattern matching / schedule)
│ target specified
┌────────────────┼────────────────┐
▼ ▼ ▼
SageMaker Pipeline Step Functions CodePipeline
(start run) (state machine) (start deploy)Amazon MWAA (Managed Workflows for Apache Airflow) is managed Airflow. It defines workflows as DAGs written in Python and uses Airflow's rich operator ecosystem as is. Choose it in these situations.
# Airflow DAG for MWAA (conceptual): Airflow orchestrates SageMaker training
from airflow import DAG
from airflow.providers.amazon.aws.operators.sagemaker import (
SageMakerTrainingOperator,
)
with DAG("ml_retrain", schedule_interval="@daily") as dag:
train = SageMakerTrainingOperator(
task_id="train_model",
config=training_job_config,
)Choosing an orchestrator is a question of "how much you bundle + what existing assets you have." SageMaker jobs only → Pipelines. Serverless workflow across multiple AWS services → Step Functions. Existing Airflow assets or hybrid → MWAA. Simple trigger/schedule → EventBridge. Infrastructure definition → CloudFormation/CDK. The exam separates these five by scenario.
| Tool | Nature | When to use | Exam keywords |
|---|---|---|---|
| CloudFormation / CDK | IaC (infrastructure definition) | Reproduce and version-manage infrastructure as code | Reproducible, environment consistency, eliminating drift |
| SageMaker Pipelines | ML workflow | SageMaker-job-centered, lineage and Registry integration | Preprocessing → training → evaluation → registration, lineage |
| Step Functions | General-purpose workflow | Serverless orchestration across multiple AWS services | Glue+Lambda+SNS, branching and retry |
| EventBridge | Trigger | Start a workflow by schedule or event | Every day before dawn, on approval, when new data arrives |
| MWAA (Airflow) | Managed workflow | Existing Airflow assets, hybrid, complex DAGs | Already using Airflow, includes on-premises |
⚠️ Trap: An answer choice that presents EventBridge as an orchestrator is wrong. EventBridge only decides "when to start" and knows nothing about "what to do in what order." If branching, retry, or dependencies are in the requirement, the answer is Step Functions or Pipelines, and EventBridge is just the trigger attached in front of them.
| Symptom | Common cause | Action |
|---|---|---|
| Endpoint settings differ subtly between environments | Drift from manual creation in the console | Deploy uniformly from a single CloudFormation/CDK template |
| It moves on to the next state before training finishes | The .sync integration is not used in Step Functions | Change to a .sync resource so it waits for completion |
| A schedule rule exists but nothing runs | Target not connected, rule disabled, cron expression error | Check the target, the enabled state, and the expression (UTC based) |
| The trigger fires but the target refuses to run | EventBridge lacks permission to invoke the target | Grant permissions to the target invocation role |
| You cannot build retry and branching in a pipeline | Wrong tool choice (the scope goes beyond SageMaker) | Move up to Step Functions for the higher-level orchestration |
| The stack deployment fails and rolls back entirely | Resource name collision, insufficient permissions, dependent resource not created | Check from the first failed resource in the stack events |
| Airflow environment cost keeps accruing | MWAA is an always-running environment | If the workflow is event-driven in nature, consider Step Functions |
| You hand-edited the pipeline definition and it vanished on the next deployment | An IaC-managed resource was modified in the console | Make changes only in code and redeploy as a stack |
The five tools are not competitors but layers. From the bottom they stack as IaC (what exists) → workflow (what to do in what order) → trigger (when it starts). When reading a scenario, first ask "which layer is this about?" and some answer choices are filtered out automatically.
Tomorrow we review this week's MLOps pieces by tying them into a single chain.
.sync integration: A mode in which Step Functions waits until the job it invoked finishes before moving on to the next.Click a choice to reveal the answer and explanation.
Question 1
You want to reproduce SageMaker endpoints, IAM roles, and buckets identically across dev/staging/prod and version-control the changes. What is the most appropriate approach?
Question 2
An ML workflow spans multiple AWS services, such as Glue ETL → SageMaker training → Lambda post-processing → SNS notification, and requires branching, retries, and error handling. What is the most suitable orchestrator?
Question 3
You want to orchestrate an ML workflow made up of only SageMaker jobs while also enjoying lineage tracking and Model Registry integration. What is most suitable?
Question 4
An organization already runs complex data dependencies, including on-premises ones, as Apache Airflow DAGs and wants to continue them on AWS as a managed service. What is the most appropriate service?
Question 5
You want to automatically start a retraining pipeline at 2 AM every day. What is the simplest and most appropriate trigger method?