Skip to content

Terraform Examples for MLOps Training

This directory contains practical examples demonstrating various Terraform concepts from basic to intermediate levels.

Available Examples

ExampleDescriptionDifficulty
data-sourcesQuery existing AWS resources and dataBeginner
for-eachCreate multiple resources with for_each and countIntermediate
localsUse local values for reusable expressionsIntermediate
outputsDefine and format outputs for various use casesBeginner
modulesCreate reusable infrastructure componentsIntermediate
conditionalsEnvironment-specific configurations with logicIntermediate
lifecycleSafe resource updates and protectionIntermediate
remote-stateS3 backend for teamsIntermediate

Recommended order: data-sources → outputs → locals → for-each → modules → conditionals → lifecycle → remote-state


How to Use These Examples

Prerequisites

  1. Terraform 1.14+ installed
  2. AWS account with credentials configured
  3. Basic understanding of Terraform from the main README

Running an Example

bash
# Navigate to the example directory
cd module-01/terraform/examples/data-sources

# Initialize Terraform
terraform init

# Review the plan
terraform plan

# Apply (only if you want to create resources)
terraform apply

Example Descriptions

1. Data Sources (data-sources/)

Learn how to:

  • Query AWS account and region information
  • Find existing VPCs, subnets, and security groups
  • Get the latest AMI IDs dynamically
  • Query S3 buckets and IAM roles
  • Filter resources by tags and attributes

Key Concepts:

  • data blocks
  • Filtering with filter blocks
  • Referencing data sources in resources
  • Using try() for safe access

2. For Each & Count (for-each/)

Learn how to:

  • Create multiple resources from a list using count
  • Create resources from maps using for_each
  • Use dynamic blocks with for_each
  • Handle nested configurations
  • Choose between count and for_each

Key Concepts:

  • count meta-argument
  • for_each meta-argument
  • Dynamic blocks
  • Resource references with indices and keys
  • Flattening nested structures

3. Locals (locals/)

Learn how to:

  • Define reusable values within a module
  • Create naming conventions
  • Build complex tag combinations
  • Use conditionals in locals
  • Transform and filter data with locals

Key Concepts:

  • locals blocks
  • DRY (Don't Repeat Yourself) principle
  • String manipulation and regex
  • Merge and transform functions
  • Environment-specific configurations

4. Outputs (outputs/)

Learn how to:

  • Define basic outputs
  • Create complex nested outputs
  • Format outputs for human consumption
  • Mark sensitive outputs
  • Generate JSON and file outputs

Key Concepts:

  • output blocks
  • Descriptions and formatting
  • Sensitive outputs
  • Template rendering
  • Cross-module outputs

5. Modules (modules/)

Learn how to:

  • Organize code into reusable modules
  • Define module inputs and outputs
  • Compose multiple modules
  • Use modules for ML infrastructure patterns

Key Concepts:

  • Module structure and files
  • Module inputs (variables)
  • Module outputs
  • Module composition for ML workloads

ML Use Cases:

  • Reusable ML model storage module
  • Training data module with intelligent tiering
  • Artifacts module for pipeline outputs

6. Conditionals (conditionals/)

Learn how to:

  • Use ternary operators for value selection
  • Conditionally create resources with count
  • Filter resources with for_each conditionals
  • Use dynamic blocks with conditionals
  • Validate inputs with conditionals

Key Concepts:

  • Ternary operator: condition ? true_value : false_value
  • Conditional count: condition ? 1 : 0
  • Filtered for_each: for_each = {for k, v in map : k => v if v.condition}
  • Dynamic blocks with conditional iteration

ML Use Cases:

  • Environment-specific instance types
  • Production-only lifecycle rules
  • Conditional monitoring and alerts
  • Account-based compliance levels

7. Lifecycle (lifecycle/)

Learn how to:

  • Use create_before_destroy for zero-downtime updates
  • Protect critical resources with prevent_destroy
  • Ignore dynamic changes with ignore_changes
  • Force replacement with replace_triggered_by

Key Concepts:

  • create_before_destroy - Safe updates
  • prevent_destroy - Deletion protection
  • ignore_changes - Skip drift detection
  • replace_triggered_by - Conditional replacement

ML Use Cases:

  • Zero-downtime model deployment
  • Production model storage protection
  • Ignoring ML pipeline tags
  • Replacing resources on model version change

8. Remote State (remote-state/)

Learn how to:

  • Configure S3 as a remote state backend
  • Use modern S3 lock file (no DynamoDB needed)
  • Enable state encryption and versioning
  • Work with both AWS and LocalStack

Key Concepts:

  • S3 remote state backend
  • use_lockfile option
  • State security and recovery
  • LocalStack for local development

Common Patterns

Pattern 1: Dynamic Resource Naming

hcl
locals {
  name_prefix = "${var.project_name}-${var.environment}"
}

resource "aws_s3_bucket" "example" {
  bucket = "${local.name_prefix}-models"
}

Pattern 2: Conditional Resource Creation

hcl
resource "aws_cloudwatch_log_group" "example" {
  count = var.enable_logging ? 1 : 0
  name  = "/aws/ml/example"
}

Pattern 3: Iterating Over a Map

hcl
resource "aws_s3_bucket" "buckets" {
  for_each = {
    "dev" = "ml-dev-data"
    "prod" = "ml-prod-data"
  }
  bucket = each.value
}

Pattern 4: Combining Tags

hcl
locals {
  common_tags = {
    Project     = var.project_name
    Environment = var.environment
  }

  specific_tags = {
    Purpose = "ml-storage"
  }

  all_tags = merge(local.common_tags, local.specific_tags)
}

resource "aws_s3_bucket" "example" {
  bucket = "example-bucket"
  tags   = local.all_tags
}

Practice Exercises

Exercise 1: Create Multi-Environment S3 Buckets

Using the for-each example as reference:

  • Create S3 buckets for dev, staging, and prod
  • Apply different lifecycle rules for each environment
  • Output all bucket names and ARNs

Exercise 2: Build a Naming Convention

Using the locals example as reference:

  • Create a locals block with naming conventions
  • Apply the naming convention to multiple resources
  • Ensure all resources have consistent tags

Exercise 3: Query and Use Existing Resources

Using the data-sources example as reference:

  • Find an existing VPC in your account
  • Query the latest Amazon Linux AMI
  • Create an EC2 instance in the VPC with the AMI

Exercise 4: Build a Reusable Module

Using the modules example as reference:

  • Create a simple module for ML model storage
  • Define input variables for customization
  • Output the bucket name and ARN
  • Use the module in your root configuration

Exercise 5: Environment-Specific Configuration

Using the conditionals example as reference:

  • Create different instance types per environment
  • Add production-only monitoring resources
  • Implement conditional tagging

Exercise 6: Safe Resource Updates

Using the lifecycle example as reference:

  • Create a resource with create_before_destroy
  • Add prevent_destroy to critical storage
  • Use ignore_changes for dynamic tags

Exercise 7: Configure Remote State

Using the remote-state example as reference:

  • Set up an S3 bucket for state storage
  • Configure the S3 backend with encryption
  • Enable state locking

Tips for Success

  1. Start with terraform plan - Always review before applying
  2. Use descriptions - Document your outputs and variables
  3. Check the state - Use terraform show to inspect results
  4. Clean up - Run terraform destroy when done practicing
  5. Experiment - Modify the examples and see what happens

Next Steps

After mastering these examples:

  1. Complete the main basics exercises
  2. Work through the comprehensive exercises
  3. Build your own MLOps infrastructure from scratch
  4. Explore Terraform Cloud/Enterprise for team collaboration

Learning Path

Recommended order for learning:

  1. Beginnerdata-sources, outputs
  2. Intermediatelocals, for-each
  3. Advancedmodules, conditionals, lifecycle
  4. Productionremote-state

Need Help? Refer to the main Terraform Basics guide or main README

Released under the MIT License.