Skip to content

LocalStack Module

Testcontainers module for LocalStack, 'a fully functional local AWS cloud stack', to develop and test your cloud and serverless apps without actually using the cloud.

Usage example

Running LocalStack as a stand-in for AWS S3 during a test:

DockerImageName localstackImage = DockerImageName.parse("localstack/localstack:0.11.3");

@Rule
public LocalStackContainer localstack = new LocalStackContainer(localstackImage)
        .withServices(S3);

Creating a client using AWS SDK

AmazonS3 s3 = AmazonS3ClientBuilder
    .standard()
    .withEndpointConfiguration(
        new AwsClientBuilder.EndpointConfiguration(
            localstack.getEndpoint().toString(),
            localstack.getRegion()
        )
    )
    .withCredentials(
        new AWSStaticCredentialsProvider(
            new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey())
        )
    )
    .build();
S3Client s3 = S3Client
    .builder()
    .endpointOverride(localstack.getEndpoint())
    .credentialsProvider(
        StaticCredentialsProvider.create(
            AwsBasicCredentials.create(localstack.getAccessKey(), localstack.getSecretKey())
        )
    )
    .region(Region.of(localstack.getRegion()))
    .build();

Environment variables listed in Localstack's README may be used to customize Localstack's configuration. Use the .withEnv(key, value) method on LocalStackContainer to apply configuration settings.

HOSTNAME_EXTERNAL and hostname-sensitive services

Some Localstack APIs, such as SQS, require the container to be aware of the hostname that it is accessible on - for example, for construction of queue URLs in responses.

Testcontainers will inform Localstack of the best hostname automatically, using the HOSTNAME_EXTERNAL environment variable:

  • when running the Localstack container directly without a custom network defined, it is expected that all calls to the container will be from the test host. As such, the container address will be used (typically localhost or the address where the Docker daemon is running).

    @ClassRule
    public static LocalStackContainer localstack = new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE)
        .withServices(
            Service.S3,
            Service.SQS,
            Service.CLOUDWATCHLOGS,
            Service.KMS,
            LocalStackContainer.EnabledService.named("events")
        );
    
  • when running the Localstack container with a custom network defined, it is expected that all calls to the container will be from other containers on that network. HOSTNAME_EXTERNAL will be set to the last network alias that has been configured for the Localstack container.

    private static Network network = Network.newNetwork();
    
    @ClassRule
    public static LocalStackContainer localstackInDockerNetwork = new LocalStackContainer(
        LocalstackTestImages.LOCALSTACK_IMAGE
    )
        .withNetwork(network)
        .withNetworkAliases("notthis", "localstack") // the last alias is used for HOSTNAME_EXTERNAL
        .withServices(Service.S3, Service.SQS, Service.CLOUDWATCHLOGS);
    
  • Other usage scenarios, such as where the Localstack container is used from both the test host and containers on a custom network are not automatically supported. If you have this use case, you should set HOSTNAME_EXTERNAL manually.

Adding this module to your project dependencies

Add the following dependency to your pom.xml/build.gradle file:

testImplementation "org.testcontainers:localstack:1.19.7"
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>localstack</artifactId>
    <version>1.19.7</version>
    <scope>test</scope>
</dependency>