Meta Description: Learn how to build a cost-effective development environment using GitHub Actions and AWS EC2 Spot Instances for only $3-4/month. Achieve 80% cost reduction with automated infrastructure control and detailed implementation guide.
Introduction
Learn how to build a cost-effective development environment using GitHub Actions and AWS EC2 Spot Instances for just $3-4/month, achieving 80% cost reduction.
- Reading time: approximately 6 minutes
- Tech stack: GitHub Actions, AWS EC2, Spot Instance
- Cost reduction: 80% (from $15-20/month to $3-4/month)
Target Audience
- Those with basic knowledge of AWS EC2 and GitHub Actions
- Those interested in cloud development environment cost optimization
Technical Background and Solution
Traditional development environments run EC2 24/7, causing excessive costs for actual usage time. AWS EC2 Spot Instances offer up to 90% cost reduction but may be terminated unexpectedly. By leveraging GitHub Actions for complete automation, we can use this characteristic for temporary development environments.
Operation Challenges
- Fixed costs: t3.micro costs $15-20/month even for minimal use
- Manual operations: Tedious AWS Console operations
- Environment recovery: Complex setup after Spot Instance interruptions
System Architecture and Key Features
.github/workflows/ec2-control.yml # Main workflow
user-data.sh # EC2 initialization script
AWS Infrastructure
├── EC2 Spot Instance (t3.micro)
├── EBS Volume (encrypted)
└── Security Group
Key Features
- One-click operation: GitHub Actions UI for EC2 control
- Data persistence: EBS volumes retain data across instances
- Complete automation: Environment setup to VPN configuration
Implementation Steps
Prerequisites
1. AWS Environment Setup
Create required AWS resources:
# Create VPC with "main" tag
VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query 'Vpc.VpcId' --output text)
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=main
# Create public subnet with "Public" tag
SUBNET_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.1.0/24 --query 'Subnet.SubnetId' --output text)
aws ec2 create-tags --resources $SUBNET_ID --tags Key=Name,Value=Public
# Create security group
SG_ID=$(aws ec2 create-security-group --group-name claude-code-smartphone-sg --description "Claude Code dev env" --vpc-id $VPC_ID --query 'GroupId' --output text)
aws ec2 create-tags --resources $SG_ID --tags Key=Name,Value=claude-code-smartphone-sg
# Setup OIDC Provider (for GitHub Actions)
aws iam create-open-id-connect-provider --url https://token.actions.githubusercontent.com --thumbprint-list YOUR_THUMBPRINT --client-id-list sts.amazonaws.com
2. GitHub Secrets Setup
AWS_ROLE_ARN: arn:aws:iam::YOUR_ACCOUNT_ID:role/GitHubActionsEC2Role
GIT_TOKEN: ghp_YOUR_GITHUB_TOKEN
TAILSCALE_AUTH_KEY: tskey-auth-YOUR_KEY
GIT_USERNAME: your-github-username
GIT_EMAIL: your-email@example.com
GitHub Actions Workflow
Basic workflow configuration:
name: EC2 Instance Control
on:
workflow_dispatch:
inputs:
action:
description: 'EC2 Action'
required: true
default: 'status'
type: choice
options: [status, start, stop]
env:
AWS_REGION: ap-northeast-1
INSTANCE_NAME: claude-code-smartphone-server
INSTANCE_TYPE: t3.micro
SPOT_PRICE_MAX: "0.005"
Stop/Start/Status Implementation
Core control logic:
# Status check
get_instance_status() {
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=$INSTANCE_NAME" \
--query 'Reservations[0].Instances[0].State.Name' \
--output text
}
# Create Spot Instance
create_spot_instance() {
# Auto-detect VPC/Subnet
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=main" --query 'Vpcs[0].VpcId' --output text)
SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=Public" --query 'Subnets[0].SubnetId' --output text)
# Get latest Ubuntu AMI
AMI_ID=$(aws ec2 describe-images --owners 099720109477 \
--filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" \
--query 'Images | sort_by(@, &CreationDate) | [-1].ImageId' --output text)
# Request Spot Instance
aws ec2 request-spot-instances \
--spot-price "$SPOT_PRICE_MAX" \
--instance-count 1 \
--type "one-time" \
--launch-specification "{
\"ImageId\": \"$AMI_ID\",
\"InstanceType\": \"$INSTANCE_TYPE\",
\"UserData\": \"$(base64 -i user-data.sh)\"}"
}
Data Persistence Configuration
EBS volume configuration for data retention:
"BlockDeviceMappings": [{
"DeviceName": "/dev/sda1",
"Ebs": {
"VolumeSize": 20,
"VolumeType": "gp3",
"DeleteOnTermination": false, // Important: Retain on instance deletion
"Encrypted": true
}
}]
Automated Environment Setup (user-data.sh)
Automatic setup at instance startup:
#!/bin/bash
set -euo pipefail
# System update
sudo apt-get update && sudo apt-get upgrade -y
# Git configuration
git config --global user.name "$git_username"
git config --global user.email "$git_email"
echo "https://$git_username:$github_token@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
git config --global credential.helper store
# Tailscale VPN
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --authkey="$tailscale_auth_key" --ssh
# Development tools
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker ubuntu
curl -fsSL https://claude.ai/install.sh | sh
Cost Reduction Results and Operational Impact
After 3 months of operation:
Cost Comparison
# Previous (on-demand 24/7)
t3.micro: $15/month + EBS: $2/month = ~$17-20/month
# After (Spot Instance + 4 hours/day)
Spot: $0.4/month + EBS: $2/month + Transfer: $1/month = ~$3-4/month
Reduction rate: Achieved 80% cost reduction
Operational Efficiency Improvement
- Startup time: 5-10 minutes → 2-3 minutes
- Operations: 10+ clicks → 1 click
- VPN setup: Manual → Automatic
Summary
By combining GitHub Actions with EC2 Spot Instances, we achieved a flexible development environment at 1/5 the cost of traditional approaches.
Success Points
- Complete automation: Environment setup to VPN configuration
- Cost optimization: Spot Instance characteristics match development environment needs
- Data protection: EBS volumes persist data after instance termination
If you’re struggling with cloud development environment costs, consider this approach.
References
- AWS EC2 Spot Instances
- GitHub Actions Documentation
- Tailscale SSH Documentation
- Using EC2 Development Environment from Smartphone with Claude Code