What is AWS Glue DataBrew?
AWS Glue DataBrew is a no-code visual data preparation tool that enables data scientists, data engineers, and data analysts to clean, normalize, and transform data without writing code. It provides over 250 pre-built transformations for tasks like data profiling, deduplication, and data quality validation.
Core Concepts
| Concept | Description |
|---|---|
| Project | A workspace for interactive data preparation and exploration |
| Recipe | A set of data transformation steps that can be versioned and published |
| Job | A scheduled or on-demand data preparation execution |
| Dataset | A connection to data in S3, Redshift, or other sources |
| Profile | Data statistics and quality metrics generated for a dataset |
| Pattern | A rule-based transformation for applying consistent changes |
| Sticky Column | A column that remains visible during wide-dataset exploration |
DataBrew Architecture
How DataBrew Works
DataBrew reads data from source connectors, loads it into an interactive session for profiling and transformation, and writes the results to your chosen output. The recipe-based workflow ensures transformations are reproducible and version-controlled, while built-in data quality rules validate results at each step.
Real-World Project Structure
databrew-production/
āāā datasets/
ā āāā raw/
ā ā āāā customer-raw.json
ā ā āāā orders-raw.json
ā ā āāā products-raw.json
ā āāā connected/
ā āāā s3-customer-dataset.json
ā āāā redshift-sales-dataset.json
āāā projects/
ā āāā customer-cleaning/
ā ā āāā project-config.json
ā ā āāā interactive-session.yaml
ā āāā sales-enrichment/
ā āāā project-config.json
ā āāā interactive-session.yaml
āāā recipes/
ā āāā customer-standardization/
ā ā āāā v1-recipe.json
ā ā āāā v2-recipe.json
ā ā āāā published-recipe.json
ā āāā sales-deduplication/
ā āāā v1-recipe.json
ā āāā published-recipe.json
āāā jobs/
ā āāā recipe-jobs/
ā ā āāā daily-customer-clean.yaml
ā ā āāā weekly-sales-transform.yaml
ā ā āāā monthly-data-quality.yaml
ā āāā profile-jobs/
ā ā āāā customer-profile-daily.yaml
ā ā āāā sales-profile-weekly.yaml
ā āāā scheduling/
ā āāā step-functions/
ā ā āāā daily-databrew-pipeline.json
ā āāā eventbridge-rules.yaml
āāā monitoring/
ā āāā cloudwatch-alarms.yaml
ā āāā dashboards/
ā āāā job-performance.json
ā āāā data-quality-scores.json
āāā security/
āāā iam-roles/
ā āāā databrew-service-role.json
ā āāā s3-access-role.json
āāā vpc-config/
āāā endpoint-config.json
Production Python Code
import boto3
import json
import logging
import time
from datetime import datetime
from typing import Dict, List, Optional
logger = logging.getLogger(__name__)
class DataBrewManager:
"""Production-grade AWS Glue DataBrew manager."""
def __init__(self, region: str = 'us-east-1'):
self.client = boto3.client('databrew', region_name=region)
def create_dataset(
self,
name: str,
input_location: str,
format: str = 'PARQUET',
path_options: Optional[Dict] = None
) -> Dict:
"""Create a DataBrew dataset from S3."""
try:
kwargs = {
'Name': name,
'Input': {
'S3InputDefinition': {
'Bucket': input_location.split('/')[2],
'Key': '/'.join(input_location.split('/')[3:])
}
},
'FormatOptions': {
'Json': {'MultiLine': True} if format == 'JSON' else {}
},
'Format': format
}
if path_options:
kwargs['Input']['DataCatalogInputDefinition'] = path_options
response = self.client.create_dataset(**kwargs)
logger.info(f"Created dataset: {name}")
return response
except Exception as e:
logger.error(f"Failed to create dataset: {e}")
raise
def create_recipe_project(
self,
project_name: str,
dataset_name: str,
role_arn: str,
sample_size: str = '10000'
) -> Dict:
"""Create a DataBrew project for interactive exploration."""
try:
response = self.client.create_project(
Name=project_name,
DatasetName=dataset_name,
RoleArn=role_arn,
Sample={
'Size': int(sample_size)
}
)
logger.info(f"Created project: {project_name}")
return response
except Exception as e:
logger.error(f"Failed to create project: {e}")
raise
def create_recipe_job(
self,
job_name: str,
dataset_name: str,
recipe_version: str = 'LATEST_PUBLISHED',
output_location: str = '',
output_format: str = 'PARQUET',
role_arn: str = '',
max_capacity: int = 10,
timeout: int = 3600
) -> Dict:
"""Create a DataBrew recipe job."""
try:
response = self.client.create_job(
Name=job_name,
Type='RECIPE',
DatasetName=dataset_name,
RecipeVersion=recipe_version,
RoleArn=role_arn,
MaxCapacity=max_capacity,
Timeout=timeout,
Output={
'Location': {
'Bucket': output_location.split('/')[2],
'Key': '/'.join(output_location.split('/')[3:])
},
'Format': output_format,
'PartitionColumns': []
},
EncryptionOptions={
'SseKmsKey': 'arn:aws:kms:us-east-1:*:key/*',
'S3SseKmsEnabled': True
}
)
logger.info(f"Created recipe job: {job_name}")
return response
except Exception as e:
logger.error(f"Failed to create recipe job: {e}")
raise
def create_profile_job(
self,
job_name: str,
dataset_name: str,
output_location: str,
role_arn: str,
max_samples: int = 10000,
pattern_rules: Optional[List[Dict]] = None
) -> Dict:
"""Create a DataBrew profile job for data profiling."""
try:
response = self.client.create_job(
Name=job_name,
Type='PROFILE',
DatasetName=dataset_name,
RoleArn=role_arn,
MaxSamples=max_samples,
Output={
'Location': {
'Bucket': output_location.split('/')[2],
'Key': '/'.join(output_location.split('/')[3:])
},
'Format': 'JSON'
}
)
logger.info(f"Created profile job: {job_name}")
return response
except Exception as e:
logger.error(f"Failed to create profile job: {e}")
raise
def run_job(
self,
job_name: str,
run_id: Optional[str] = None
) -> Dict:
"""Start a DataBrew job run."""
try:
response = self.client.start_job_run(
JobName=job_name
)
run_id = response['RunId']
logger.info(f"Started job {job_name}, run: {run_id}")
return response
except Exception as e:
logger.error(f"Failed to start job: {e}")
raise
def wait_for_job(
self,
job_name: str,
run_id: str,
poll_interval: int = 30,
max_wait: int = 7200
) -> Dict:
"""Wait for a job run to complete."""
start_time = time.time()
while time.time() - start_time < max_wait:
response = self.client.get_job_run(
JobName=job_name,
RunId=run_id
)
state = response['JobRun']['State']
if state == 'SUCCEEDED':
logger.info(f"Job {job_name} completed successfully")
return response['JobRun']
elif state in ('FAILED', 'STOPPED'):
logger.error(
f"Job {job_name} {state}: "
f"{response['JobRun'].get('ErrorMessage', 'Unknown')}"
)
return response['JobRun']
logger.info(f"Job {job_name} state: {state}, waiting...")
time.sleep(poll_interval)
raise TimeoutError(f"Job {job_name} timed out after {max_wait}s")
def publish_recipe(
self,
project_name: str,
recipe_name: str,
description: str = ''
) -> str:
"""Publish a recipe from a project."""
try:
response = self.client.publish_project(
Name=project_name
)
version = response['RecipeVersion']
logger.info(
f"Published recipe {recipe_name}: version {version}"
)
return version
except Exception as e:
logger.error(f"Failed to publish recipe: {e}")
raise
def batch_delete_recipe_version(
self,
recipe_name: str,
versions: List[str]
) -> Dict:
"""Batch delete recipe versions."""
try:
response = self.client.batch_delete_recipe_version(
Name=recipe_name,
RecipeVersions=versions
)
logger.info(
f"Deleted {len(versions)} versions from {recipe_name}"
)
return response
except Exception as e:
logger.error(f"Failed to batch delete versions: {e}")
raise
# Production usage
if __name__ == '__main__':
databrew = DataBrewManager()
# Create dataset
dataset = databrew.create_dataset(
name='customer-data-raw',
input_location='s3://data-lake-raw/customers/',
format='PARQUET'
)
# Create project for interactive exploration
project = databrew.create_recipe_project(
project_name='customer-cleaning-project',
dataset_name='customer-data-raw',
role_arn='arn:aws:iam::*:role/databrew-service-role',
sample_size='50000'
)
print(f"Project created: {project}")
Production Bash Commands
#!/bin/bash
# DataBrew job monitoring and scheduling script
set -euo pipefail
PROJECT_NAME="${1:-customer-cleaning-project}"
DATASET_NAME="${2:-customer-data-raw}"
REGION="${AWS_REGION:-us-east-1}"
echo "=== AWS Glue DataBrew Status ==="
echo "Project: ${PROJECT_NAME}"
echo "Dataset: ${DATASET_NAME}"
echo "Region: ${REGION}"
echo "Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
# List datasets
echo ""
echo "=== Datasets ==="
aws databrew list-datasets \
--region "${REGION}" \
--query 'datasets[*].[Name,Format,CreateTime]' \
--output table
# List projects
echo ""
echo "=== Projects ==="
aws databrew list-projects \
--region "${REGION}" \
--query 'projects[*].[Name,DatasetName,CreateTime]' \
--output table
# List jobs
echo ""
echo "=== Jobs ==="
aws databrew list-jobs \
--region "${REGION}" \
--query 'jobs[*].[Name,Type,DatasetName,State]' \
--output table
# Get recent job runs
echo ""
echo "=== Recent Job Runs ==="
aws databrew list-job-runs \
--job-name "daily-customer-clean" \
--region "${REGION}" \
--query 'jobRuns[:5].[*].[RunId,State,StartTime,EndTime,RunBytes]' \
--output table
# Check data quality metrics
echo ""
echo "=== Data Quality Profile Output ==="
S3_PROFILE_PATH="s3://databrew-profiles/${DATASET_NAME}/latest"
aws s3 ls "${S3_PROFILE_PATH}" --recursive --human-readable 2>/dev/null || echo "No profile output found"
# Monitor CloudWatch metrics
echo ""
echo "=== DataBrew Metrics ==="
aws cloudwatch get-metric-statistics \
--namespace AWS/DataBrew \
--metric-name JobRuns \
--start-time "$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 300 \
--statistics Sum \
--region "${REGION}" | jq -r '.Datapoints[] | "\(.Timestamp): \(.Sum) runs"'
# Start a profile job
echo ""
echo "=== Starting Profile Job ==="
aws databrew start-job-run \
--job-name "customer-profile-daily" \
--region "${REGION}" | jq '.RunId'
echo ""
echo "Monitoring complete."
Why This Matters
Glue DataBrew democratizes data preparation by providing a no-code visual interface for cleaning, normalizing, and transforming data. Unlike code-based ETL tools, DataBrew enables data analysts and business users to prepare data without writing PySpark or SQL. The recipe-based workflow ensures reproducibility and version control, while integration with Glue Data Catalog enables seamless analytics pipeline orchestration.
Mathematical Formulas
Performance Considerations
| Factor | Recommendation | Impact |
|---|---|---|
| Sample Size | Use 10,000-100,000 rows for interactive sessions | Medium - balances speed and accuracy |
| Node Capacity | Use 5-10 nodes for most jobs | Medium - affects processing speed |
| Output Format | Use Parquet for analytics workloads | High - reduces downstream query cost |
| Partitioning | Partition output by date or category | High - improves downstream query pruning |
| Recipe Complexity | Minimize transform steps where possible | Medium - reduces processing time |
| Job Scheduling | Schedule during off-peak hours | Medium - reduces cost and resource contention |
| Monitoring | Set up CloudWatch alarms for failures | High - early detection of issues |
| Version Control | Publish recipes for production jobs | High - ensures reproducibility |
Security Considerations
- IAM Roles: Use least-privilege IAM roles for DataBrew service access
- Encryption at Rest: Enable S3 SSE-KMS for all input and output data
- Encryption in Transit: Enforce HTTPS for all DataBrew API calls
- VPC Endpoints: Use VPC endpoints for private network connectivity
- Resource Policies: Restrict DataBrew access to specific projects and datasets
- CloudTrail Logging: Log all DataBrew API calls for audit compliance
- Output Validation: Validate data quality scores before publishing
- Cross-Account Access: Use resource-based policies for cross-account scenarios
Common Pitfalls
| Pitfall | Consequence | Solution |
|---|---|---|
| Using large sample sizes | Slow interactive sessions | Start with 10K rows, increase as needed |
| Not publishing recipes | Non-reproducible transformations | Always publish recipes for production |
| Ignoring profile outputs | Undetected data quality issues | Run profile jobs regularly |
| No job monitoring | Undetected failures | Set up CloudWatch alarms |
| Missing encryption | Data exposure risk | Enable encryption for all I/O |
| No VPC deployment | Network exposure | Deploy in VPC with private endpoints |
| Skipping recipe versioning | Difficult to track changes | Use version control for all recipes |
| Disabling CloudWatch logs | No visibility into failures | Enable all logging exports |
Interview Questions & Answers
Q1: What is AWS Glue DataBrew and when would you use it?
Answer: AWS Glue DataBrew is a no-code visual data preparation tool for cleaning, normalizing, and transforming data. Use it when you need to prepare data for analytics or ML without writing code, when data analysts need self-service data preparation, or when you need reproducible and version-controlled data transformations. It complements code-based Glue ETL jobs for different user personas.
Q2: What is the difference between a DataBrew recipe and a recipe job?
Answer: A recipe is a collection of data transformation steps created interactively in a DataBrew project. A recipe job is the scheduled or on-demand execution of those recipe steps against a dataset. Recipes are version-controlled and published, while jobs handle the actual processing and output generation.
Q3: How does DataBrew handle data quality?
Answer: DataBrew provides data quality through: (1) Built-in statistical profiling with anomaly detection. (2) Data quality rules that validate values, patterns, and ranges. (3) Column-level statistics including nulls, uniqueness, and value distributions. (4) Row-level validation for data cleansing. (5) Integration with Glue Data Catalog for quality score tracking.
Q4: What types of DataBrew jobs are available?
Answer: DataBrew offers three job types: (1) Recipe jobs apply published transformation steps. (2) Profile jobs generate data statistics and quality metrics. (3) Cleansing jobs automatically clean data using pattern-based rules. Each type is optimized for specific use cases and can be scheduled via CloudWatch Events.
Q5: How do you optimize DataBrew job performance?
Answer: Optimization strategies: (1) Use appropriate sample sizes for interactive sessions. (2) Minimize the number of transformation steps in recipes. (3) Use Parquet output format for analytics. (4) Partition output data for downstream query efficiency. (5) Schedule jobs during off-peak hours. (6) Monitor node utilization and adjust capacity.
Q6: Can DataBrew integrate with other AWS services?
Answer: Yes, DataBrew integrates with: S3 for input/output storage, Glue Data Catalog for schema management, CloudWatch for monitoring and scheduling, IAM for access control, KMS for encryption, Step Functions for workflow orchestration, and EventBridge for event-driven job triggers.
Q7: How do you handle schema evolution in DataBrew?
Answer: DataBrew handles schema changes through: (1) Auto-detection of new columns during profile jobs. (2) Recipe step updates to accommodate new fields. (3) Schema mapping in project settings. (4) Version control for recipes to track schema changes over time. (5) Integration with Glue Schema Registry for centralized management.
Q8: What are the pricing considerations for DataBrew?
Answer: DataBrew charges $0.4862 per node-hour for job execution. Interactive sessions are billed per session hour. Costs depend on: (1) Data volume processed. (2) Number of transformation steps. (3) Node capacity configured. (4) Job duration. Use smaller nodes for lighter workloads and larger nodes for complex transformations.