Skip to main content

iac-data-engineering-terraform

Infrastructure-as-Code patterns for data engineering with Terraform on AWS (S3, EC2, IAM)

インストールへ移動

ソース情報

リポジトリ
reason-machines/data-skills
ソースの最終更新活動
2026年5月27日 19:22
検出された SKILL.md の言語
英語
スター
5
フォーク
1

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
iac-data-engineering-terraform
description
Infrastructure-as-Code patterns for data engineering with Terraform on AWS (S3, EC2, IAM)
triggers
["set up terraform for data engineering","create AWS infrastructure with terraform","manage data engineering infrastructure as code","terraform for S3 and EC2 setup","IaC patterns for data pipelines","deploy data engineering resources on AWS","terraform state management for data infrastructure","automate AWS data infrastructure provisioning"]
# IaC for Data Engineering with Terraform > Skill by [ara.so](https://ara.so) — Data Skills collection. This project demonstrates Infrastructure-as-Code (IaC) fundamentals for data engineers using Terraform to provision AWS resources including S3 buckets, EC2 instances, and IAM configurations. It provides reusable patterns for managing data infrastructure declaratively. ## What This Project Does - Provisions AWS S3 buckets for data storage - Creates and configures EC2 instances for data processing - Sets up IAM roles and policies with proper permissions - Manages infrastructure state with Terraform - Provides reproducible data engineering environments ## Prerequisites Before using this project, ensure you have: ```bash # Install Terraform brew tap hashicorp/tap brew install hashicorp/tap/terraform # Install AWS CLI brew install awscli # Configure AWS credentials aws configure # Enter your AWS Access Key ID, Secret Access Key, region, and output format ``` Set up required environment variables: ```bash export AWS_ACCESS_KEY_ID=$YOUR_ACCESS_KEY export AWS_SECRET_ACCESS_KEY=$YOUR_SECRET_KEY export AWS_DEFAULT_REGION=us-east-1 ``` ## Project Structure ``` terraform/ ├── main.tf # Main infrastructure definitions ├── variables.tf # Input variables ├── outputs.tf # Output values └── terraform.tfstate # State file (auto-generated) ``` ## Core Terraform Commands ### Initialize Terraform ```bash # Initialize the working directory and download providers terraform -chdir=terraform init # Validate configuration syntax terraform -chdir=terraform validate # Format configuration files terraform -chdir=terraform fmt ``` ### Plan and Apply Infrastructure ```bash # Preview changes without applying terraform -chdir=terraform plan # Apply infrastructure changes terraform -chdir=terraform apply # Auto-approve without prompts (use carefully) terraform -chdir=terraform apply -auto-approve ``` ### Inspect Infrastructure ```bash # List all resources in state terraform -chdir=terraform state list # Show detailed state information terraform -chdir=terraform show # Output specific values terraform -chdir=terraform output ``` ### Destroy Infrastructure ```bash # Destroy all managed infrastructure terraform -chdir=terraform destroy # Destroy specific resource terraform -chdir=terraform destroy -target=aws_s3_bucket.data_bucket ``` ## Key Configuration Patterns ### S3 Bucket for Data Storage ```hcl # main.tf resource "aws_s3_bucket" "data_lake" { bucket = "my-data-engineering-bucket-${random_id.bucket_suffix.hex}" tags = { Environment = "dev" Purpose = "data-engineering" ManagedBy = "terraform" } } resource "random_id" "bucket_suffix" { byte_length = 4 } # Enable versioning for data protection resource "aws_s3_bucket_versioning" "data_lake_versioning" { bucket = aws_s3_bucket.data_lake.id versioning_configuration { status = "Enabled" } } # Configure lifecycle rules 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 ```hcl # main.tf resource "aws_instance" "data_processor" { ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 instance_type = "t3.medium" key_name = aws_key_pair.data_eng_key.key_name vpc_security_group_ids = [aws_security_group.data_processor_sg.id] iam_instance_profile = aws_iam_instance_profile.data_processor_profile.name user_data = <<-EOF #!/bin/bash yum update -y yum install -y python3 python3-pip pip3 install pandas boto3 awscli EOF tags = { Name = "data-processor" Environment = "dev" ManagedBy = "terraform" } root_block_device { volume_size = 50 volume_type = "gp3" } } resource "aws_key_pair" "data_eng_key" { key_name = "data-engineering-key" public_key = file("~/.ssh/id_rsa.pub") } ``` ### Security Group Configuration ```hcl resource "aws_security_group" "data_processor_sg" { name = "data-processor-sg" description = "Security group for data processing EC2 instances" # SSH access ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # Restrict in production } # Allow all outbound traffic egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "data-processor-sg" } } ``` ### IAM Role for EC2 with S3 Access ```hcl 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" "s3_access_policy" { name = "s3-access-policy" role = aws_iam_role.data_processor_role.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "s3:GetObject", "s3:PutObject", "s3:ListBucket" ] Resource = [ aws_s3_bucket.data_lake.arn, "${aws_s3_bucket.data_lake.arn}/*" ] } ] }) } resource "aws_iam_instance_profile" "data_processor_profile" { name = "data-processor-profile" role = aws_iam_role.data_processor_role.name } ``` ## Variables and Outputs ### Define Variables ```hcl # 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" } variable "bucket_prefix" { description = "Prefix for S3 bucket names" type = string default = "data-engineering" } ``` ### Configure Outputs ```hcl # outputs.tf output "s3_bucket_name" { description = "Name of the created S3 bucket" value = aws_s3_bucket.data_lake.id } output "s3_bucket_arn" { description = "ARN of the S3 bucket" value = aws_s3_bucket.data_lake.arn } output "ec2_instance_id" { description = "ID of the EC2 instance" value = aws_instance.data_processor.id } output "ec2_public_ip" { description = "Public IP of the EC2 instance" value = aws_instance.data_processor.public_ip } output "ec2_private_ip" { description = "Private IP of the EC2 instance" value = aws_instance.data_processor.private_ip } ``` ## Remote State Management For team collaboration, use S3 backend for state: ```hcl # backend.tf terraform { backend "s3" { bucket = "terraform-state-bucket-name" key = "data-engineering/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-state-lock" } } ``` Create the backend resources: ```hcl resource "aws_s3_bucket" "terraform_state" { bucket = "terraform-state-bucket-name" lifecycle { prevent_destroy = true } } resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-state-lock" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID" attribute { name = "LockID" type = "S" } } ``` ## Verification Commands After applying infrastructure: ```bash # Verify S3 buckets aws s3 ls # Verify EC2 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 # Check IAM roles aws iam list-roles --query 'Roles[?contains(RoleName, `data-processor`)].RoleName' # Inspect Terraform state terraform -chdir=terraform state list cat terraform/terraform.tfstate | jq -r '.resources[] | [.type, .name] | join(",")' ``` ## Common Patterns ### Multi-Environment Setup ```hcl # environments/dev/main.tf module "data_infrastructure" { source = "../../modules/data-infra" environment = "dev" instance_type = "t3.small" bucket_prefix = "dev-data" } # environments/prod/main.tf module "data_infrastructure" { source = "../../modules/data-infra" environment = "prod" instance_type = "t3.large" bucket_prefix = "prod-data" } ``` ### Using terraform.tfvars ```hcl # terraform.tfvars aws_region = "us-west-2" environment = "staging" instance_type = "t3.medium" bucket_prefix = "staging-data-lake" ``` Apply with variables: ```bash terraform -chdir=terraform apply -var-file="terraform.tfvars" ``` ## Troubleshooting ### State Lock Issues ```bash # Force unlock if state is stuck terraform -chdir=terraform force-unlock LOCK_ID # View current state terraform -chdir=terraform show ``` ### S3 Bucket Name Conflicts If bucket name is taken: ```hcl # Use random suffix resource "random_id" "bucket_suffix" { byte_length = 8 } resource "aws_s3_bucket" "data_lake" { bucket = "${var.bucket_prefix}-${random_id.bucket_suffix.hex}" } ``` ### Import Existing Resources ```bash # Import existing S3 bucket terraform -chdir=terraform import aws_s3_bucket.data_lake existing-bucket-name # Import EC2 instance terraform -chdir=terraform import aws_instance.data_processor i-1234567890abcdef0 ``` ### Debugging Terraform ```bash # Enable detailed logging export TF_LOG=DEBUG terraform -chdir=terraform apply # Disable logging unset TF_LOG ``` ### Refresh State ```bash # Sync state with real infrastructure terraform -chdir=terraform refresh # Replace corrupted resource terraform -chdir=terraform apply -replace=aws_instance.data_processor ``` ## Best Practices 1. **Always use variables** for environment-specific values 2. **Enable S3 versioning** for data protection 3. **Use IAM roles** instead of access keys for EC2 4. **Tag all resources** for cost tracking and management 5. **Store state remotely** for team collaboration 6. **Use modules** for reusable infrastructure patterns 7. **Run `terraform plan`** before every apply 8. **Never commit** `.tfstate` files or sensitive variables to Git 9. **Use `.gitignore`** for Terraform files: ```gitignore # .gitignore .terraform/ *.tfstate *.tfstate.backup .terraform.lock.hcl terraform.tfvars *.auto.tfvars ```
GitHubで見る