# 007 - AWS Lambda Container with FastAPI

By
Alexander Zabielski

Last Modified: July 16th, 2025

Title: Adoption of AWS Lambda Container with Lightweight Python Router (FastAPI) for API Endpoints

# Status: Implemented

# Context

Our team currently has a collection of Python files that serve as individual AWS Lambda functions, each responsible for a single CRUD (Create, Read, Update, Delete) operation. For example, we have separate Lambdas such as AddUser.py, DeleteUser.py, AddCustomer.py, and DeleteCustomer.py. This architecture has led to:

  • Lambda Sprawl: A rapidly growing number of individual Lambda functions, making management, monitoring, and deployment increasingly complex.
  • Redundant Code and Dependencies: Common logic (e.g., database connection, authentication, error handling) is often duplicated across many functions, increasing maintenance overhead and the risk of inconsistencies.
  • Inefficient Cold Starts: Each individual Lambda function is prone to its own cold starts, leading to inconsistent API response times, particularly for less frequently accessed operations.
  • Complex CI/CD: Deploying new features or updating existing ones often involves managing multiple, separate deployment pipelines.
  • Limited Development Velocity: The overhead of creating and managing individual Lambdas for every granular operation slows down feature development.

As we consider more scalable and maintainable deployment strategies on AWS for our Python backend logic and API endpoints, we need a solution that addresses these challenges. The goal is to refactor our existing scattered Python code into a coherent, scalable, and cost-efficient application, moving away from fragmented, single-operation scripts towards a more unified and streamlined approach.


# Decision

We will consolidate our Python API endpoint logic into a single AWS Lambda function, leveraging a lightweight Python web framework (FastAPI) as a router, and packaging this application as a Docker container image for deployment to AWS Lambda. This refactoring effort will replace the existing individual CRUD operation Lambdas (e.g., AddUser.py, DeleteUser.py) with a consolidated API, with all infrastructure provisioned and managed using Terraform within our CI/CD pipelines, leveraging the Terraform Docker provider.


# Rationale

This option was selected based on a comprehensive evaluation of scalability, cost-effectiveness, operational simplicity, and developer experience, directly addressing the limitations of our current "Lambda sprawl" architecture.

  1. Optimized Scalability and Cost for API Workloads:

    • Serverless Nature: AWS Lambda automatically scales to meet demand, eliminating the need for manual server provisioning or scaling configurations. We only pay for the actual compute time consumed, making it highly cost-effective for variable or intermittent API traffic.
    • Reduced Cold Starts: By consolidating multiple API paths (e.g., /users, /customers) into a single Lambda function, the aggregated traffic helps keep the function "warm" more consistently. This significantly reduces the frequency of cold starts across our API endpoints compared to deploying numerous individual Lambda functions for each CRUD operation.
    • Cost Efficiency for Aggregate Traffic: While the single Lambda might be configured with slightly more memory than a minimal individual Lambda, the efficiency gained from fewer cold starts and streamlined management often results in comparable or even better overall cost efficiency for API workloads.
  2. Enhanced Developer Experience with FastAPI:

    • Unified Development Model: Developers can build and test a single, coherent web application using familiar web framework patterns (routes, dependency injection, validation) instead of managing disparate Lambda handlers. This directly replaces the need for separate AddUser.py, DeleteUser.py files with clear routing within one application.
    • Automatic Documentation: FastAPI provides automatic interactive API documentation (Swagger UI/OpenAPI), which is invaluable for development, testing, and team collaboration, especially as API surface grows.
    • Code Reusability: Common logic (e.g., user authentication, input validation, database interactions) can be centralized and reused across different API endpoints (e.g., for users and customers), eliminating the duplication present in our current individual Lambda files.
  3. Flexibility and Control with Container Images:

    • Larger Dependencies: Container images overcome the 250MB unzipped deployment package limit of ZIP archives, allowing us to include larger Python libraries directly within the Lambda function.
    • Custom Runtimes and OS Packages: Provides full control over the Python environment and the ability to include specific operating system-level packages if needed, which is not possible with standard Lambda runtimes.
    • Local Development Consistency: The Docker image ensures consistency between local development environments and the deployed Lambda environment, reducing "it works on my machine" issues.
  4. Simplified Management and Deployment:

    • Full Infrastructure and Application Lifecycle as Code: Terraform, using the Docker provider, now centrally manages not just the AWS infrastructure (Lambda, API Gateway, ECR, IAM roles, etc.) but also the entire Docker image build and push process. This offers a single source of truth for both infrastructure and the deployable application artifact.
    • Fewer Tools in CI/CD Script: The CI/CD pipeline's script becomes simpler, primarily executing Terraform commands, as the complex Docker build/push logic is encapsulated within Terraform.
    • Streamlined CI/CD: Terraform integrates seamlessly into CI/CD pipelines, enabling automated, repeatable, and safe deployments of both application code and infrastructure changes.

# Implications

This decision will have several consequences affecting our team, processes, and tooling.

  1. People/Training:

    • Developers will need familiarity with Docker for building and debugging container images.
    • Team members new to FastAPI will require basic training on the framework's conventions and features, specifically how to define routes and dependencies within a consolidated application.
    • A good understanding of mangum and its role in connecting FastAPI to Lambda events will be beneficial.
    • Existing team members will need to gain proficiency in Terraform for defining and managing the AWS infrastructure.
  2. Process Adjustments:

    • A single Terraform step to terraform plan and terraform apply which will now internally trigger the Docker image build, push to ECR, and update the Lambda function.
    • Deployment scripts will primarily consist of Terraform configurations.
    • A clear strategy for tagging and versioning Docker images in ECR should be established, as Terraform will now manage the image tags pushed.
    • Code reviews will shift from reviewing individual Lambda files to reviewing API endpoints within the consolidated FastAPI application, alongside Terraform configuration changes.
    • The CI/CD runner environment must have access to a Docker daemon for Terraform's Docker provider to function.
  3. Tooling:

    • Docker: Required on developer machines for local build and test, and on CI/CD runners for Terraform's Docker provider.
    • AWS CLI: For interacting with ECR and Lambda during development and for CI/CD authentication.
    • Terraform: The primary Infrastructure as Code tool for defining and managing all AWS resources (Lambda, API Gateway, ECR, IAM roles, CloudWatch logs, etc.) and, importantly, for building and pushing the Docker image via the Docker provider.
    • Mangum: This Python library will be a core dependency in our application.
  4. Risks:

    • Potential for Larger Cold Starts (Initial): While overall cold starts are expected to decrease, the initial cold start for a container image might be longer than a very small ZIP-deployed Lambda, especially if the image is large. This can be mitigated with Terraform-managed Lambda Provisioned Concurrency for critical paths.
    • Increased Memory Consumption: A full web framework like FastAPI might require more memory than a minimal "straight" Lambda function, leading to a slightly higher per-second compute cost. Careful monitoring and memory optimization will be necessary, configurable via Terraform.
    • Monolithic-like Concerns within Lambda (Anti-Pattern Risk): While offering more flexibility, putting all logic into one extremely large Lambda can still lead to a less focused application if not well-architected internally with proper modularization, routers, and separation of concerns. This is a refactoring challenge, not a deployment challenge unique to Lambda.
    • 15-Minute Timeout Limit: Still subject to Lambda's maximum execution duration, making it unsuitable for very long-running background tasks.
    • Terraform Learning Curve: There will be an initial investment in time for the team to learn and become proficient with Terraform, particularly for managing Lambda and API Gateway resources with container images and integrating the Docker provider effectively.
    • Docker Daemon Dependency on CI/CD: The CI/CD environment must reliably provide a Docker daemon for Terraform to interact with. This might require specific runner configurations (e.g., Docker-in-Docker or a shared daemon)

# Trade-Offs

  • Benefits:

    • Eliminates Lambda Sprawl: Drastically reduces the number of individual Lambda functions to manage.
    • Unified Infrastructure and Application Lifecycle with Terraform: A single Terraform configuration manages both AWS resources and the Docker image build/push, streamlining the deployment process and improving consistency
    • Enhanced Developer Productivity: Leverage FastAPI's features (validation, docs, dependency injection) for faster development and clearer API definitions.
    • Consistent Development Environment: Docker ensures local behavior matches production.
    • Scalability & Cost Efficiency: Inherits Lambda's auto-scaling and pay-per-use model, with potential cold start reduction benefits due to aggregated traffic.
    • Simplified CI/CD Scripts: The CI/CD pipeline's scripts becomes leaner as Docker logic is encapsulated in Terraform.
    • Improved Code Reusability: Facilitates shared logic and components across API endpoints.
    • Streamlined CI/CD: Automated and consistent deployments of both code and infrastructure.
  • Drawbacks:

    • Potential for Higher Per-Invocation Cost: A slightly larger memory allocation and framework overhead might result in a higher cost per invocation compared to an absolutely minimal individual Lambda.
    • ECR Storage Cost: A small, additional monthly cost for storing Docker images.
    • Initial Learning Curve: Developers new to Docker, FastAPI, and the Terraform Docker provider will need time to adapt.
    • 15-Minute Timeout Limit: Still subject to Lambda's maximum execution duration, making it unsuitable for very long-running background tasks.
    • CI/CD Runner Requirements: The CI/CD environment must be able to run a Docker daemon, which might influence platform choice or configuration

# Key Evaluation Metrics

We will define clear criteria to measure whether this decision solves the intended problems and delivers the expected benefits.

  • Reduced Number of Lambda Functions: A direct measure of success will be a significant reduction in the total number of Lambda functions deployed for our API.
  • Deployment Time: Reduce the time from code commit to a deployed, functional API endpoint (compared to managing individual Lambda deployments). Aim for < 5 minutes for a routine update.
  • API Latency: Maintain average API response times below 200ms, with a focus on minimizing the impact of cold starts on user-facing endpoints.
  • Operational Overhead Reduction: Measure the reduction in manual configuration tasks for new API endpoints (e.g., number of CloudFormation/Terraform lines for a new endpoint), and reduced time spent debugging "Lambda sprawl" issues. This includes the simplification of infrastructure management through Terraform.
  • Developer Satisfaction: Conduct surveys or feedback sessions to gauge developer satisfaction with the new development workflow and tools, specifically noting improvements from the consolidation and the use of Terraform for infrastructure.
  • Cost Efficiency: Monitor AWS bills to ensure that the total cost (Lambda + API Gateway + ECR) for our API endpoints remains within acceptable limits or shows favorable trends compared to fragmented deployments, accounting for the refactoring.

# Conclusion

We recommend adopting the strategy of deploying a single AWS Lambda function containing a Python FastAPI application, packaged as a container image, for our API endpoints. This decision directly addresses our current challenges of Lambda sprawl, redundant code, and inefficient cold starts stemming from single CRUD operation Lambdas. The explicit adoption of Terraform, including its Docker provider, for all infrastructure provisioning and Docker image lifecycle management, will further solidify our Infrastructure as Code practices, enhancing consistency and reliability by centralizing these concerns. While there's an initial learning curve for Docker, FastAPI, and Terraform, and a slight potential for higher per-invocation costs due to increased memory allocation, the significant advantages in developer productivity, architectural simplicity, scalability management, and the ability to handle rich Python dependencies far outweigh these challenges. This approach provides a robust, maintainable, and modern foundation for our API services on AWS, consolidating our scattered Python logic into a cohesive application managed entirely as code.

Next steps include:

  1. Setting up the core FastAPI application structure, beginning the refactoring of existing CRUD logic into unified API routes.
  2. Developing a sample Dockerfile and updating the requirements.txt.
  3. Developing initial Terraform configurations for ECR, the Lambda function, IAM roles, API Gateway, and the Docker image build/push process using the Terraform Docker provider.
  4. Integrating the Terraform plan and apply steps into our CI/CD pipeline, ensuring the CI/CD runner has Docker daemon access.

# References