localstack / localstack
- среда, 29 января 2020 г. в 00:19:18
Python
💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline!
LocalStack provides an easy-to-use test/mocking framework for developing Cloud applications.
Currently, the focus is primarily on supporting the AWS cloud stack.
0.7.0, the Docker image will be pushed
and kept up to date under the new name localstack/localstack. (This means that you may
have to update your CI configurations.) Please refer to the updated
End-User License Agreement (EULA) for the new versions.
The old Docker image (atlassianlabs/localstack) is still available but will not be maintained
any longer.LocalStack spins up the following core Cloud APIs on your local machine:
In addition to the above, the Pro version of LocalStack supports additional APIs and advanced features, including:
LocalStack builds on existing best-of-breed mocking/testing tools, most notably kinesalite/dynalite and moto. While these tools are awesome (!), they lack functionality for certain use cases. LocalStack combines the tools, makes them interoperable, and adds important missing functionality on top of them:
ProvisionedThroughputExceededException which is thrown by Kinesis or DynamoDB if the amount of
read/write throughput is exceeded.python (both Python 2.x and 3.x supported)pip (python package manager)DockerThe easiest way to install LocalStack is via pip:
pip install localstack
Note: Please do not use sudo or the root user - LocalStack
should be installed and started entirely under a local non-root user. If you have problems
with permissions in MacOS X Sierra, install with pip install --user localstack
By default, LocalStack gets started inside a Docker container using this command:
localstack start
(Note that on MacOS you may have to run TMPDIR=/private$TMPDIR localstack start --docker if
$TMPDIR contains a symbolic link that cannot be mounted by Docker.)
docker-composeYou can also use the docker-compose.yml file from the repository and use this command (currently requires docker-compose version 2.1+):
docker-compose up
(Note that on MacOS you may have to run TMPDIR=/private$TMPDIR docker-compose up if
$TMPDIR contains a symbolic link that cannot be mounted by Docker.)
Use on existing docker-compose project. Add in existing services. The project can be found in docker hub, no need to download or clone source:
version: '2.1'
services:
...
localstack:
image: localstack/localstack
ports:
- "4567-4584:4567-4584"
- "${PORT_WEB_UI-8080}:${PORT_WEB_UI-8080}"
environment:
- SERVICES=${SERVICES- }
- DEBUG=${DEBUG- }
- DATA_DIR=${DATA_DIR- }
- PORT_WEB_UI=${PORT_WEB_UI- }
- LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- }
- KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
To facilitate interoperability, configuration variables can be prefixed with LOCALSTACK_ in docker. For instance, setting LOCALSTACK_SERVICES=s3 is equivalent to SERVICES=s3.
Alternatively, the infrastructure can be spun up on the local host machine (without using Docker) using the following command:
localstack start --host
(Note that this will require additional dependencies, and currently is not supported on some operating systems, including Windows.)
LocalStack will attempt to automatically fetch the missing dependencies when you first start it up in "host" mode; alternatively, you can use the full profile to install all dependencies at pip installation time:
pip install "localstack[full]"
You can pass the following environment variables to LocalStack:
SERVICES: Comma-separated list of service names and (optional) ports they should run on.
If no port is specified, a default port is used. Service names basically correspond to the
service names of the AWS CLI
(kinesis, lambda, sqs, etc), although LocalStack only supports a subset of them.
Example value: kinesis,lambda:4569,sqs:4570 to start Kinesis on the default port,
Lambda on port 4569, and SQS on port 4570. In addition, the following shorthand values can be
specified to run a predefined ensemble of services:
serverless: run services often used for Serverless apps (iam, lambda, dynamodb, apigateway, s3, sns)DEFAULT_REGION: AWS region to use when talking to the API (defaults to us-east-1).
HOSTNAME: Name of the host to expose the services internally (defaults to localhost).
Use this to customize the framework-internal communication, e.g., if services are
started in different containers using docker-compose.
HOSTNAME_EXTERNAL: Name of the host to expose the services externally (defaults to localhost).
This host is used, e.g., when returning queue URLs from the SQS service to the client.
<SERVICE>_PORT: Port number to bind a specific service to (defaults to service ports above).
<SERVICE>_PORT_EXTERNAL: Port number to expose a specific service externally (defaults to service ports above). SQS_PORT_EXTERNAL, for example, is used when returning queue URLs from the SQS service to the client.
USE_SSL: Whether to use https://... URLs with SSL encryption (defaults to false).
KINESIS_ERROR_PROBABILITY: Decimal value between 0.0 (default) and 1.0 to randomly
inject ProvisionedThroughputExceededException errors into Kinesis API responses.
KINESIS_SHARD_LIMIT: Integer value (defaults to 100) or Infinity (to disable), in which to kinesalite will start throwing exceptions to mimick the default shard limit.
KINESIS_LATENCY: Integer value (defaults to 500) or 0 (to disable), in which to kinesalite will delay returning a response in order to mimick latency from a live AWS call.
DYNAMODB_ERROR_PROBABILITY: Decimal value between 0.0 (default) and 1.0 to randomly
inject ProvisionedThroughputExceededException errors into DynamoDB API responses.
LAMBDA_EXECUTOR: Method to use for executing Lambda functions. Possible values are:
local: run Lambda functions in a temporary directory on the local machinedocker: run each function invocation in a separate Docker containerdocker-reuse: create one Docker container per function and reuse it across invocationsFor docker and docker-reuse, if LocalStack itself is started inside Docker, then
the docker command needs to be available inside the container (usually requires to run the
container in privileged mode). Default is docker, fallback to local if Docker is not available.
LAMBDA_REMOTE_DOCKER determines whether Lambda code is copied or mounted into containers.
Possible values are:
true (default): your Lambda function definitions will be passed to the container by
copying the zip file (potentially slower). It allows for remote execution, where the host
and the client are not on the same machine.false: your Lambda function definitions will be passed to the container by mounting a
volume (potentially faster). This requires to have the Docker client and the Docker
host on the same machine.LAMBDA_DOCKER_NETWORK: Optional Docker network for the container running your lambda function.
LAMBDA_CONTAINER_REGISTRY Use an alternative docker registry to pull lambda execution containers (default: lambci/lambda).
LAMBDA_REMOVE_CONTAINERS: Whether to remove containers after Lambdas finished executing (default: true).
DATA_DIR: Local directory for saving persistent data (currently only supported for these services:
Kinesis, DynamoDB, Elasticsearch, S3). Set it to /tmp/localstack/data to enable persistence
(/tmp/localstack is mounted into the Docker container), leave blank to disable
persistence (default).
PORT_WEB_UI: Port for the Web user interface (dashboard). Default is 8080.
<SERVICE>_BACKEND: Custom endpoint URL to use for a specific service, where <SERVICE> is the uppercase
service name (currently works for: APIGATEWAY, CLOUDFORMATION, DYNAMODB, ELASTICSEARCH,
KINESIS, S3, SNS, SQS). This allows to easily integrate third-party services into LocalStack.
FORCE_NONINTERACTIVE: when running with Docker, disables the --interactive and --tty flags. Useful when running headless.
DOCKER_FLAGS: Allows to pass custom flags (e.g., volume mounts) to "docker run" when running LocalStack in Docker.
DOCKER_CMD: Shell command used to run Docker containers, e.g., set to "sudo docker" to run as sudo (default: docker).
START_WEB: Flag to control whether the Web API should be started in Docker (values: 0/1; default: 1).
LAMBDA_FALLBACK_URL: Fallback URL to use when a non-existing Lambda is invoked. Either records invocations in DynamoDB (value dynamodb://<table_name>) or forwards invocations as a POST request (value http(s)://...).
EXTRA_CORS_ALLOWED_HEADERS: Comma-separated list of header names to be be added to Access-Control-Allow-Headers CORS header
EXTRA_CORS_EXPOSE_HEADERS: Comma-separated list of header names to be be added to Access-Control-Expose-Headers CORS header
LAMBDA_JAVA_OPTS: Allow passing custom JVM options (e.g., -Xmx512M) to Java Lambdas executed in Docker. Use _debug_port_ placeholder to configure the debug port (e.g., -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=_debug_port_).
Additionally, the following read-only environment variables are available:
LOCALSTACK_HOSTNAME: Name of the host where LocalStack services are available.
This is needed in order to access the services from within your Lambda functions
(e.g., to store an item to DynamoDB or S3 from Lambda).
The variable LOCALSTACK_HOSTNAME is available for both, local Lambda execution
(LAMBDA_EXECUTOR=local) and execution inside separate Docker containers (LAMBDA_EXECUTOR=docker).Each of the service APIs listed above defines
a backdoor API under the path /?_config_ which allows to dynamically update configuration variables
defined in config.py.
For example, to dynamically set KINESIS_ERROR_PROBABILITY=1 at runtime, use the following command:
curl -v -d '{"variable":"KINESIS_ERROR_PROBABILITY","value":1}' 'http://localhost:4568/?_config_'
When a container is started for the first time, it will execute files with extensions .sh that are found in /docker-entrypoint-initaws.d. Files will be executed in alphabetical order. You can easily create aws resources on localstack using awslocal (or aws) cli tool in the initialization scripts.
USE_SSL=1)If you need to use your own SSL Certificate and keep it persistent and not use the random automatic generated Certificate, you can place into the localstack temporary directory :
/tmp/localstack/
the three named files below :
server.test.pem
server.test.pem.crt
server.test.pem.keyserver.test.pem must contains your key file content, your certificate and chain certificate files contents (do a cat in this order)server.test.pem.crt must contains your certificate and chains files contents (do a 'cat' in this order)Typically with docker-compose you can add into docker-compose.yml this volume to the localstack services :
volumes:
- "${PWD}/ls_tmp:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
local directory ls_tmp must contains the three files (server.test.pem, server.test.pem.crt, server.test.pem.key)
You can point your aws CLI to use the local infrastructure, for example:
aws --endpoint-url=http://localhost:4568 kinesis list-streams
{
"StreamNames": []
}
NEW: Check out awslocal, a thin CLI wrapper
that runs commands directly against LocalStack (no need to specify --endpoint-url anymore).
Install it via pip install awscli-local, and then use it as follows:
awslocal kinesis list-streams
{
"StreamNames": []
}
UPDATE: Use the environment variable $LOCALSTACK_HOSTNAME to determine the target host
inside your Lambda function. See Configurations section for more details.
boto3 and use the endpoint_url parameter when creating a connectionIf you want to use LocalStack in your integration tests (e.g., nosetests), simply fire up the infrastructure in your test setup method and then clean up everything in your teardown method:
from localstack.services import infra
def setup():
infra.start_infra(asynchronous=True)
def teardown():
infra.stop_infra()
def my_app_test():
# here goes your test logic
See the example test file tests/integration/test_integration.py for more details.
You can use the serverless-localstack plugin to easily run Serverless applications on LocalStack.
For more information, please check out the plugin repository here:
https://github.com/localstack/serverless-localstack
You can use Terraform to provision your resources locally. Please refer to the Terraform AWS Provider docs here on how to configure the API endpoints on localhost.
In order to mount a local folder, ensure that LAMBDA_REMOTE_DOCKER is set to false then set the S3 bucket name to __local__ and the S3 key to your local path:
awslocal lambda create-function --function-name myLambda \
--code S3Bucket="__local__",S3Key="/my/local/lambda/folder" \
--handler index.myHandler \
--runtime nodejs8.10 \
--role whatever
In order to use LocalStack with Java, the project ships with a simple JUnit runner and a JUnit 5
extension. Take a look at the example JUnit tests in ext/java.
By default, the JUnit Test Runner starts LocalStack in a Docker container, for the duration of the test.
The container can be configured by using the @LocalstackDockerProperties annotation.
...
import cloud.localstack.LocalstackTestRunner;
import cloud.localstack.TestUtils;
import cloud.localstack.docker.annotation.LocalstackDockerProperties;
@RunWith(LocalstackTestRunner.class)
@LocalstackDockerProperties(services = { "s3", "sqs", "kinesis:77077" })
public class MyCloudAppTest {
@Test
public void testLocalS3API() {
AmazonS3 s3 = TestUtils.getClientS3()
List<Bucket> buckets = s3.listBuckets();
...
}
}
Or with JUnit 5 :
@ExtendWith(LocalstackExtension.class)
@LocalstackDockerProperties(...)
public class MyCloudAppTest {
...
}
The LocalStack JUnit test runner is published as an artifact in Maven Central.
Simply add the following dependency to your pom.xml file:
<dependency>
<groupId>cloud.localstack</groupId>
<artifactId>localstack-utils</artifactId>
<version>0.2.0</version>
</dependency>
You can configure the Docker behaviour using the @LocalstackDockerProperties annotation with the following parameters:
| property | usage | type | default value |
|---|---|---|---|
pullNewImage |
Determines if a new image is pulled from the docker repo before the tests are run. | boolean | false |
randomizePorts |
Determines if the container should expose the default local stack ports (4567-4583) or if it should expose randomized ports. | boolean | false |
services |
Determines which services should be run when the localstack starts. | String[] | All |
imageTag |
Use a specific image tag for docker container | String | latest |
hostNameResolver |
Used for determining the host name of the machine running the docker containers so that the containers can be addressed. | IHostNameResolver | localhost |
environmentVariableProvider |
Used for injecting environment variables into the container. | IEnvironmentVariableProvider | Empty Map |
useSingleDockerContainer |
Whether a singleton container should be used by all test classes. | boolean | false |
Note: When specifying the port in the services property, you cannot use randomizePorts = true
If you're using AWS Java libraries with Kinesis, please, refer to CBOR protocol issues with the Java SDK guide how to disable CBOR protocol which is not supported by kinesalite.
Accessing local S3 from Java: To avoid domain name resolution issues, you need to enable path style access on your client:
s3.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build());
// There is also an option to do this if you're using any of the client builder classes:
AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard();
builder.withPathStyleAccessEnabled(true);
...
Mounting the temp. directory: Note that on MacOS you may have to run TMPDIR=/private$TMPDIR docker-compose up if
$TMPDIR contains a symbolic link that cannot be mounted by Docker.
(See details here: https://bitbucket.org/atlassian/localstack/issues/40/getting-mounts-failed-on-docker-compose-up)
If you run into file permission issues on pip install under Mac OS (e.g., Permission denied: '/Library/Python/2.7/site-packages/six.py'), then you may have to re-install pip via Homebrew (see this discussion thread). Alternatively, try installing
with the --user flag: pip install --user localstack
If you are deploying within OpenShift, please be aware: the pod must run as root, and the user must have capabilities added to the running pod, in order to allow Elasticsearch to be run as the non-root localstack user.
The environment variable no_proxy is rewritten by LocalStack.
(Internal requests will go straight via localhost, bypassing any proxy configuration).
For troubleshooting LocalStack start issues, you can check debug logs by running DEBUG=1 localstack start
In case you get errors related to node/nodejs, you may find (this issue comment: https://github.com/localstack/localstack/issues/227#issuecomment-319938530) helpful.
If you are using AWS Java libraries and need to disable SSL certificate checking, add -Dcom.amazonaws.sdk.disableCertChecking to the java invocation.
To develop new features, or to start the stack locally (outside of Docker), the following additional tools are required:
makenpm (node.js package manager)java/javac (Java 8 runtime environment and compiler)mvn (Maven, the build system for Java)If you pull the repo in order to extend/modify LocalStack, run this command to install all the dependencies:
make install
This will install the required pip dependencies in a local Python virtualenv directory
.venv (your global python packages will remain untouched), as well as some node modules
in ./localstack/node_modules/. Depending on your system, some pip/npm modules may require
additional native libs installed.
The Makefile contains a target to conveniently run the local infrastructure for development:
make infra
Check out the developer guide which contains a few instructions on how to get started with developing (and debugging) features for LocalStack.
The project contains a set of unit and integration tests that can be kicked off via a make target:
make test
The projects also comes with a simple Web dashboard that allows to view the deployed AWS components and the relationship between them.
localstack web
LAMBDA_REMOVE_CONTAINERS config; bump moto to latest version; fix LocationConstraint markup in S3 responses; fix success_action_status for S3 POST Object; add UUIDs to CW events; update SSL certificate to new requirements in MacOS Catalina; fix Docker port mapping for JUnit test runner; add test for CW logs multi-byte message; fix S3 bucket name validation, auto-convert uppercase characters in bucket names; fix CF deployment of step functions; fix DOCKER_HOST_FROM_CONTAINER config for local exec; fix object ACLs for multipart uploads; add initial support for Kinesis stream consumers; enhance proxy to transparently accept both HTTP/HTTPS on the same port; support TemplateURL for CF ValidateTemplate; support Marker for S3 ListObjects; fix passing of metadata on S3 presigned URL put; allow trailing slashes in Elasticsearch API; refactor Java libs, make Docker the default JUnit executor; update ElasticMQ version; add initial support for KMS via local-kms; fix Terraform deployment for Lambdas; fix stack name in CloudFormation resource names; fix S3 bucket name checks for domain based addressing; add locking for SSL cert creation; support JARs in lib/ folder for Java lambdas; disable SSL verification for CF template URLs; add S3 website ErrorDocument emulation; fix return type of Lambda GetPolicy; fix API Gateway authorizer implementation; fix permission issue for cert files; fix non-JSON content types for API Gateway; fix DynamoDB error for Put on non-existing table; fix notification triggers on S3 presigned URL upload; add CloudFormation support for deployment of SAM resources; fix SNS FilterPolicy configuration; add kinesis/ListStreams API Gateway integrationingest-geoip ES module to optimize image size; skip checking MD5 on S3 copy; fix DynamoDB table ARN for CF; fix CF deployment of StepFunction activities; fix uploading of Java Lambda as JAR in ZIP; fix installing libs for plugins; added LAMBDA_JAVA_OPTS for Java Lambda debugging; bump Maven dependency versions; refactor Lambda API; fix boolean strings in CF templates; allow overriding AWS account id with TEST_AWS_ACCOUNT_ID; fix incorrect region for API GW resources created via CF; fix permissions for cache files in /tmpRef in CloudFormation; fix ddb streams uuid generation; upgrade travis CI setup; fix DynamoDB error messages; cache server processes@LocalstackDockerProperties; add basic EC2 support; upgrade to ElasticSearch 6.7; set Last-Modified header in S3; preserve logic with uppercase event keys in Java; add support for nodejs 10.x Lambdas@Nested in Junit5; add support for batch/transaction in DynamoDB; fix output buffering for subprocesses; assign unique ports under docker-reuse; check if topic ARN exists before publishLOCALSTACK_ prefix in Docker environment variables; enable request forwarding for non-existing Lambdas; fix large downloads for S3; add API endpoint for dynamically updating config variables; fix CloudFormation stack updatedocker-entrypoint-initaws.d dir for initializing resources; add S3Event Parser for Lambda; fix S3 chunk encoding; fix S3 multipart upload notification; add dotnetcore2.1 and ruby2.5 Lambda runtimes; fix issues with JDK 9; install ES plugins available in AWSES_JAVA_OPTS; fix SQS CORS preflight response; fix S3 content md5 checks and Host header; fix ES startup issue; Bump elasticmq to 0.13.10; bump kinesalite versionpipenv dependency issue; Docker JUnit test runner; POJO type for Java Lambda RequestHandler; Java Lambda DynamoDB event; reuse Docker containers for Lambda invocations; API Gateway wildcard path segments; fix SNS RawMessageDeliverydocker.for.mac.localhost to connect to LocalStack from Docker on Mac; fix b64 encoding for Java Lambdas; fix path of moto_server commandGenericProxyHandler; add $PORT_WEB_UI and $HOSTNAME_EXTERNAL configs; API Gateway path parameters; enable flake8 linting; add config for service backend URLs; use ElasticMQ instead of moto for SQS; expose $LOCALSTACK_HOSTNAME; custom environment variable support for Lambda; improve error logging and installation for Java/JUnit; add support for S3 REST Object POSTUSE_SSL config); create Docker base image; fix issue with DATA_DIRWe welcome feedback, bug reports, and pull requests!
For pull requests, please stick to the following guidelines:
Please note that by contributing any code or documentation to this repository (by raising pull requests, or otherwise) you explicitly agree to the Contributor License Agreement.
This project exists thanks to all the people who contribute.
Thank you to all our backers!
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
Copyright (c) 2017-2019 LocalStack maintainers and contributors.
Copyright (c) 2016 Atlassian and others.
This version of LocalStack is released under the Apache License, Version 2.0 (see LICENSE.txt). By downloading and using this software you agree to the End-User License Agreement (EULA).
We build on a number of third-party software tools, including the following:
| Third-Party software | License |
|---|---|
| Python/pip modules: | |
| airspeed | BSD License |
| amazon_kclpy | Amazon Software License |
| boto3 | Apache License 2.0 |
| coverage | Apache License 2.0 |
| docopt | MIT License |
| elasticsearch | Apache License 2.0 |
| flask | BSD License |
| flask_swagger | MIT License |
| jsonpath-rw | Apache License 2.0 |
| moto | Apache License 2.0 |
| requests | Apache License 2.0 |
| subprocess32 | PSF License |
| Node.js/npm modules: | |
| kinesalite | MIT License |
| Other tools: | |
| Elasticsearch | Apache License 2.0 |
| local-kms | MIT License |