1
0
Files
2026-02-20 15:36:45 +08:00

3.7 KiB

LocalStack

It's a fair tool to test terraform code without actually deploying anything on aws. However, there are a few limitations on LocalStack.

Setup

Sign up for localstack and obtain the auth token. Then fire up a container:

docker run -e LOCALSTACK_AUTH_TOKEN=ls-xxx-yyy-zzz-aaa-bbb -it \
--name localstack --network macvlan localstack/localstack-pro localstack 

or use community edition while it is still available

docker run \
-e AWS_ACCESS_KEY_ID=test \
-e AWS_SECRET_ACCESS_KEY=test \
-e SERVICES="s3,iam,lambda,dynamodb,cloudwatch,rds,ec2,secretsmanager,stepfunctions" \
-e DEBUG=0 \
-d --rm --name localstack --network macvlan localstack/localstack localstack 

In terraform, configure aws endpoints to go to localstack and add localstack required configurations:

provider "aws" {
  region = var.aws-region

  # localstack config
  access_key                  = "test"
  secret_key                  = "test"
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  # localstack endpoints https://docs.localstack.cloud/aws/integrations/infrastructure-as-code/terraform/#:~:text=tflocal%20is%20a%20small%20wrapper,unmodified%20Terraform%20scripts%20against%20LocalStack.
  endpoints {
    apigateway     = "http://192.168.86.96:4566"
    apigatewayv2   = "http://192.168.86.96:4566"
    cloudformation = "http://192.168.86.96:4566"
    cloudwatch     = "http://192.168.86.96:4566"
    dynamodb       = "http://192.168.86.96:4566"
    ec2            = "http://192.168.86.96:4566"
    es             = "http://192.168.86.96:4566"
    elasticache    = "http://192.168.86.96:4566"
    firehose       = "http://192.168.86.96:4566"
    iam            = "http://192.168.86.96:4566"
    kinesis        = "http://192.168.86.96:4566"
    lambda         = "http://192.168.86.96:4566"
    rds            = "http://192.168.86.96:4566"
    redshift       = "http://192.168.86.96:4566"
    route53        = "http://192.168.86.96:4566"
    s3             = "http://192.168.86.96:4566"
    secretsmanager = "http://192.168.86.96:4566"
    ses            = "http://192.168.86.96:4566"
    sns            = "http://192.168.86.96:4566"
    sqs            = "http://192.168.86.96:4566"
    ssm            = "http://192.168.86.96:4566"
    stepfunctions  = "http://192.168.86.96:4566"
    sts            = "http://192.168.86.96:4566"
  }
}

Limitations

At time of writing, localstack seems very limited. Many basic layers would not run. For example, vpc with ipv6 could not be created. It failed with the following error

│ Error: waiting for EC2 Subnet (subnet-c113e8c02abd344e0) EnableDns64 update: timeout while waiting for state to become 'true' (last state: 'false', timeout: 5m0s)
│ 
│   with module.vpc.aws_subnet.private[1],
│   on .terraform/modules/vpc/main.tf line 293, in resource "aws_subnet" "private":
│  293: resource "aws_subnet" "private" {

Also, ec2 instance's associate_public_ip_address attribute is always set to true, despite it is set to false in my code. This caused the instance to be redeployed everytime terraform apply is ran.

If I tried to deploy a lambda function, LocalStack actually tried to create an executable container via docker. That cannot be disabled and without docker, I got this error when trying to deploy a function. Subsequently, I cannot destroy the function since provisioning failed.

Error: waiting for Lambda Function (HelloWorldFunction) create: unexpected state 'Failed', wanted target 
'Active, ActiveNonInvocable'. last error: InternalError: Error while creating lambda: Docker not available

Both the free and community editions of LocalStack do not support rds, among other services described in https://docs.localstack.cloud/aws/licensing/