Skip to content

RomanKaliupinMelonusa/aws-docker-lambda-basic-setup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lambda Python Container (ARM64) — Setup & Deploy Guide

This repository ships a minimal, enterprise-friendly starter that:

  • Builds a single Docker image for ARM64 (native on Apple Silicon) that runs as an AWS Lambda and can also run a tiny local Python HTTP service.
  • Lets you test Lambda locally using the official Runtime Interface Emulator (RIE) built into the AWS Lambda Python base image.
  • Deploys entirely with CloudFormation (ECR repo, IAM role, Lambda from container image, Function URL).
  • Uses AWS CLI SSO (IAM Identity Center) for authentication.
  • Keeps application deps in requirements.in (compiled to pinned requirements.txt at image build).

Contents


Prerequisites

  • Docker Desktop (with Buildx) on macOS Apple Silicon (M1/M2/M3).
  • AWS CLI v2 installed.
  • Make installed.
  • Access to an AWS account via IAM Identity Center (SSO).

The project uses the official AWS Lambda Python base image, which mirrors the Lambda environment and includes the Runtime Interface Emulator for local testing.


AWS SSO (one-time per account)

Configure an SSO-backed CLI profile and sign in:

aws configure sso
# Follow the prompts: SSO start URL, SSO region, account, role, and profile name.

aws sso login --profile <your-sso-profile>
aws sts get-caller-identity --profile <your-sso-profile>
  • aws configure sso creates a profile that sources temporary credentials from IAM Identity Center. (AWS Documentation)
  • aws sso login retrieves and caches an SSO access token for that profile. (AWS CLI)

Project Layout

.
├── app/
│   ├── __init__.py
│   ├── handler.py        # Lambda handler
│   └── service.py        # Tiny FastAPI "service" for local health/echo
├── cfn/
│   ├── infra.yaml        # ECR repo + IAM role
│   └── app.yaml          # Lambda from container image (arm64) + Function URL
├── .dockerignore
├── .env.example
├── Dockerfile
├── Makefile
├── requirements.in       # single source of truth
└── requirements.txt      # pinned (compiled at build)

Key Files

  • app/handler.py — Lambda handler that returns a JSON response with event data and an environment variable.
  • app/service.py — FastAPI app with /health and /echo endpoints for local testing.
  • Dockerfile — Multi-purpose image using AWS Lambda Python 3.11 base image.
  • Makefile — All commands for build, deploy, and test workflows.
  • cfn/infra.yaml — CloudFormation template for ECR repository and Lambda execution role.
  • cfn/app.yaml — CloudFormation template for Lambda function and Function URL.

.env Configuration

Copy and edit:

cp .env.example .env

Key variables (override as needed):

# ---- General ----
APP_NAME=lambda-python-basic
AWS_REGION=us-west-2
AWS_PROFILE=your-sso-profile-name
ECR_REPO_NAME=lambda-python-basic
IMAGE_TAG=v0

# ---- App runtime (used locally and in AWS) ----
EXAMPLE_MESSAGE=Hello from .env (local) and CloudFormation (AWS)

# ---- Stacks ----
STACK_INFRA=lambda-python-basic-infra
STACK_APP=lambda-python-basic-app

Local vs AWS env

  • Local: make loads .env and passes variables to containers.
  • AWS: cfn/app.yaml sets Environment.Variables on the Lambda function; these are standard Lambda env vars. For secrets, prefer AWS Secrets Manager or SSM Parameter Store (not included in this minimal starter). (AWS Documentation)

Local Build & Run (Apple Silicon / ARM64)

1) Build the ARM64 image

make build
  • The Makefile builds with --platform linux/arm64 to match the Lambda architecture and run natively on M1/M2/M3.

2) Run the Lambda locally (RIE)

make run-lambda-local
# In another terminal:
make invoke-local
  • The AWS base image includes the Runtime Interface Emulator, which exposes a local endpoint on :9000. We invoke the standard Lambda Runtime API path to simulate an invocation. (GitHub)
  • Expected response:
{
    "statusCode": 200,
    "headers": {
        "Content-Type": "application/json"
    },
    "body": "{\"message\": \"Hello from .env (local) and CloudFormation (AWS)\", \"received_event\": {\"ping\": \"pong\"}, \"arch_hint\": \"arm64\"}"
}

3) (Optional) Run the tiny Python service

make run-api
# Visit http://localhost:8000/health and http://localhost:8000/echo?msg=hi

Provision AWS Infrastructure (CloudFormation)

All AWS resources are defined as code in cfn/.

1) ECR repository + Lambda IAM role

make cfn-up-infra
  • Creates a private ECR repository (immutability, scan-on-push) and a Lambda execution role with basic logging.
  • Outputs the ECR repo URI and role ARN for later steps.

ECR hosts the container image used by the Lambda; CloudFormation is the supported way to define the Lambda function and its image reference (Code.ImageUri). (AWS Documentation)


Build, Tag & Push the Image to ECR

1) Authenticate Docker to ECR

make ecr-login

This uses the recommended get-login-password flow with Docker's login command. (AWS Documentation)

2) Push the image

make push

Tags your local image with the ECR URI exported by the infra stack and pushes :$(IMAGE_TAG).


Deploy the Lambda + Function URL (CloudFormation)

make cfn-up-app

This stack:

  • Creates/updates AWS::Lambda::Function with PackageType: Image and your ECR ImageUri. (AWS Documentation)
  • Sets Architectures: ["arm64"] to run on Graviton/ARM64.
  • Creates an AWS::Lambda::Url for quick HTTPS testing (public in this starter; switch to AWS_IAM for private). (AWS Documentation)

The official Lambda container-image flow requires referencing an image in Amazon ECR via Code.ImageUri when using CloudFormation. (AWS Documentation)


Test on AWS

A) Invoke via AWS CLI

make invoke-aws

Returns the handler's JSON response for a sample payload:

{
    "statusCode": 200,
    "headers": {
        "Content-Type": "application/json"
    },
    "body": "{\"message\": \"Hello from .env (local) and CloudFormation (AWS)\", \"received_event\": {\"from\": \"make\"}, \"arch_hint\": \"arm64\"}"
}

B) Invoke via public Function URL

FUNCTION_URL=$(make -s show-url)
curl -s "$FUNCTION_URL" | python -m json.tool
  • A Function URL is a dedicated HTTPS endpoint to invoke your function directly. In this starter it's public (AuthType: NONE) for convenience; for production use AWS_IAM and a matching AWS::Lambda::Permission. (AWS Documentation)

Cleanup

make teardown
  • Deletes the app and infra stacks. You may need to delete images/tags to remove an immutable ECR repo cleanly.

Troubleshooting

SSO auth issues

Re-run aws sso login --profile <your-sso-profile> to refresh tokens. Ensure the profile was created with aws configure sso. (AWS Documentation)

ECR login fails

Use the get-login-password flow and verify your AWS CLI is up to date. (AWS Documentation)

# Verify AWS CLI version
aws --version

# Should be 2.x

Local Lambda not responding

Ensure the container is running and you're POSTing to /2015-03-31/functions/function/invocations on port 9000. The RIE is included in the AWS Lambda base image for local testing. (GitHub)

# Check if container is running
docker ps

# Check logs
docker logs <container-id>

Architecture mismatch

Always build with --platform linux/arm64 locally and set Architectures: ["arm64"] in CloudFormation for the function. (AWS Documentation)

ECR_URI or ROLE_ARN empty

If you see errors about empty ECR_URI or ROLE_ARN, ensure you've run make cfn-up-infra first and the stack has completed successfully.

# Check stack status
aws cloudformation describe-stacks --stack-name lambda-python-basic-infra --profile <your-sso-profile>

Make Commands Reference

make help                 # Show all available commands
make build                # Build ARM64 image
make run-lambda-local     # Run Lambda locally on :9000 with RIE
make invoke-local         # Invoke local Lambda
make run-api              # Run FastAPI service on :8000
make cfn-up-infra         # Deploy ECR repo + IAM role
make ecr-login            # Docker login to ECR
make push                 # Build/tag/push image to ECR
make cfn-up-app           # Deploy Lambda (container image) + Function URL
make invoke-aws           # Invoke deployed Lambda via AWS CLI
make show-url             # Print Function URL
make teardown             # Delete both stacks

References

  • AWS Lambda (Python) container images & local testing — base images and usage. (AWS Documentation)
  • Runtime Interface Emulator (RIE) — local testing for containerized Lambdas. (GitHub)
  • CloudFormation: AWS::Lambda::FunctionPackageType: Image, Code.ImageUri, Architectures. (AWS Documentation)
  • CloudFormation: AWS::Lambda::Url — Function URL resource. (AWS Documentation)
  • Amazon ECR authget-login-password + Docker login. (AWS Documentation)
  • AWS CLI SSO Configuration — configuring IAM Identity Center authentication. (AWS Documentation)

License

This project is open source and available under the MIT License.

About

Basic setup with AWS + Docker + Lambda + Python

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors