Terraform/IaC Export

FakeDataDSL can export your schemas to Terraform HCL configurations, generating infrastructure definitions for AWS DynamoDB, RDS PostgreSQL, S3, and more.

Quick Start

# Export single schema
fake_data_dsl export schemas/user.dsl -f terraform -o main.tf

# Export all schemas
fake_data_dsl export schemas/ --all -f terraform -o infrastructure/
# Ruby API
schema = FakeDataDSL.load("schemas/user.dsl")
terraform = FakeDataDSL::Export::Terraform.new(schema).export
puts terraform

Basic Usage

Single Schema Export

# Input schema (user.dsl)
# User:
#   id: uuid @key
#   email: email @unique @indexed
#   name: name
#   role: enum(user, admin)
#   created_at: timestamp

schema = FakeDataDSL.load("schemas/user.dsl")
exporter = FakeDataDSL::Export::Terraform.new(schema)
puts exporter.export

Output:

# Generated by FakeDataDSL
# Schema: User

resource "aws_dynamodb_table" "users" {
  name           = "users"
  billing_mode   = "PAY_PER_REQUEST"
  hash_key       = "id"

  attribute {
    name = "id"
    type = "S"
  }

  attribute {
    name = "email"
    type = "S"
  }

  global_secondary_index {
    name            = "email-index"
    hash_key        = "email"
    projection_type = "ALL"
  }

  tags = {
    ManagedBy = "FakeDataDSL"
    Schema    = "User"
  }
}

Supported Providers

AWS DynamoDB

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_dynamodb
)

Features:

  • Hash and range keys
  • Global Secondary Indexes
  • Local Secondary Indexes
  • TTL configuration
  • Stream configuration

AWS RDS PostgreSQL

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_rds_postgresql
)

Output:

resource "aws_db_instance" "main" {
  identifier        = "fake-data-db"
  engine            = "postgres"
  engine_version    = "15.4"
  instance_class    = "db.t3.micro"
  allocated_storage = 20

  db_name  = "fake_data"
  username = var.db_username
  password = var.db_password
}

resource "postgresql_schema" "users" {
  name     = "public"
  database = aws_db_instance.main.db_name
}

resource "postgresql_table" "users" {
  name   = "users"
  schema = postgresql_schema.users.name

  column {
    name = "id"
    type = "uuid"
    default = "gen_random_uuid()"
    nullable = false
  }

  column {
    name = "email"
    type = "varchar(255)"
    nullable = false
  }

  column {
    name = "name"
    type = "varchar(255)"
    nullable = false
  }

  primary_key {
    columns = ["id"]
  }

  unique {
    columns = ["email"]
  }
}

AWS S3 (for data storage)

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_s3
)

Output:

resource "aws_s3_bucket" "users_data" {
  bucket = "users-data-${var.environment}"

  tags = {
    Schema = "User"
  }
}

resource "aws_s3_bucket_versioning" "users_data" {
  bucket = aws_s3_bucket.users_data.id
  versioning_configuration {
    status = "Enabled"
  }
}

Google Cloud (Firestore)

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :gcp_firestore
)

Azure (Cosmos DB)

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :azure_cosmosdb
)

Configuration Options

Basic Options

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_dynamodb,
  region: "us-east-1",
  environment: "production",
  prefix: "myapp",
  tags: {
    Project: "MyProject",
    Team: "Backend"
  }
)

DynamoDB-Specific

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_dynamodb,
  billing_mode: "PROVISIONED",  # or "PAY_PER_REQUEST"
  read_capacity: 5,
  write_capacity: 5,
  enable_ttl: true,
  ttl_attribute: "expires_at",
  enable_streams: true,
  stream_view_type: "NEW_AND_OLD_IMAGES"
)

RDS-Specific

exporter = FakeDataDSL::Export::Terraform.new(schema,
  provider: :aws_rds_postgresql,
  instance_class: "db.t3.medium",
  allocated_storage: 100,
  max_allocated_storage: 500,
  multi_az: true,
  backup_retention_period: 7
)

Type Mapping

DSL to DynamoDB

DSL Type DynamoDB Type
uuid, text, email S (String)
number, integer N (Number)
boolean BOOL
array(...) L (List)
json, object M (Map)
binary B (Binary)

DSL to PostgreSQL

DSL Type PostgreSQL Type
uuid uuid
text, name varchar(255)
paragraph text
number integer
float double precision
money numeric(10,2)
boolean boolean
date date
timestamp timestamp with time zone
json jsonb
array(text) text[]

CLI Commands

# Basic export
fake_data_dsl export schemas/ -f terraform -o main.tf

# With provider
fake_data_dsl export schemas/ -f terraform \
  --provider aws_dynamodb \
  -o dynamodb.tf

# With options
fake_data_dsl export schemas/ -f terraform \
  --provider aws_rds_postgresql \
  --region us-west-2 \
  --environment staging \
  -o rds.tf

# Multiple providers
fake_data_dsl export schemas/ -f terraform \
  --provider aws_dynamodb,aws_s3 \
  -o infrastructure/

Multi-Schema Infrastructure

Export All Schemas

schemas = FakeDataDSL.load_all("schemas/")
exporter = FakeDataDSL::Export::Terraform.new(*schemas,
  provider: :aws_dynamodb
)

File.write("main.tf", exporter.export)

Separate Files

schemas = FakeDataDSL.load_all("schemas/")

schemas.each do |schema|
  exporter = FakeDataDSL::Export::Terraform.new(schema)
  File.write("terraform/#{schema.name.underscore}.tf", exporter.export)
end

Modular Structure

exporter = FakeDataDSL::Export::Terraform.new(*schemas,
  structure: :modular  # Creates module structure
)

exporter.export_to_directory("terraform/")
# Creates:
# terraform/
#   main.tf
#   variables.tf
#   outputs.tf
#   modules/
#     users/
#       main.tf
#       variables.tf
#     orders/
#       main.tf
#       variables.tf

Variables and Outputs

Generated Variables

# variables.tf
variable "environment" {
  description = "Deployment environment"
  type        = string
  default     = "development"
}

variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "tags" {
  description = "Common tags for all resources"
  type        = map(string)
  default     = {}
}

Generated Outputs

# outputs.tf
output "users_table_arn" {
  description = "ARN of the users DynamoDB table"
  value       = aws_dynamodb_table.users.arn
}

output "users_table_name" {
  description = "Name of the users DynamoDB table"
  value       = aws_dynamodb_table.users.name
}

API Reference

Terraform.new

FakeDataDSL::Export::Terraform.new(*schemas, options = {})

Parameters:

  • schemas - One or more Schema objects
  • options[:provider] - Cloud provider
  • options[:region] - Cloud region
  • options[:environment] - Environment name
  • options[:prefix] - Resource name prefix
  • options[:tags] - Default tags
  • options[:structure] - :flat or :modular

Terraform#export

exporter.export
# => String containing HCL configuration

Terraform#export_to_directory

exporter.export_to_directory(path)
# Creates directory structure with .tf files

Best Practices

1. Use Modules for Reusability

exporter = FakeDataDSL::Export::Terraform.new(schema,
  structure: :modular,
  module_source: "git::https://github.com/org/terraform-modules.git"
)

2. Environment Separation

%w[development staging production].each do |env|
  exporter = FakeDataDSL::Export::Terraform.new(schema,
    environment: env
  )
  File.write("environments/#{env}/main.tf", exporter.export)
end

3. Version Control Generated Files

Keep generated Terraform in version control but mark as generated:

# GENERATED FILE - DO NOT EDIT
# Generated by FakeDataDSL from schemas/user.dsl
# Regenerate with: fake_data_dsl export schemas/user.dsl -f terraform

See Also