Skip to content

LocalStack for AWS Service Study

Local AWS Cloud Development Environment for CLF-C02 Exam Preparation

Tool Versions (Pinned for Consistency)

This guide has been tested with the following tool versions. For consistency, we recommend using these versions or newer:

ToolVersionInstallation Check
Docker28.x+docker --version
Docker Composev2.24.0+docker compose version
AWS CLIv2.22.0+aws --version
LocalStack4.12.0+docker run localstack/localstack:latest
Python3.9+ (optional)python --version

Overview

LocalStack is a fully functional local AWS cloud stack that enables you to develop and test your cloud and serverless applications without connecting to AWS. It provides an emulated environment for AWS services that runs in a Docker container on your local machine.

Why Use LocalStack for AWS Study?

  • Zero AWS Costs: No charges for testing and learning
  • Fast Development: No network latency, instant responses
  • Offline Development: Work without internet connection
  • Safe Testing: Experiment freely without affecting production AWS resources
  • CI/CD Integration: Perfect for automated testing pipelines
  • Reproducible Environments: Consistent local setup across team members

LocalStack Tiers (2025)

As of May 8, 2025, LocalStack is offered in four tiers:

TierCostBest ForCI Credits
Free$0Learning, development, personal projectsNone
Base$39/monthProfessional development, small teams300 credits/month
UltimateCustomProduction development, enterprise features1000 credits/month
EnterpriseContact SalesLarge organizations, custom needsUnlimited

This guide focuses on the FREE tier and which AWS services are available for study.

Installation

Prerequisites

  • Docker Desktop or Docker Engine
  • 4GB RAM minimum (8GB recommended)
  • Python 3.7+ (for LocalStack CLI)
  • AWS CLI (optional, for testing)

Installation Methods

bash
# Pull the latest LocalStack image
docker pull localstack/localstack:latest

# Start LocalStack
docker run --rm -it -p 4566:4566 -p 4510-4559:4510-4559 localstack/localstack

Quick Start with provided files:

bash
cd module-01/aws/localstack
cp .env.example .env
docker compose up -d

Windows PowerShell:

powershell
cd module-01\aws\localstack
copy .env.example .env
docker compose up -d

Features:

  • Docker volume for data persistence (Pro feature - see notes below)
  • Environment variable configuration via .env file
  • Resource limits and health checks pre-configured
  • Cross-platform compatible

Important Notes:

  • Persistence is Pro-only: Community Edition is ephemeral by design. State is not persisted across container restarts.
  • Services load on-demand: In LocalStack 4.x, services are loaded automatically when accessed - no need to specify them.

Or create your own docker-compose.yml:

yaml
volumes:
  localstack-data:
    driver: local

services:
  localstack:
    image: localstack/localstack:4.12.0
    container_name: localstack-main
    ports:
      - "127.0.0.1:4566:4566"
      - "127.0.0.1:4510-4559:4510-4559"
    environment:
      # Core configuration
      - DEBUG=0
      # Persistence (Pro-only feature - Community Edition is ephemeral)
      - PERSISTENCE=1
    volumes:
      - localstack-data:/var/lib/localstack
      - /var/run/docker.sock:/var/run/docker.sock

Start with:

bash
docker compose up

Stop and remove data:

bash
docker compose down -v  # -v removes associated volumes

Notes:

  • The version field in docker-compose.yml is deprecated and no longer required in Docker Compose v2+
  • SERVICES variable is deprecated in 4.x - services load on-demand automatically
  • DATA_DIR variable is deprecated in 4.x - state is stored in /var/lib/localstack
  • Volume mount must be to /var/lib/localstack for persistence to work (Pro-only)
  • On Windows with Docker Desktop, the Docker socket is usually handled automatically
  • Use docker volume ls to list all volumes and docker volume inspect localstack-data to view volume details
  • Community Edition is ephemeral - data is not persisted across container restarts (persistence is Pro-only)

Method 3: Python pip

bash
pip install localstack

# Start LocalStack
localstack start

Verifying Installation

bash
# Check if LocalStack is running
curl http://localhost:4566/_localstack/health

# Expected response:
# {"status": "ok"}

Configuring AWS CLI for LocalStack

LocalStack requires AWS credentials to be configured. Use test credentials for local development:

bash
# Option 1: Create a dedicated LocalStack profile (recommended)
aws configure set aws_access_key_id test --profile localstack
aws configure set aws_secret_access_key test --profile localstack
aws configure set region us-east-1 --profile localstack

# Verify configuration
aws --profile localstack configure list

# Option 2: Set environment variables
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_REGION=us-east-1

# Set the endpoint URL for all commands
export AWS_ENDPOINT_URL=http://localhost:4566

# Or use in each command:
aws --profile localstack --endpoint-url=http://localhost:4566 s3 ls

Important: For S3 pre-signed URLs to work correctly, credentials must be set to test/test.

Service Coverage - FREE Tier

Services Available in FREE Tier

The following AWS services covered in the CLF-C02 exam are available in the LocalStack FREE tier:

Compute Services

ServiceFree TierNotes
EC2✅ YesFull mock implementation
Lambda✅ YesFull support with Docker/Lambda execution
Elastic Beanstalk❌ NoRequires Base tier

Storage Services

ServiceFree TierNotes
S3✅ YesFull S3 API support including versioning
S3 Control✅ YesS3 control plane operations
EBS✅ YesIncluded with EC2 mock
EFS❌ NoRequires Base tier
S3 Glacier❌ NoRequires Base tier

Database Services

ServiceFree TierNotes
DynamoDB✅ YesFull DynamoDB support
DynamoDB Streams✅ YesStreams functionality included
RDS❌ NoRequires Base tier
ElastiCache❌ NoRequires Base tier
Aurora❌ NoPart of RDS (Base tier)

Networking Services

ServiceFree TierNotes
Route 53✅ YesDNS mock implementation
API Gateway (REST)✅ YesFull REST API support
API Gateway (HTTP)❌ NoRequires Base tier
CloudFront❌ NoRequires Base tier
VPC✅ YesVPC and networking mock
ELB/ELBv2❌ NoRequires Base tier
Direct ConnectN/ANot applicable for local

Analytics Services

ServiceFree TierNotes
Kinesis Data Streams✅ YesFull Kinesis streams support
Kinesis Data Firehose✅ YesFirehose delivery supported
Kinesis Data Analytics❌ NoRequires Base tier
Athena❌ NoRequires Ultimate tier
Redshift✅ YesRedshift mock available
EMR❌ NoRequires Ultimate tier
Glue❌ NoRequires Ultimate tier
OpenSearch/Elasticsearch✅ YesFull search service support
QuickSight❌ NoNot available in LocalStack
MSK❌ NoRequires Base tier

Security & Compliance Services

ServiceFree TierNotes
IAM✅ YesFull IAM policy enforcement
KMS✅ YesKey management mock
Secrets Manager✅ YesSecrets storage supported
Certificate Manager✅ YesSSL certificate mock
STS✅ YesSecurity Token Service
Cognito❌ NoRequires Base tier
WAF❌ NoRequires Base tier
Shield❌ NoRequires Base tier
GuardDutyN/ANot available in LocalStack

Application Integration Services

ServiceFree TierNotes
SNS✅ YesFull SNS topic/subscription support
SQS✅ YesFull SQS queue support
Step Functions✅ YesWorkflow orchestration
EventBridge✅ YesEvent bus and rules

Management & Governance Services

ServiceFree TierNotes
CloudFormation✅ YesFull CloudFormation support
CloudWatch Metrics✅ YesMetrics storage and retrieval
CloudWatch Logs✅ YesLog storage and queries
CloudTrail❌ NoRequires Ultimate tier
Config✅ YesConfiguration tracking
Systems Manager✅ YesParameter Store supported
Resource Groups✅ YesResource organization
Support API✅ YesAWS Support mock

Services NOT Available (Limitations)

The following CLF-C02 services are NOT available in LocalStack Free tier:

ServiceReason
Elastic BeanstalkRequires Base tier
EFSRequires Base tier
S3 GlacierRequires Base tier
RDSRequires Base tier
ElastiCacheRequires Base tier
AuroraPart of RDS (Base tier)
API Gateway HTTP/WebSocketRequires Base tier
CloudFrontRequires Base tier
ELB/ELBv2Requires Base tier
Kinesis Data AnalyticsRequires Base tier
AthenaRequires Ultimate tier
EMRRequires Ultimate tier
GlueRequires Ultimate tier
MSKRequires Base tier
CognitoRequires Base tier
WAFRequires Base tier
ShieldRequires Base tier
CloudTrailRequires Ultimate tier
QuickSightNot available (BI service)

Getting Started with LocalStack

1. Test S3 (Storage)

bash
# Create a bucket
aws --endpoint-url=http://localhost:4566 s3 mb s3://my-test-bucket

# List buckets
aws --endpoint-url=http://localhost:4566 s3 ls

# Upload a file
echo "Hello LocalStack" > test.txt
aws --endpoint-url=http://localhost:4566 s3 cp test.txt s3://my-test-bucket/

# List objects
aws --endpoint-url=http://localhost:4566 s3 ls s3://my-test-bucket

# Download the file
aws --endpoint-url=http://localhost:4566 s3 cp s3://my-test-bucket/test.txt test-downloaded.txt

2. Test Lambda (Compute)

bash
# Create a simple Lambda function
mkdir lambda-test
cd lambda-test

# Create handler.py
cat > handler.py << 'EOF'
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'Hello from LocalStack Lambda!'
        })
    }
EOF

# Create the Lambda function
aws --endpoint-url=http://localhost:4566 lambda create-function \
    --function-name my-test-function \
    --runtime python3.11 \
    --role arn:aws:iam::000000000000:role/test-role \
    --handler handler.lambda_handler \
    --zip-file fileb://function.zip \
    --timeout 10

# Zip the function
zip -r function.zip handler.py

# Invoke the Lambda
aws --endpoint-url=http://localhost:4566 lambda invoke \
    --function-name my-test-function \
    response.json

# View the response
cat response.json

3. Test DynamoDB (Database)

bash
# Create a table
aws --endpoint-url=http://localhost:4566 dynamodb create-table \
    --table-name Users \
    --attribute-definitions \
        AttributeName=UserId,AttributeType=S \
        AttributeName=Username,AttributeType=S \
    --key-schema \
        AttributeName=UserId,KeyType=HASH \
        AttributeName=Username,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST

# List tables
aws --endpoint-url=http://localhost:4566 dynamodb list-tables

# Put an item
aws --endpoint-url=http://localhost:4566 dynamodb put-item \
    --table-name Users \
    --item '{"UserId":{"S":"user1"},"Username":{"S":"john_doe"},"Email":{"S":"john@example.com"}}'

# Get the item
aws --endpoint-url=http://localhost:4566 dynamodb get-item \
    --table-name Users \
    --key '{"UserId":{"S":"user1"},"Username":{"S":"john_doe"}}'

# Scan the table
aws --endpoint-url=http://localhost:4566 dynamodb scan --table-name Users

4. Test Kinesis (Analytics)

bash
# Create a Kinesis stream
aws --endpoint-url=http://localhost:4566 kinesis create-stream \
    --stream-name my-test-stream \
    --shard-count 1

# List streams
aws --endpoint-url=http://localhost:4566 kinesis list-streams

# Describe the stream
aws --endpoint-url=http://localhost:4566 kinesis describe-stream \
    --stream-name my-test-stream

# Put a record
aws --endpoint-url=http://localhost:4566 kinesis put-record \
    --stream-name my-test-stream \
    --partition-key test-key \
    --data "SGVsbG8gTG9jYWxTdGFjayE="

# Get records (using shard iterator)
SHARD_ITERATOR=$(aws --endpoint-url=http://localhost:4566 kinesis get-shard-iterator \
    --stream-name my-test-stream \
    --shard-id shardId-000000000000 \
    --shard-iterator-type TRIM_HORIZON \
    --query 'ShardIterator' \
    --output text)

aws --endpoint-url=http://localhost:4566 kinesis get-records \
    --shard-iterator $SHARD_ITERATOR

5. Test SQS (Application Integration)

bash
# Create a queue
aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name my-test-queue

# List queues
aws --endpoint-url=http://localhost:4566 sqs list-queues

# Send a message
QUEUE_URL=$(aws --endpoint-url=http://localhost:4566 sqs get-queue-url --queue-name my-test-queue --query 'QueueUrl' --output text)

aws --endpoint-url=http://localhost:4566 sqs send-message \
    --queue-url $QUEUE_URL \
    --message "Hello from SQS in LocalStack!"

# Receive messages
aws --endpoint-url=http://localhost:4566 sqs receive-message \
    --queue-url $QUEUE_URL

6. Test CloudFormation (Infrastructure as Code)

bash
# Create a CloudFormation template
cat > template.yaml << 'EOF'
AWSTemplateFormatVersion: '2010-09-09'
Description: 'LocalStack Test S3 Bucket'

Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: my-cloudformation-bucket

Outputs:
  BucketName:
    Description: 'Name of the S3 bucket'
    Value: !Ref MyBucket
EOF

# Create the stack
aws --endpoint-url=http://localhost:4566 cloudformation create-stack \
    --stack-name my-test-stack \
    --template-body file://template.yaml

# Describe the stack
aws --endpoint-url=http://localhost:4566 cloudformation describe-stacks \
    --stack-name my-test-stack

# List stacks
aws --endpoint-url=http://localhost:4566 cloudformation list-stacks

LocalStack CLI Commands

Starting and Stopping

bash
# Start LocalStack
localstack start

# Stop LocalStack
localstack stop

# Check status
localstack status

# Start with specific services
SERVICES=s3,dynamodb,lambda localstack start

Docker Commands

bash
# Start with specific configuration
docker run --rm -it \
  -p 4566:4566 \
  -p 4510-4559:4510-4559 \
  -e SERVICES=lambda,s3,dynamodb,kinesis \
  -e DEBUG=1 \
  -e DATA_DIR=/tmp/localstack/data \
  -v "$(pwd)/volume:/tmp/localstack/data" \
  localstack/localstack

# View logs
docker logs -f localstack_main

# Stop container
docker stop localstack_main

# Remove container
docker rm localstack_main

Configuration

Environment Variables

VariableDescriptionDefault
SERVICESComma-separated list of servicesAll services
DEBUGEnable debug output0
DATA_DIRDirectory for persistent data/tmp/localstack/data
PORT_WEB_UIPort for web UI8080
LAMBDA_EXECUTORLambda execution modedocker
KINESIS_ERROR_PROBABILITYKinesis failure injection0.0

Configuration File

Create localstack-config.yaml:

yaml
services:
  - s3
  - lambda
  - dynamodb
  - kinesis
  - apigateway
  - iam
  - sns
  - sqs
  - logs

debug: true
data_dir: /tmp/localstack/data

lambda:
  executor: docker
  docker_network: localstack_local

kinesis:
  error_probability: 0.0

web_ui:
  port: 8080

Start with config:

bash
docker run --rm -it \
  -v $(pwd)/localstack-config.yaml:/etc/localstack-config.yaml \
  -p 4566:4566 \
  localstack/localstack

Web UI

LocalStack includes a web UI for monitoring and debugging:

bash
# Access the web UI
open http://localhost:8080
# Or in browser: http://localhost:8080

Features:

  • Resource viewer
  • Service status dashboard
  • Request/response logs
  • CloudFormation stack visualization
  • Lambda function logs

Best Practices for Study

1. Service-Specific Practice

S3 Practice:

  • Create buckets with different storage classes
  • Upload, download, and delete objects
  • Test versioning and lifecycle policies
  • Practice bucket policies

Lambda Practice:

  • Create functions with different runtimes
  • Test environment variables
  • Practice Lambda layers
  • Test Lambda with S3, DynamoDB triggers

DynamoDB Practice:

  • Create tables with different schemas
  • Test CRUD operations
  • Practice with indexes (GSI, LSI)
  • Test DynamoDB Streams

Kinesis Practice:

  • Create and manage streams
  • Test shard operations
  • Practice with Kinesis Firehose

2. CloudFormation Practice

Use CloudFormation to practice infrastructure as code:

yaml
# Complete S3 + Lambda + DynamoDB stack
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Serverless API in LocalStack'

Resources:
  # S3 Bucket for storage
  DataBucket:
    Type: AWS::S3::Bucket

  # DynamoDB Table
  UsersTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST

  # Lambda Function
  ProcessorFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.11
      Handler: index.handler
      Code:
        ZipFile: |
          def handler(event, context):
            return {'statusCode': 200, 'body': 'Hello!'}
      Role: !GetAtt LambdaRole.Arn

  # IAM Role
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole

3. Testing Commands

Create a test script test-localstack.sh:

bash
#!/bin/bash

ENDPOINT=http://localhost:4566

echo "Testing LocalStack..."
echo

# Test S3
echo "1. Testing S3..."
aws --endpoint-url=$ENDPOINT s3 mb s3://test-bucket
aws --endpoint-url=$ENDPOINT s3 ls
echo

# Test DynamoDB
echo "2. Testing DynamoDB..."
aws --endpoint-url=$ENDPOINT dynamodb create-table \
    --table-name TestTable \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST
echo

# Test Lambda
echo "3. Testing Lambda..."
# Add Lambda test commands here
echo

echo "All tests completed!"

Troubleshooting

Common Issues

Port Already in Use:

Linux/macOS:

bash
# Find and kill process using port 4566
lsof -ti:4566 | xargs kill -9

# Or use different port
docker run --rm -it -p 4567:4566 localstack/localstack

Windows PowerShell:

powershell
# Find process using port 4566
Get-NetTCPConnection -LocalPort 4566 | Select-Object -Property State, OwningProcess
# Kill the process using the PID
Stop-Process -Id <PID> -Force

Windows Command Prompt:

cmd
# Find process using port 4566
netstat -ano | findstr :4566
# Kill the process using the PID
taskkill /PID <PID> /F

Container Not Starting:

bash
# Check Docker is running
docker ps

# Check container logs
docker logs localstack_main

# Restart Docker Desktop (if using Mac/Windows)

Services Not Responding:

bash
# Check health endpoint
curl http://localhost:4566/_localstack/health

# Enable debug mode
docker run --rm -it -e DEBUG=1 -p 4566:4566 localstack/localstack

Lambda Execution Failures:

bash
# Ensure Docker is available for Lambda
docker ps

# Check Lambda logs
docker logs localstack_main | grep lambda

Study Tips

1. Progressive Learning Path

  1. Week 1: S3, DynamoDB, Lambda (Core services)
  2. Week 2: Kinesis, SQS, SNS (Messaging)
  3. Week 3: API Gateway, CloudFormation (Integration)
  4. Week 4: IAM, KMS, CloudWatch (Security & Monitoring)

2. Hands-On Exercises

For each service:

  1. Read the AWS documentation
  2. Practice basic operations in LocalStack
  3. Build a simple use case
  4. Test error scenarios
  5. Practice with AWS CLI commands

3. Practice Scenarios

Scenario 1: Serverless API

  • Create API Gateway
  • Add Lambda backend
  • Store data in DynamoDB
  • Test the complete flow

Scenario 2: Data Pipeline

  • Create S3 bucket
  • Create Kinesis stream
  • Create Lambda processor
  • Store results in DynamoDB

Scenario 3: Microservices

  • Create SQS queues
  • Create Lambda consumers
  • Implement SNS notifications
  • Test message flow

Limitations of FREE Tier

Service Limitations

The following CLF-C02 exam topics cannot be practiced with LocalStack FREE tier:

TopicServices Affected
Elastic BeanstalkPaaS deployment
EFSNetwork file storage
RDS/AuroraRelational databases
ElastiCacheIn-memory caching
CloudFrontCDN
ELB/ELBv2Load balancing
AthenaServerless queries
EMR/GlueBig data processing
QuickSightBI dashboards

Alternative Learning Strategies

For services NOT in LocalStack FREE tier:

  1. Use AWS Free Tier for RDS, CloudFront, ELB
  2. Read Documentation for conceptual understanding
  3. Watch Video Tutorials for service demonstrations
  4. Use DigitalCloud Cheat Sheets for exam prep
  5. Practice with AWS Console (sandbox accounts available)

Additional Resources

Official Documentation

LocalStack Resources

Learning Resources

Pricing and Tiers


Last Updated: January 2025 | LocalStack Version: 4.12.0 (Community Edition)

Released under the MIT License.