Goal
Quickly spin up and tear down test instances for:
- Django upgrades (1.11 → 2.2 → 3.2 → 4.2 → 5.1)
- Ansible playbook validation
- Feature development with realistic data
Approach
Two complementary paths:
- AWS Cloud - EC2 + optional RDS clone (realistic, ephemeral, ~$0.35-0.65/day)
- Local Development - Docker + database dumps (free, laptop-friendly)
Existing Infrastructure (Already in Repo)
| Component |
Status |
Notes |
setup-test.yml |
✅ Ready |
Playbook exists, uses regluit_prod role |
group_vars/test/vars.yml |
✅ Ready |
Configured for Let's Encrypt staging |
group_vars/test/vault.yml |
✅ Exists |
Copy of production vault |
hosts [test] |
⚠️ Commented |
Needs EC2 IP when instance created |
Path A: AWS Cloud Test Environment
Step 1: Create EC2 Instance
# Set environment
export ANSIBLE_VAULT_PASSWORD_FILE=/Volumes/ryvault1/ebookfoundation/vault_pass.txt
# Create instance (Ubuntu 22.04, t3.medium)
INSTANCE_ID=$(aws ec2 run-instances \
--image-id ami-0c7217cdde317cfec \
--instance-type t3.medium \
--key-name production \
--security-group-ids sg-0a1b2c3d4e5f \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=regluit-test}]' \
--query 'Instances[0].InstanceId' --output text)
# Wait and get IP
aws ec2 wait instance-running --instance-ids $INSTANCE_ID
PUBLIC_IP=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID \
--query 'Reservations[0].Instances[0].PublicIpAddress' --output text)
echo "Public IP: $PUBLIC_IP"
Step 2: Update Hosts File
# Edit hosts - uncomment [test] and add IP
sed -i '' "s/#regluit-test ansible_host=<PUBLIC_IP>/regluit-test ansible_host=$PUBLIC_IP/" hosts
Step 3: Run Ansible Playbook
cd /Users/raymondyee/C/src/Gluejar/regluit-provisioning
ansible-playbook -i hosts setup-test.yml -e git_branch=production
Step 4: (Optional) Clone Production RDS
For isolated database testing:
# Create snapshot
aws rds create-db-snapshot \
--db-instance-identifier production-2024 \
--db-snapshot-identifier regluit-test-$(date +%Y%m%d)
# Restore to smaller instance
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier regluit-test \
--db-snapshot-identifier regluit-test-YYYYMMDD \
--db-instance-class db.t3.small
# Update vault with new endpoint
ansible-vault edit group_vars/test/vault.yml
# Change: vault_mysql_db_host: "regluit-test.xxx.us-east-1.rds.amazonaws.com"
Step 5: Tear Down When Done
# Terminate EC2
aws ec2 terminate-instances --instance-ids $INSTANCE_ID
# Delete test RDS (if created)
aws rds delete-db-instance --db-instance-identifier regluit-test --skip-final-snapshot
# Re-comment hosts file
sed -i '' "s/^regluit-test ansible_host=.*/#regluit-test ansible_host=<PUBLIC_IP>/" hosts
Path B: Local Development (Laptop)
Step 1: Start Local Services (Docker)
Create docker/docker-compose.yml:
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: regluit
MYSQL_USER: regluit
MYSQL_PASSWORD: devpass
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
mysql_data:
docker compose -f docker/docker-compose.yml up -d
Step 2: Dump Production Database
# Via SSH to production (uses existing dump.sh)
ssh ubuntu@unglue.it 'cd ~ && ./dump.sh'
scp ubuntu@unglue.it:~/unglue.it.sql.gz ./db_dumps/
# OR via direct SSH tunnel + mysqldump
ssh -L 3307:production-2024.cboagmr25pjs.us-east-1.rds.amazonaws.com:3306 ubuntu@unglue.it -N &
mysqldump -h 127.0.0.1 -P 3307 -u $DB_USER -p$DB_PASS unglueit \
--single-transaction --no-tablespaces | gzip > db_dumps/unglueit.sql.gz
Step 3: Load Into Local MySQL
gunzip -c db_dumps/unglueit.sql.gz | docker exec -i regluit-mysql mysql -u root -prootpass regluit
Step 4: Run Django Locally
cd /path/to/regluit
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# Create local settings (point to Docker MySQL/Redis)
export DJANGO_SETTINGS_MODULE=regluit.settings.local
python manage.py runserver
Cost Breakdown (Ephemeral Usage)
| Resource |
Hourly |
8-hour session |
Notes |
| EC2 t3.medium |
$0.042 |
$0.34 |
2 vCPU, 4GB |
| RDS t3.small (optional) |
$0.034 |
$0.27 |
Only if cloned |
| Total (EC2 only) |
|
~$0.35/day |
Uses prod RDS |
| Total (EC2 + RDS) |
|
~$0.65/day |
Isolated DB |
| Local Docker |
$0 |
$0 |
Laptop only |
Files to Create
| File |
Purpose |
scripts/spin-up-test.sh |
Automate EC2 creation + hosts update |
scripts/tear-down-test.sh |
Automate cleanup |
scripts/dump-production-db.sh |
Create database dumps |
docker/docker-compose.yml |
Local MySQL + Redis |
regluit/settings/local.py |
Local development settings |
Verification Checklist
Django Upgrade Testing Workflow
Once test environment is running:
ssh ubuntu@<test-ip>
cd /opt/regluit && source venv/bin/activate
# Test current state
python manage.py check --deploy
python manage.py test
# Upgrade Django incrementally
pip install Django==2.2
python manage.py check # Fix deprecation warnings
python manage.py migrate --check
# Repeat for 3.2, 4.2, 5.1
Related Issues
🤖 Generated with Claude Code
Goal
Quickly spin up and tear down test instances for:
Approach
Two complementary paths:
Existing Infrastructure (Already in Repo)
setup-test.ymlregluit_prodrolegroup_vars/test/vars.ymlgroup_vars/test/vault.ymlhosts [test]Path A: AWS Cloud Test Environment
Step 1: Create EC2 Instance
Step 2: Update Hosts File
Step 3: Run Ansible Playbook
cd /Users/raymondyee/C/src/Gluejar/regluit-provisioning ansible-playbook -i hosts setup-test.yml -e git_branch=productionStep 4: (Optional) Clone Production RDS
For isolated database testing:
Step 5: Tear Down When Done
Path B: Local Development (Laptop)
Step 1: Start Local Services (Docker)
Create
docker/docker-compose.yml:Step 2: Dump Production Database
Step 3: Load Into Local MySQL
Step 4: Run Django Locally
Cost Breakdown (Ephemeral Usage)
Files to Create
scripts/spin-up-test.shscripts/tear-down-test.shscripts/dump-production-db.shdocker/docker-compose.ymlregluit/settings/local.pyVerification Checklist
manage.py checkpassesmanage.py dbshell)systemctl status celery)Django Upgrade Testing Workflow
Once test environment is running:
Related Issues
🤖 Generated with Claude Code