Skip to content

Commit 39ee700

Browse files
author
Jaap Haitsma
committed
Add python example
1 parent a89f529 commit 39ee700

File tree

19 files changed

+822
-2
lines changed

19 files changed

+822
-2
lines changed

.eslintignore

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.projenrc.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ new TextFile(project, ".eslintignore", {
6767
'# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen"',
6868
...managedFiles,
6969
"example/",
70+
"*.md",
7071
],
7172
});
7273

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# WAF HTTP API
22

3-
43
A CDK construct that fronts an HTTP API with a CloudFront distribution and protects it with AWS WAF.
54

65
[![npm version](https://badge.fury.io/js/waf-http-api.svg)](https://badge.fury.io/js/waf-http-api)
76
[![PyPI version](https://badge.fury.io/py/waf-http-api.svg)](https://badge.fury.io/py/waf-http-api)
7+
88
## Features
99

1010
- **Enhanced Security:** Protects your HTTP API with AWS WAF rules
@@ -29,6 +29,24 @@ npm install waf-http-api
2929
pip install waf-http-api
3030
```
3131

32+
## Examples
33+
34+
Complete working examples demonstrating the usage of `waf-http-api` can be found in the [`example/`](./example/) directory:
35+
36+
- **[TypeScript Example](./example/typescript/)**: Full CDK application with Node.js 22 Lambda, comprehensive tests, and deployment scripts
37+
- **[Python Example](./example/python/)**: Complete CDK application with Python 3.12 Lambda, pytest test suite, and development tools
38+
39+
Both examples include:
40+
41+
- ✅ Complete CDK stacks using the `WafHttpApi` construct
42+
- ✅ Lambda functions with origin verification
43+
- ✅ HTTP API Gateway with multiple routes
44+
- ✅ Comprehensive test suites
45+
- ✅ Build and deployment scripts
46+
- ✅ Detailed documentation
47+
48+
These examples serve as practical references for implementing WAF-protected HTTP APIs in production environments.
49+
3250
## Usage
3351

3452
### Basic Usage

example/python/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
*.swp
2+
package-lock.json
3+
__pycache__
4+
.pytest_cache
5+
.venv
6+
*.egg-info
7+
8+
# CDK asset staging directory
9+
.cdk.staging
10+
cdk.out

example/python/Makefile

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Makefile for WAF HTTP API Python Example
2+
3+
.PHONY: help install test build deploy synth destroy clean
4+
5+
help: ## Show this help message
6+
@echo "WAF HTTP API Python Example"
7+
@echo "Available commands:"
8+
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-15s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
9+
10+
install: ## Install dependencies
11+
@echo "📦 Installing dependencies..."
12+
@source .venv/bin/activate && pip install -r requirements.txt
13+
@source .venv/bin/activate && pip install -r requirements-dev.txt
14+
15+
test: ## Run tests
16+
@echo "🧪 Running tests..."
17+
@source .venv/bin/activate && pytest -v
18+
19+
build: ## Build (synthesize CloudFormation template)
20+
@echo "🔧 Synthesizing CloudFormation template..."
21+
@source .venv/bin/activate && cdk synth
22+
23+
deploy: ## Deploy to AWS
24+
@echo "🚀 Deploying to AWS..."
25+
@source .venv/bin/activate && cdk deploy --require-approval never
26+
27+
synth: build ## Alias for build
28+
29+
destroy: ## Destroy AWS resources
30+
@echo "🗑️ Destroying AWS resources..."
31+
@source .venv/bin/activate && cdk destroy --force
32+
33+
clean: ## Clean build artifacts
34+
@echo "🧹 Cleaning build artifacts..."
35+
@rm -rf cdk.out/
36+
@rm -rf .pytest_cache/
37+
@find . -type d -name "__pycache__" -exec rm -rf {} +
38+
@find . -type f -name "*.pyc" -delete
39+
40+
setup: ## Initial setup (create venv and install dependencies)
41+
@echo "🏗️ Setting up Python environment..."
42+
@python3 -m venv .venv
43+
@source .venv/bin/activate && pip install --upgrade pip
44+
@make install
45+
@echo "✅ Setup complete! Run 'source .venv/bin/activate' to activate the virtual environment."

example/python/README.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# WAF HTTP API Python Example
2+
3+
This is a Python CDK example that demonstrates how to use the `waf-http-api` construct to create a WAF-protected HTTP API.
4+
5+
## Architecture
6+
7+
This example creates:
8+
9+
- **Lambda Function**: Python 3.12 runtime that returns a greeting with request information
10+
- **HTTP API Gateway**: RESTful API with multiple routes (`/` and `/hello`)
11+
- **WafHttpApi Construct**: Automatically creates CloudFront distribution and WAF WebACL
12+
- **Origin Verification**: Secret header mechanism to ensure requests come through CloudFront
13+
14+
## Features
15+
16+
-**Python 3.12 Lambda Runtime**: Latest Python runtime for optimal performance
17+
-**WafHttpApi Construct**: Uses the official `waf-http-api` package for simplified setup
18+
-**Comprehensive Security**: WAF protection with IP reputation and common rule sets
19+
-**Origin Verification**: CloudFront adds secret headers to verify legitimate requests
20+
-**Multiple HTTP Methods**: Supports GET and POST requests
21+
-**CORS Support**: Configured for cross-origin requests
22+
-**Detailed Logging**: Request information and verification status
23+
-**Infrastructure as Code**: Fully defined using AWS CDK Python
24+
25+
## Prerequisites
26+
27+
- Python 3.8 or later
28+
- AWS CDK CLI installed (`npm install -g aws-cdk`)
29+
- AWS credentials configured
30+
31+
## Setup
32+
33+
1. **Create and activate virtual environment**:
34+
35+
```bash
36+
python3 -m venv .venv
37+
source .venv/bin/activate # On Windows: .venv\Scripts\activate.bat
38+
```
39+
40+
2. **Install dependencies**:
41+
42+
```bash
43+
pip install -r requirements.txt
44+
pip install -r requirements-dev.txt
45+
```
46+
47+
This will install:
48+
49+
- `aws-cdk-lib`: AWS CDK core library
50+
- `constructs`: CDK constructs framework
51+
- `waf-http-api`: The WAF HTTP API construct package
52+
- `pytest`: Testing framework
53+
54+
## Usage
55+
56+
### Build and Test
57+
58+
```bash
59+
# Run tests
60+
pytest
61+
62+
# Synthesize CloudFormation template
63+
cdk synth
64+
65+
# Deploy to AWS
66+
cdk deploy
67+
68+
# Clean up resources
69+
cdk destroy
70+
```
71+
72+
### Testing the API
73+
74+
After deployment, you'll get several outputs:
75+
76+
- **CloudFrontUrl**: Use this endpoint for production traffic (recommended)
77+
- **HttpApiUrl**: Direct API Gateway URL (not recommended for production)
78+
79+
```bash
80+
# Test the API through CloudFront (recommended)
81+
curl https://d1234567890.cloudfront.net/
82+
83+
# Test the hello endpoint
84+
curl https://d1234567890.cloudfront.net/hello
85+
86+
# POST request
87+
curl -X POST https://d1234567890.cloudfront.net/hello \
88+
-H "Content-Type: application/json" \
89+
-d '{"test": "data"}'
90+
```
91+
92+
## Project Structure
93+
94+
```
95+
example/python/
96+
├── app.py # CDK app entry point
97+
├── waf_http_api_example/
98+
│ ├── __init__.py
99+
│ └── waf_http_api_example_stack.py # Main stack definition
100+
├── tests/
101+
│ ├── __init__.py
102+
│ └── test_waf_http_api_example.py # Comprehensive test suite
103+
├── requirements.txt # Runtime dependencies
104+
├── requirements-dev.txt # Development dependencies
105+
├── cdk.json # CDK configuration
106+
└── README.md # This file
107+
```
108+
109+
## Key Components
110+
111+
### Lambda Function
112+
113+
- **Runtime**: Python 3.12
114+
- **Handler**: Inline code that processes HTTP requests
115+
- **Features**: Origin verification, detailed logging, CORS headers
116+
117+
### HTTP API Gateway
118+
119+
- **Type**: HTTP API (faster and cheaper than REST API)
120+
- **Routes**: `GET /`, `GET /hello`, `POST /hello`
121+
- **Integration**: Lambda proxy integration
122+
123+
### WafHttpApi Construct
124+
125+
- **Package**: `waf_http_api` from PyPI
126+
- **Features**: Automatically creates and configures CloudFront and WAF
127+
- **Configuration**: Simple API with sensible defaults
128+
- **Extensibility**: Support for custom domains and WAF rules
129+
130+
### CloudFront Distribution (via WafHttpApi)
131+
132+
- **Caching**: Optimized for API responses
133+
- **Security**: WAF integration for DDoS and application-layer protection
134+
- **Origin**: HTTP API Gateway with custom verification headers
135+
136+
### WAF WebACL (via WafHttpApi)
137+
138+
- **Scope**: CloudFront (global)
139+
- **Rules**:
140+
- AWS Managed IP Reputation List
141+
- AWS Managed Common Rule Set
142+
- **Action**: Allow by default, block malicious traffic
143+
144+
## Security Features
145+
146+
1. **WAF Protection**: Blocks malicious requests before they reach your API
147+
2. **Origin Verification**: Secret headers ensure requests come through CloudFront
148+
3. **HTTPS Only**: All traffic redirected to HTTPS
149+
4. **IP Reputation**: Automatic blocking of known malicious IP addresses
150+
5. **Common Attack Protection**: OWASP Top 10 and common web vulnerabilities
151+
152+
## Monitoring and Observability
153+
154+
- **CloudWatch Logs**: Lambda function logs for debugging
155+
- **WAF Metrics**: Request counts, blocked requests, rule matches
156+
- **CloudFront Metrics**: Cache hit rates, origin response times
157+
- **API Gateway Metrics**: Request counts, latency, error rates
158+
159+
## Cost Optimization
160+
161+
- **HTTP API**: More cost-effective than REST API
162+
- **CloudFront**: Reduces origin load and improves performance
163+
- **Lambda**: Pay-per-request pricing with efficient Python runtime
164+
- **WAF**: Only pay for requests processed
165+
166+
## Development
167+
168+
### Running Tests
169+
170+
```bash
171+
# Run all tests
172+
pytest
173+
174+
# Run with verbose output
175+
pytest -v
176+
177+
# Run specific test
178+
pytest tests/test_waf_http_api_example.py::TestWafHttpApiExampleStack::test_lambda_function_created_with_python_312
179+
```
180+
181+
### Adding Custom WAF Rules
182+
183+
You can extend the WAF configuration by adding custom rules to the `web_acl` in the stack:
184+
185+
```python
186+
# Add rate limiting rule
187+
rate_limit_rule = wafv2.CfnWebACL.RuleProperty(
188+
name="RateLimitRule",
189+
priority=10,
190+
action=wafv2.CfnWebACL.RuleActionProperty(block={}),
191+
statement=wafv2.CfnWebACL.StatementProperty(
192+
rate_based_statement=wafv2.CfnWebACL.RateBasedStatementProperty(
193+
limit=2000,
194+
aggregate_key_type="IP"
195+
)
196+
),
197+
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
198+
cloud_watch_metrics_enabled=True,
199+
metric_name="RateLimitRule",
200+
sampled_requests_enabled=True
201+
)
202+
)
203+
```
204+
205+
## Troubleshooting
206+
207+
### Common Issues
208+
209+
1. **403 Forbidden**: Check that requests are going through CloudFront, not directly to API Gateway
210+
2. **Origin Verification Failed**: Ensure the secret header is properly configured
211+
3. **WAF Blocking Legitimate Traffic**: Review WAF logs and adjust rules if needed
212+
213+
### Debugging
214+
215+
1. **Check Lambda Logs**: View CloudWatch logs for the Lambda function
216+
2. **WAF Logs**: Enable WAF logging to S3 for detailed analysis
217+
3. **CloudFront Logs**: Enable access logs for request analysis
218+
219+
## License
220+
221+
This example is provided under the same license as the main waf-http-api project.

example/python/app.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
6+
from waf_http_api_example.waf_http_api_example_stack import WafHttpApiExampleStack
7+
8+
9+
app = cdk.App()
10+
WafHttpApiExampleStack(app, "WafHttpApiExampleStack",
11+
# If you don't specify 'env', this stack will be environment-agnostic.
12+
# Account/Region-dependent features and context lookups will not work,
13+
# but a single synthesized template can be deployed anywhere.
14+
15+
# Uncomment the next line to specialize this stack for the AWS Account
16+
# and Region that are implied by the current CLI configuration.
17+
18+
env=cdk.Environment(
19+
account=os.getenv('CDK_DEFAULT_ACCOUNT'),
20+
region=os.getenv('CDK_DEFAULT_REGION')
21+
),
22+
23+
# Uncomment the next line if you know exactly what Account and Region you
24+
# want to deploy the stack to.
25+
26+
#env=cdk.Environment(account='123456789012', region='us-east-1'),
27+
28+
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
29+
)
30+
31+
app.synth()

example/python/cdk.context.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"acknowledged-issue-numbers": [34892, 34892]
3+
}

0 commit comments

Comments
 (0)