README
¶
LocalStack Integration for Prism
This directory contains LocalStack configuration for offline AWS testing.
Overview
LocalStack allows Prism developers to:
- Develop offline without AWS credentials
- Test faster with no AWS API latency (tests run in ~2-3 minutes vs 10-15 minutes)
- Save costs with no real AWS resources
- Test safely with no risk of affecting production
Quick Start
Prerequisites
- Docker Desktop or Docker Engine
- Docker Compose v2.0+
- AWS CLI v2 (for testing)
- jq (for initialization scripts)
Starting LocalStack
# From project root
cd test/localstack
docker-compose up -d
# Wait for services to be ready (initialization scripts run automatically)
docker-compose logs -f localstack
# Verify LocalStack is ready
docker-compose exec localstack awslocal ec2 describe-instances
Running Tests with LocalStack
# Set environment variable to use LocalStack
export PRISM_USE_LOCALSTACK=true
# Run integration tests (they will automatically use LocalStack)
go test -tags integration ./test/integration/... -v
# Run specific test suites
go test -tags integration ./test/integration/phase1_workflows/... -v
go test -tags integration ./test/integration/chaos/... -v
Stopping LocalStack
cd test/localstack
docker-compose down
# Clean up all data (for fresh start)
docker-compose down -v
Architecture
Services
LocalStack provides mock implementations of:
- EC2 - Instance launching, management, AMIs, security groups, VPCs
- EFS - File system creation, mount targets
- S3 - Backup storage
- SSM - Parameter Store for AMI discovery
- IAM - Roles and policies (basic support)
- STS - Temporary credentials
Initialization
When LocalStack starts, it runs initialization scripts in order:
- 01-seed-ec2.sh - Creates VPC, subnets, security groups, AMIs, key pairs
- 02-seed-efs.sh - Creates EFS file systems and mount targets
- 03-seed-ssm.sh - Populates SSM Parameter Store with AMI paths
These scripts create a /tmp/prism-localstack-config.json file with resource IDs that tests can use.
Test AMIs
LocalStack is seeded with mock AMIs for:
- Ubuntu 22.04 LTS (x86_64 & ARM64)
- Rocky Linux 9 (x86_64 & ARM64)
- Amazon Linux 2023 (x86_64 & ARM64)
- Debian 12 (x86_64 & ARM64)
Environment Detection
Prism automatically detects LocalStack mode through:
- Environment Variable:
PRISM_USE_LOCALSTACK=true - Endpoint Override: Automatically sets AWS endpoints to
http://localhost:4566 - Mock Credentials: Uses
test/testfor access keys
The pkg/aws/localstack package handles environment detection and configuration.
Configuration
Test Configuration
// pkg/aws/localstack/config.go
const (
LocalStackEndpoint = "http://localhost:4566"
LocalStackRegion = "us-west-2"
LocalStackAccessKey = "test"
LocalStackSecretKey = "test"
)
// Automatic detection
if IsLocalStackEnabled() {
// Use LocalStack endpoints
} else {
// Use real AWS
}
Docker Compose Configuration
Key settings in docker-compose.yml:
environment:
- SERVICES=ec2,efs,s3,ssm,iam,sts # Services to enable
- DEBUG=1 # Verbose logging
- PERSISTENCE=0 # Fresh state each run
- EC2_BACKEND=mock # Fast mock backend
CI/CD Integration
GitHub Actions Workflow
LocalStack tests run in CI with:
# .github/workflows/localstack-tests.yml
- name: Start LocalStack
run: |
cd test/localstack
docker-compose up -d
docker-compose logs -f &
- name: Wait for LocalStack
run: |
timeout 60 bash -c 'until curl -f http://localhost:4566/_localstack/health; do sleep 2; done'
- name: Run LocalStack tests
env:
PRISM_USE_LOCALSTACK: true
run: |
go test -tags integration ./test/integration/... -v -timeout 15m
Benefits in CI
- Faster builds: Tests complete in ~3-5 minutes vs 15-20 minutes with real AWS
- No AWS costs: No charges for test runs
- Parallel execution: Multiple CI jobs can run simultaneously without conflicts
- No credentials: No need to manage AWS credentials in CI
Development Workflow
Typical Developer Workflow
# 1. Start LocalStack (once per development session)
cd test/localstack && docker-compose up -d
# 2. Develop features
vim pkg/aws/manager.go
# 3. Run tests frequently (fast with LocalStack)
PRISM_USE_LOCALSTACK=true go test -tags integration ./test/integration/... -v
# 4. Debug issues
docker-compose logs -f localstack
# 5. Clean up when done
docker-compose down
Debugging LocalStack
# View LocalStack logs
docker-compose logs -f localstack
# Check service health
curl http://localhost:4566/_localstack/health
# List EC2 instances
docker-compose exec localstack awslocal ec2 describe-instances
# List EFS file systems
docker-compose exec localstack awslocal efs describe-file-systems
# List SSM parameters
docker-compose exec localstack awslocal ssm describe-parameters
# Inspect resource configuration
cat /tmp/prism-localstack-config.json
Common Issues
Problem: LocalStack won't start
# Check Docker is running
docker ps
# Check port 4566 is available
lsof -i :4566
# View logs for errors
docker-compose logs localstack
Problem: Tests can't connect to LocalStack
# Verify LocalStack is healthy
curl http://localhost:4566/_localstack/health
# Check environment variable is set
echo $PRISM_USE_LOCALSTACK
# Check AWS endpoint configuration
aws --endpoint-url=http://localhost:4566 ec2 describe-instances
Problem: AMIs not found in tests
# Verify SSM parameters exist
docker-compose exec localstack awslocal ssm describe-parameters
# Check initialization logs
docker-compose logs localstack | grep "Seeding"
# Re-run initialization scripts
docker-compose restart localstack
Test Coverage
Supported Test Scenarios
✅ Fully Supported:
- Instance launching (all templates)
- Instance lifecycle (start, stop, terminate)
- EFS volume creation and attachment
- Security groups and networking
- Template validation
- AMI discovery via SSM
⚠️ Partially Supported:
- EBS volumes (basic support, limited snapshot functionality)
- IAM roles (basic support)
- Hibernation (mocked, not fully realistic)
❌ Not Supported:
- GPU instance testing (LocalStack doesn't emulate GPU hardware)
- Real network latency simulation
- Spot instances (requires real AWS pricing)
- Multi-region replication (LocalStack is single-region)
Test Migration Strategy
Tests are designed to work with both LocalStack and real AWS:
func TestInstanceLaunch(t *testing.T) {
// Works with both LocalStack and real AWS
ctx := integration.NewTestContext(t)
instance, err := ctx.LaunchInstance("ubuntu-22-04", "test-instance", "S")
require.NoError(t, err)
require.NotNil(t, instance)
}
The integration.NewTestContext() automatically detects LocalStack mode and configures endpoints accordingly.
Performance Comparison
Test Suite Execution Time
| Test Suite | Real AWS | LocalStack | Speedup |
|---|---|---|---|
| Basic Templates | 10 min | 2 min | 5x |
| Instance Lifecycle | 15 min | 3 min | 5x |
| Storage Operations | 8 min | 1.5 min | 5x |
| Chaos Tests | 20 min | 4 min | 5x |
| Full Suite | 45-60 min | 8-12 min | ~5x |
Developer Feedback Loop
- Real AWS: Write code → Wait 2-3 min → See results
- LocalStack: Write code → Wait 20-30 sec → See results
- 10x faster iteration during development
Cost Savings
Real AWS Testing Costs (Monthly)
Assuming 20 working days, 10 test runs per day:
- EC2 instances: ~$50-100/month
- EFS storage: ~$20-30/month
- Data transfer: ~$10-20/month
- Total: ~$80-150/month per developer
LocalStack Costs
- $0/month for individual developers
- LocalStack Pro (optional): $50/month for advanced features
- Savings: ~$80-150/month per developer
For a team of 5 developers: $400-750/month savings
Advanced Configuration
Custom Initialization
Add custom seed data by creating additional scripts:
# test/localstack/init/04-custom-data.sh
#!/bin/bash
aws_local() {
aws --endpoint-url=http://localhost:4566 "$@"
}
# Add custom test data
aws_local s3 mb s3://my-test-bucket
aws_local s3 cp test-data.json s3://my-test-bucket/
Scripts run in alphabetical order on LocalStack startup.
Environment Variables
Additional configuration options:
# Use specific LocalStack version
export LOCALSTACK_VERSION=2.3.0
# Enable specific services only
export SERVICES=ec2,efs
# Enable persistence across restarts
export PERSISTENCE=1
# Custom endpoint (for remote LocalStack)
export LOCALSTACK_ENDPOINT=http://remote-localstack:4566
Integration with IDE
VS Code (.vscode/launch.json):
{
"version": "0.2.0",
"configurations": [
{
"name": "Test with LocalStack",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}/test/integration",
"env": {
"PRISM_USE_LOCALSTACK": "true"
},
"args": ["-tags=integration", "-v"]
}
]
}
GoLand:
- Edit Run Configuration
- Add Environment Variables:
PRISM_USE_LOCALSTACK=true - Run tests normally
Troubleshooting
Reset Everything
# Stop and remove all LocalStack data
cd test/localstack
docker-compose down -v
# Remove cached configuration
rm -f /tmp/prism-localstack-config.json
rm -rf /tmp/localstack
# Start fresh
docker-compose up -d
View LocalStack Logs
# Follow logs in real-time
docker-compose logs -f localstack
# Search for errors
docker-compose logs localstack | grep ERROR
# Check initialization
docker-compose logs localstack | grep "Seeding"
Test Specific Service
# Test EC2
awslocal ec2 describe-instances --endpoint-url=http://localhost:4566
# Test EFS
awslocal efs describe-file-systems --endpoint-url=http://localhost:4566
# Test SSM
awslocal ssm get-parameter --name "/aws/service/canonical/ubuntu/server/22.04/stable/current/amd64/hvm/ebs-gp2/ami-id" --endpoint-url=http://localhost:4566
Resources
Support
For LocalStack-related issues:
- Check this README first
- Review LocalStack logs:
docker-compose logs localstack - Consult LocalStack docs
- Open issue with Prism team if integration-specific