Skip to content

Commit 5c94a22

Browse files
committed
Add AWS App Runner deployment configuration
1 parent a3580ea commit 5c94a22

10 files changed

Lines changed: 764 additions & 15 deletions

File tree

β€Ž.env.productionβ€Ž

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Production Environment Configuration for AWS App Runner
2+
# These environment variables should be configured in AWS App Runner Console
3+
4+
# Flask Configuration
5+
FLASK_ENV=production
6+
FLASK_DEBUG=0
7+
FLASK_APP=wsgi:application
8+
9+
# Security - Production API Keys
10+
# Replace with your actual production API keys
11+
API_KEYS=prod_client_basic_key:ProductionClientBasic:basic,prod_client_premium_key:ProductionClientPremium:premium
12+
MASTER_API_KEY=your_secure_production_master_key_here
13+
14+
# Data Sources Configuration
15+
# Paths adjusted for App Runner deployment
16+
EDGAR_XLSX_PATH=/opt/app/reference/EDGAR_emiss_on_UCDB_2024.xlsx
17+
ISO_XLSX_PATH=/opt/app/reference/list_iso.xlsx
18+
19+
# EEA API Configuration (default is fine)
20+
EEA_BASE_URL=https://eeadmz1-downloads-api-appservice.azurewebsites.net
21+
22+
# Rate Limiting
23+
RATELIMIT_STORAGE_URL=memory://
24+
25+
# Logging Configuration
26+
LOG_LEVEL=INFO
27+
LOG_FILE=/opt/app/logs/permit_api.log
28+
29+
# Security Headers
30+
SECURITY_HEADERS_ENABLED=true
31+
32+
# CORS Configuration - Update with your domain
33+
CORS_ORIGINS=*
34+
CORS_METHODS=GET,POST,PUT,DELETE,OPTIONS
35+
CORS_HEADERS=Content-Type,Authorization,X-API-Key
36+
37+
# Production Settings
38+
TESTING=false
39+
SAMPLE_DATA_ENABLED=true
40+
41+
# AWS Specific
42+
PORT=8000

β€Ž.github/workflows/deploy.ymlβ€Ž

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Deploy to AWS App Runner
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
AWS_REGION: us-east-1
11+
APP_RUNNER_SERVICE: permit-api-prod
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Python 3.11
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install -r requirements.txt
29+
30+
- name: Run tests
31+
run: |
32+
python -m pytest tests/ -v --tb=short -k "not test_global"
33+
34+
- name: Lint code
35+
run: |
36+
pip install flake8
37+
flake8 api/ --count --select=E9,F63,F7,F82 --show-source --statistics
38+
39+
deploy-staging:
40+
needs: test
41+
runs-on: ubuntu-latest
42+
if: github.event_name == 'pull_request'
43+
44+
steps:
45+
- name: Configure AWS credentials
46+
uses: aws-actions/configure-aws-credentials@v4
47+
with:
48+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
49+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
50+
aws-region: ${{ env.AWS_REGION }}
51+
52+
- name: Deploy to staging
53+
run: |
54+
echo "Would deploy to staging environment"
55+
# Add actual staging deployment commands here
56+
57+
deploy-production:
58+
needs: test
59+
runs-on: ubuntu-latest
60+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
61+
62+
steps:
63+
- name: Configure AWS credentials
64+
uses: aws-actions/configure-aws-credentials@v4
65+
with:
66+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
67+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
68+
aws-region: ${{ env.AWS_REGION }}
69+
70+
- name: Trigger App Runner deployment
71+
run: |
72+
echo "App Runner will automatically deploy from main branch"
73+
# App Runner handles deployment automatically when connected to GitHub
74+
75+
- name: Wait for deployment
76+
run: |
77+
echo "Waiting for App Runner deployment to complete..."
78+
aws apprunner describe-service --service-arn ${{ secrets.APP_RUNNER_SERVICE_ARN }} --query 'Service.Status'
79+
80+
- name: Test production deployment
81+
run: |
82+
echo "Testing production endpoints..."
83+
# Add production health checks here
84+
# curl -f https://your-production-url.awsapprunner.com/health
85+
86+
- name: Notify deployment status
87+
if: always()
88+
run: |
89+
echo "Deployment completed with status: ${{ job.status }}"
90+
# Add Slack/email notifications here if needed

β€ŽAWS_DEPLOYMENT_GUIDE.mdβ€Ž

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# AWS App Runner Deployment Guide
2+
3+
## πŸš€ Quick Deployment Steps
4+
5+
### Prerequisites
6+
- AWS Account with appropriate permissions
7+
- GitHub repository with your code
8+
- AWS CLI installed (optional, for advanced configuration)
9+
10+
### Step 1: Prepare Your Repository
11+
12+
Ensure these files are in your repository root:
13+
- βœ… `apprunner.yaml` - App Runner configuration
14+
- βœ… `requirements.txt` - Python dependencies
15+
- βœ… `run_server.py` - Application startup script
16+
- βœ… `wsgi.py` - WSGI entry point
17+
- βœ… `.env.production` - Production environment template
18+
19+
### Step 2: Deploy via AWS Console
20+
21+
1. **Open AWS App Runner Console**
22+
- Go to: https://console.aws.amazon.com/apprunner/
23+
- Click "Create an App Runner service"
24+
25+
2. **Configure Source**
26+
- Source: "Source code repository"
27+
- Repository type: GitHub
28+
- Connect to your GitHub account
29+
- Select repository: `your-username/project-permit-api`
30+
- Branch: `main`
31+
- Deployment trigger: "Automatic" (deploys on push)
32+
33+
3. **Configure Build**
34+
- Configuration file: "Use configuration file"
35+
- Configuration file: `apprunner.yaml`
36+
37+
4. **Configure Service**
38+
- Service name: `permit-api-prod`
39+
- Virtual CPU: `1 vCPU`
40+
- Virtual memory: `2 GB`
41+
- Environment variables (click "Add environment variable"):
42+
43+
**Required Variables:**
44+
```
45+
FLASK_ENV=production
46+
FLASK_DEBUG=0
47+
API_KEYS=your_prod_basic_key:ProductionBasic:basic,your_prod_premium_key:ProductionPremium:premium
48+
MASTER_API_KEY=your_secure_master_key_here
49+
LOG_LEVEL=INFO
50+
CORS_ORIGINS=*
51+
```
52+
53+
5. **Configure Auto Scaling**
54+
- Minimum size: 1
55+
- Maximum size: 3
56+
- Max concurrency: 100 per instance
57+
58+
6. **Configure Health Check**
59+
- Health check path: `/health`
60+
- Health check interval: 20 seconds
61+
- Health check timeout: 5 seconds
62+
- Healthy threshold: 1
63+
- Unhealthy threshold: 5
64+
65+
7. **Configure Security (Optional)**
66+
- Create VPC connector if needed for database access
67+
- Configure IAM roles if accessing other AWS services
68+
69+
8. **Review and Create**
70+
- Review all settings
71+
- Click "Create & deploy"
72+
73+
### Step 3: Monitor Deployment
74+
75+
1. **Check Build Status**
76+
- Monitor the "Activity" tab in App Runner console
77+
- Build typically takes 3-5 minutes
78+
79+
2. **Test Your API**
80+
- Once deployed, you'll get a URL like: `https://abc123.us-east-1.awsapprunner.com`
81+
- Test health: `curl https://your-url.awsapprunner.com/health`
82+
- Test with API key:
83+
```bash
84+
curl -H "Authorization: Bearer your_prod_basic_key" \
85+
"https://your-url.awsapprunner.com/global/emissions?limit=5"
86+
```
87+
88+
## πŸ”§ Advanced Configuration
89+
90+
### Custom Domain Setup
91+
92+
1. **In App Runner Console:**
93+
- Go to your service β†’ "Custom domains" tab
94+
- Click "Link domain"
95+
- Enter your domain (e.g., `api.yourcompany.com`)
96+
- Follow DNS validation steps
97+
98+
2. **DNS Configuration:**
99+
- Add CNAME record pointing to App Runner URL
100+
- Certificate will be auto-provisioned via AWS Certificate Manager
101+
102+
### Environment-Specific Configurations
103+
104+
**Staging Environment:**
105+
```
106+
Service name: permit-api-staging
107+
Environment: FLASK_ENV=staging
108+
Resources: 0.5 vCPU, 1 GB RAM
109+
Auto-scaling: Min 1, Max 2
110+
```
111+
112+
**Production Environment:**
113+
```
114+
Service name: permit-api-prod
115+
Environment: FLASK_ENV=production
116+
Resources: 1 vCPU, 2 GB RAM
117+
Auto-scaling: Min 1, Max 5
118+
```
119+
120+
### Monitoring & Logging
121+
122+
**CloudWatch Integration:**
123+
- App Runner automatically sends logs to CloudWatch
124+
- Metrics available: CPU, Memory, Request count, Response time
125+
- Set up alarms for high error rates or resource usage
126+
127+
**Custom Monitoring:**
128+
```python
129+
# Add to your Flask app
130+
import boto3
131+
cloudwatch = boto3.client('cloudwatch')
132+
133+
# Custom metrics
134+
cloudwatch.put_metric_data(
135+
Namespace='PermitAPI',
136+
MetricData=[{
137+
'MetricName': 'APIRequests',
138+
'Value': 1,
139+
'Unit': 'Count'
140+
}]
141+
)
142+
```
143+
144+
## πŸ”’ Security Best Practices
145+
146+
### Environment Variables
147+
- **Never commit production keys to Git**
148+
- Use AWS Systems Manager Parameter Store for sensitive values
149+
- Rotate API keys regularly
150+
151+
### Network Security
152+
- Use VPC connector for database connections
153+
- Configure WAF if needed for additional protection
154+
- Enable AWS Shield for DDoS protection
155+
156+
### Access Control
157+
```python
158+
# Update CORS for production
159+
CORS_ORIGINS=https://yourapp.com,https://api.yourcompany.com
160+
```
161+
162+
## πŸ“Š Cost Optimization
163+
164+
### Right-Sizing Resources
165+
- **Development**: 0.25 vCPU, 0.5 GB RAM (~$5/month)
166+
- **Production**: 1 vCPU, 2 GB RAM (~$25/month)
167+
- **Enterprise**: 2 vCPU, 4 GB RAM (~$50/month)
168+
169+
### Auto-Scaling Configuration
170+
```yaml
171+
# Optimize for cost
172+
Min instances: 0 (for dev/staging)
173+
Max instances: 3 (for production)
174+
Max concurrency: 80 (balance latency vs cost)
175+
```
176+
177+
## 🚨 Troubleshooting
178+
179+
### Common Issues
180+
181+
**Build Failures:**
182+
- Check `requirements.txt` for version conflicts
183+
- Verify Python 3.11 compatibility
184+
- Check build logs in App Runner console
185+
186+
**Health Check Failures:**
187+
- Ensure `/health` endpoint returns 200 status
188+
- Check if app is binding to `0.0.0.0:PORT`
189+
- Verify PORT environment variable is used
190+
191+
**API Key Issues:**
192+
- Check environment variables are set correctly
193+
- Test with demo keys first
194+
- Verify API key format in requests
195+
196+
### Debug Commands
197+
198+
```bash
199+
# Local testing
200+
python run_server.py
201+
202+
# Test API endpoints
203+
curl -H "Authorization: Bearer demo_key_basic_2025" \
204+
"http://localhost:5000/global/emissions?limit=1"
205+
206+
# Check logs
207+
aws logs tail /aws/apprunner/permit-api-prod --follow
208+
```
209+
210+
## πŸ“ Post-Deployment Checklist
211+
212+
- βœ… Health check returning 200
213+
- βœ… API key authentication working
214+
- βœ… Rate limiting active
215+
- βœ… CORS configured correctly
216+
- βœ… Monitoring enabled
217+
- βœ… Custom domain configured (if needed)
218+
- βœ… SSL certificate active
219+
- βœ… Production API keys rotated
220+
- βœ… Documentation updated with new URL
221+
222+
## 🎯 Next Steps
223+
224+
1. **Set up monitoring dashboards**
225+
2. **Configure automated backups** (if using databases)
226+
3. **Implement CI/CD pipeline** with GitHub Actions
227+
4. **Set up staging environment**
228+
5. **Configure alerts** for errors and performance issues
229+
230+
---
231+
232+
**Your API will be available at:** `https://[unique-id].us-east-1.awsapprunner.com`
233+
234+
**Documentation:** Update your API documentation with the production URL and new authentication requirements.

0 commit comments

Comments
Β (0)