
Terraform Data Engineering Iac
- 1.5k installs
- 4 repo stars
- Updated July 18, 2026
- aradotso/data-skills
Provision reproducible AWS data-lake and processing infrastructure with Terraform instead of clicking through the console.
About
Terraform Data Engineering IaC is an agent skill from ara.so’s Data Skills collection that teaches Infrastructure-as-Code patterns for solo and indie data builders who need AWS without manual console drift. It walks through provisioning S3 for lake storage, EC2 for processing, and IAM for secure access, with Terraform state as the source of truth for changes. Use it when triggers fire around setting up data engineering infrastructure, automating data platform provisioning, or managing pipeline-related cloud resources as code. You need an AWS account, Terraform CLI, and AWS CLI configured with permissions for S3, EC2, and IAM. The skill fits builders shipping pipelines or analytics backends who want the same environment every deploy, not one-off buckets and instances. It is a task integration for cloud provisioning, not a full MLOps or orchestration playbook—pair it with your orchestrator and monitoring choices separately.
- Provisions AWS S3 buckets for data lake storage
- Creates EC2 instances for pipeline and processing workloads
- Manages IAM policies for least-privilege access to data resources
- Uses Terraform state to track and roll back infrastructure changes
- Reproducible stack for common data-engineering AWS patterns
Terraform Data Engineering Iac by the numbers
- 1,507 all-time installs (skills.sh)
- +2 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #272 of 1,041 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aradotso/data-skills --skill terraform-data-engineering-iacAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.5k |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 18, 2026 |
| Repository | aradotso/data-skills ↗ |
What it does
Provision reproducible AWS data-lake and processing infrastructure with Terraform instead of clicking through the console.
Files
Terraform Data Engineering IaC
Skill by ara.so — Data Skills collection.
This project demonstrates Infrastructure-as-Code (IaC) fundamentals for data engineering using Terraform. It provisions AWS resources commonly used in data pipelines including S3 buckets for data storage and EC2 instances for data processing workloads.
What It Does
- Provisions AWS S3 buckets for data lake storage
- Creates EC2 instances for data processing and pipeline execution
- Manages IAM policies for secure resource access
- Uses Terraform state to track and manage infrastructure changes
- Provides reproducible infrastructure for data engineering environments
Prerequisites
Before using this project, ensure you have:
1. AWS Account with appropriate permissions 2. Terraform CLI installed 3. AWS CLI installed and configured 4. IAM user with S3, EC2, and IAM permissions
Installation
1. Install Terraform
# macOS
brew install terraform
# Linux
wget https://releases.hashicorp.com/terraform/1.5.0/terraform_1.5.0_linux_amd64.zip
unzip terraform_1.5.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/
# Verify installation
terraform version2. Install AWS CLI
# macOS
brew install awscli
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Configure AWS credentials
aws configure3. Set Up IAM Permissions
Create an IAM user with the following managed policies:
AmazonS3FullAccessAmazonEC2FullAccessIAMFullAccess
Note: For production, use fine-grained permissions instead of full access.
Project Structure
terraform/
├── main.tf # Main infrastructure definitions
├── variables.tf # Input variables
├── outputs.tf # Output values
└── terraform.tfstate # State file (generated)Key Terraform Commands
Initialize Terraform
# Initialize backend and download providers
terraform -chdir=terraform initValidate Configuration
# Check syntax and validate configuration
terraform -chdir=terraform validateFormat Code
# Auto-format HCL files
terraform -chdir=terraform fmtPlan Infrastructure Changes
# Preview what will be created/changed
terraform -chdir=terraform planApply Infrastructure
# Create or update infrastructure
terraform -chdir=terraform apply
# Auto-approve without confirmation (use carefully)
terraform -chdir=terraform apply -auto-approveDestroy Infrastructure
# Remove all managed infrastructure
terraform -chdir=terraform destroy
# Auto-approve destruction (use carefully)
terraform -chdir=terraform destroy -auto-approveState Management
# List all resources in state
terraform -chdir=terraform state list
# Show detailed resource information
terraform -chdir=terraform state show aws_s3_bucket.data_bucket
# View state as JSON
cat terraform/terraform.tfstate | jq -r '.resources[] | [.type, .name] | join(",")'Configuration Examples
Basic S3 Bucket for Data Storage
# terraform/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_s3_bucket" "data_lake" {
bucket = "my-unique-data-lake-bucket-${var.environment}"
tags = {
Name = "Data Lake Bucket"
Environment = var.environment
Project = "data-engineering"
}
}
resource "aws_s3_bucket_versioning" "data_lake_versioning" {
bucket = aws_s3_bucket.data_lake.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_lifecycle_configuration" "data_lake_lifecycle" {
bucket = aws_s3_bucket.data_lake.id
rule {
id = "archive_old_data"
status = "Enabled"
transition {
days = 90
storage_class = "GLACIER"
}
expiration {
days = 365
}
}
}EC2 Instance for Data Processing
# terraform/main.tf (continued)
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
resource "aws_instance" "data_processor" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
tags = {
Name = "Data Processing Server"
Environment = var.environment
}
user_data = <<-EOF
#!/bin/bash
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 install pandas boto3 apache-airflow
EOF
}
resource "aws_eip" "data_processor_eip" {
instance = aws_instance.data_processor.id
domain = "vpc"
}Variables Configuration
# terraform/variables.tf
variable "aws_region" {
description = "AWS region for resources"
type = string
default = "us-east-1"
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.medium"
}Outputs Configuration
# terraform/outputs.tf
output "s3_bucket_name" {
description = "Name of the S3 data lake bucket"
value = aws_s3_bucket.data_lake.id
}
output "ec2_public_ip" {
description = "Public IP of data processing EC2 instance"
value = aws_eip.data_processor_eip.public_ip
}
output "ec2_instance_id" {
description = "Instance ID of data processor"
value = aws_instance.data_processor.id
}Common Patterns
Multi-Environment Setup
# Use workspace or separate state files
terraform workspace new staging
terraform workspace new production
# Or use variable files
terraform apply -var-file="environments/dev.tfvars"
terraform apply -var-file="environments/prod.tfvars"Remote State with S3 Backend
# terraform/backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "data-engineering/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}IAM Role for EC2 with S3 Access
resource "aws_iam_role" "data_processor_role" {
name = "data-processor-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "s3_access" {
role = aws_iam_role.data_processor_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}
resource "aws_iam_instance_profile" "data_processor_profile" {
name = "data-processor-profile"
role = aws_iam_role.data_processor_role.name
}
resource "aws_instance" "data_processor" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
iam_instance_profile = aws_iam_instance_profile.data_processor_profile.name
}Verification Commands
Verify S3 Buckets
# List all S3 buckets
aws s3 ls
# Get bucket details
aws s3api get-bucket-location --bucket my-data-lake-bucket
# List bucket contents
aws s3 ls s3://my-data-lake-bucket/Verify EC2 Instances
# List running instances
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--query 'Reservations[].Instances[].{ID:InstanceId, Name:Tags[?Key==`Name`].Value, Type:InstanceType, State:State.Name, PublicIP:PublicIpAddress, PrivateIP:PrivateIpAddress}' \
--output table
# Get specific instance details
aws ec2 describe-instances --instance-ids i-1234567890abcdef0Connect to EC2 Instance
# SSH into instance (requires key pair)
ssh -i ~/.ssh/my-key.pem ubuntu@$(terraform -chdir=terraform output -raw ec2_public_ip)Troubleshooting
Issue: Terraform Init Fails
# Clear cache and reinitialize
rm -rf terraform/.terraform
rm terraform/.terraform.lock.hcl
terraform -chdir=terraform initIssue: State Lock Error
# Force unlock (use with caution)
terraform -chdir=terraform force-unlock LOCK_IDIssue: AWS Credentials Not Found
# Verify AWS configuration
aws configure list
aws sts get-caller-identity
# Set credentials explicitly
export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}"
export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}"
export AWS_DEFAULT_REGION="us-east-1"Issue: Resource Already Exists
# Import existing resource into state
terraform -chdir=terraform import aws_s3_bucket.data_lake my-existing-bucket
# Or recreate with unique name
terraform -chdir=terraform apply -var="bucket_suffix=$(date +%s)"Issue: Permission Denied
Check IAM policies and ensure your user has required permissions:
# Test S3 permissions
aws s3 ls
# Test EC2 permissions
aws ec2 describe-instances
# Test IAM permissions
aws iam list-usersDebugging Terraform
# Enable debug logging
export TF_LOG=DEBUG
terraform -chdir=terraform apply
# Show detailed plan
terraform -chdir=terraform plan -out=tfplan
terraform -chdir=terraform show tfplan
# Refresh state from actual infrastructure
terraform -chdir=terraform refreshBest Practices
1. Always use unique bucket names: S3 bucket names must be globally unique 2. Version your state files: Enable S3 versioning for state file backups 3. Use remote state: Store state in S3 with locking via DynamoDB 4. Tag all resources: Apply consistent tagging for cost tracking and organization 5. Use variables: Parameterize configurations for reusability 6. Run `terraform plan` before apply to review changes 7. Destroy dev resources: Don't leave test infrastructure running to avoid costs