# Step-by-Step Instructions to Deploy FastAPI on AWS Lambda with ALB
## Step 1: Prepare FastAPI App
1. **Install Dependencies:**
```bash
pip install fastapi uvicorn confluent_kafka protobuf mangum
pip freeze > requirements.txt
```
2. **Create FastAPI App:**
- Save the following code as `app.py`.
```python
from fastapi import FastAPI
from confluent_kafka import Consumer
from datetime import datetime, timedelta, timezone
import my_protobuf_pb2 # Import your Protobuf message definition
from mangum import Mangum
app = FastAPI()
consumer_conf = {
'bootstrap.servers': 'your-redpanda-broker:9092',
'group.id': 'fastapi-group',
'auto.offset.reset': 'earliest'
}
consumer = Consumer(consumer_conf)
topic = 'your-topic'
consumer.subscribe([topic])
@app.get("/gool-tickets")
def get_gool_tickets():
now = datetime.now(timezone.utc)
last_24_hours = now - timedelta(hours=24)
messages = []
while True:
msg = consumer.poll(1.0) # Poll for 1 second
if msg is None:
break
if msg.error():
continue
msg_timestamp = msg.timestamp()[1]
msg_time = datetime.fromtimestamp(msg_timestamp / 1000, tz=timezone.utc)
if msg_time >= last_24_hours:
proto_msg = my_protobuf_pb2.Ticket() # Adjust according to your message type
proto_msg.ParseFromString(msg.value())
if proto_msg.ticket_type == "Gool":
messages.append({
"ticket_type": proto_msg.ticket_type,
"timestamp": msg_time.isoformat()
})
return {"gool_tickets": messages}
handler = Mangum(app)
```
## Step 2: Package the Application
1. **Create Deployment Package:**
```bash
mkdir package
pip install -r requirements.txt -t package/
cp app.py my_protobuf_pb2.py package/
cd package
zip -r ../fastapi_lambda.zip .
cd ..
```
## Step 3: Upload to S3
1. **Create S3 Bucket (if needed):**
```bash
aws s3 mb s3://your-s3-bucket-name
```
2. **Upload the Package:**
```bash
aws s3 cp fastapi_lambda.zip s3://your-s3-bucket-name/
```
## Step 4: Deploy with CloudFormation
1. **Validate the Template:**
```bash
aws cloudformation validate-template --template-body file://template.yaml
```
2. **Deploy the Stack:**
```bash
aws cloudformation create-stack \
--stack-name FastAPIAppStack \
--template-body file://template.yaml \
--capabilities CAPABILITY_IAM
```
3. **Check Deployment Status:**
```bash
aws cloudformation describe-stacks --stack-name FastAPIAppStack
```
4. **Get the ALB URL:**
After deployment, get the ALB URL from the CloudFormation outputs and access your FastAPI app at:
```plaintext
http://your-alb-dns-name/gool-tickets
```
# CloudFormation Template (template.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Description: FastAPI on Lambda with ALB
Resources:
FastAPILambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: FastAPIHandler
Runtime: python3.11
Handler: app.handler
Timeout: 30
MemorySize: 256
Role: !GetAtt LambdaExecutionRole.Arn
Code:
S3Bucket: your-s3-bucket-name
S3Key: fastapi_lambda.zip
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: FastAPIExecutionRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: ['sts:AssumeRole']
Policies:
- PolicyName: FastAPIPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: FastAPIALB
Subnets:
- subnet-xxxxxxxx # Replace with your subnet IDs
- subnet-yyyyyyyy
SecurityGroups:
- !Ref ALBSecurityGroup
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '60'
Type: application
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and HTTPS
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Listener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ALB
Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupArn: !Ref LambdaTargetGroup
LambdaTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: FastAPILambdaTargetGroup
TargetType: lambda
Targets:
- Id: !GetAtt FastAPILambdaFunction.Arn
LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !GetAtt FastAPILambdaFunction.Arn
Principal: elasticloadbalancing.amazonaws.com
SourceArn: !GetAtt ALB.Arn
Outputs:
ALBUrl:
Value: !Sub "http://${ALB.DNSName}"
Description: URL of the ALB
No comments:
Post a Comment