1. Introduction

Gradle plugin for setting up mock AWS endpoints during test and development using LocalStack.

This plugin provides a number of helpful tasks for simplifying the creation of AWS resources for use in testing and development, as well as tasks for easily integrating Spring Boot with LocalStack, using simple Gradle DSL.

For detailed information on getting started with this plugin and how to configure specific AWS services, please refer to the documentation below.

This plugin requires Gradle >= 5.2 to work properly.

1.1. Getting Started

The plugin can be applied with the buildscript syntax or the plugin DSL.

1.1.1. Applying the Plugin using the Buildscript Syntax

Groovy
buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.nike.pdm.localstack:1.0.0'
    }
}

apply plugin: 'com.nike.pdm.localstack'

1.1.2. Applying the Plugin using the Plugin DSL

Groovy
plugins {
    id "com.nike.pdm.localstack"    version "1.0.0"
}

No other configuration is necessary at this point. If you wish to override any of the configuration options you can through the localstack extension detailed below.

2. Configuration

The plugin provides an extension with the namespace localstack. The following properties can be configured:

Property Name Type Default Value Description

workingDir

Property<File>

Working directory of docker-compose plugin if defined or localstack directory in project root.

The directory where the .localstack directory will be located at runtime.

host

Property<String>

localhost

Hostname of the LocalStack Docker container.

port

Property<Integer>

4566

Port number of the LocalStack Edge Service exposed by the Docker container.

signingRegion

Property<String>

us-east-1

AWS region of the LocalStack environment.

An example configuration can be seen below:

Groovy
localstack {
    workingDir = file('/localstack')
    host = 'localhost'
    port = 4566
    signingRegion = 'us-east-1'
}

3. LocalStack

The plugin provides a set of tasks for easily starting and stopping the LocalStack environment in your project.

3.1. Tasks

The plugin applies default tasks, which can be executed from the Gradle command line:

Task Name Type Usage Description

initLocalStack

Default

./gradlew initLocalStack

Initializes the project with a default LocalStack Docker Compose configuration.

startLocalStack

Default

./gradlew startLocalStack

Starts the LocalStack environment and executes any of the AWS services tasks that are found in the project.

stopLocalStack

Default

./gradlew stopLocalStack

Stops the LocalStack environment and preserves the .localstack data directory.

killLocalStack

Default

./gradlew killLocalStack

Stops the LocalStack environment and deletes the .localstack data directory.

cleanLocalStack

Default

./gradlew cleanLocalStack

Deletes the .localstack data directory.

restartLocalStack

Default

./gradlew restartLocalStack

Restarts running LocalStack environment with clean .localstack directory.

The plugin also provides tasks that make working with the mock AWS endpoints in LocalStack easy. Currently, the plugin supports the following AWS services:

For more information on how to configure and use these tasks, see the documentation for each AWS service below.

4. CloudFormation

This plugin provides a set of tasks for working with AWS CloudFormation in your project.

CloudFormation support in LocalStack is incomplete and may not work for your use case. Please consult the LocalStack website for CloudFormation support issues.

4.1. Tasks

The plugin provides both default and custom tasks.

Task Task Name Type Description

CreateCFStackTask

createCFStack

Custom

Creates a CloudFormation Stack

DeleteCFStackTask

deleteCFStack

Default

Deletes a CloudFormation Stack

ListCFStacksTask

listCFStacks

Default

Lists all CloudFormation Stacks

4.2. Examples

Example configurations for the CloudFormation tasks. For information on all available task properties please refer to the Javadocs.

4.2.1. Create Stack

Groovy
task createAppStack(type: CreateCFStackTask) {
    stackName = 'catalog-products-v1'
    cfTemplate = file("cloudformation/catalog-products-resources-v1.yml")
}

4.2.2. Delete Stack

Groovy
./gradlew deleteCFStack --stackName=catalog-products-v1

4.2.3. List Stacks

Groovy
./gradlew listCFStacks

5. DynamoDB

This plugin provides a set of tasks for working with AWS DynamoDB in your project.

5.1. Tasks

The plugin provides both default and custom tasks.

Task Task Name Type Description

CreateDynamoDbTableTask

createDynamoDbTable

Custom

Creates a DynamoDB Table

DeleteDynamoDbTableTask

deleteDynamoDbTable

Default

Deletes a DynamoDB Table

ListDynamoDbTablesTask

listDynamoDbTables

Default

Lists all DynamoDB Tables

5.2. Table Initializer

The plugin not only supports creating DynamoDB tables, but also populating them with data through the use of a Table Initializer.

5.2.1. Create Initializer

In order to create a Table Initializer, create a class on the build classpath (this is most easily done by creating the class in the Gradle buildSrc directory) that implements the following rules:

  1. Constructor that takes an AmazonDynamoDB client as a single argument.

  2. Implements a void run method with no arguments.

Java
package example.buildsrc.dynamodb;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import org.apache.commons.lang3.StringUtils;

/**
 * Loads test products into the localstack dynamodb "catalog.products" table.
 */
public class ProductTableInitializer {

    private final DynamoDBMapper mapper;

    /**
     * Creates an instance of {@link ProductTableInitializer}.
     *
     * The LocalStack Gradle plugin requires a constructor that accepts the dynamodb client
     * as a single argument.
     *
     * @param dynamoClient
     */
    public ProductTableInitializer(AmazonDynamoDB dynamoClient) {
        this.mapper = new DynamoDBMapper(dynamoClient);
    }

    /**
     * Initializes the table.
     *
     * The LocalStack Gradle plugin requires a single void method named "run" that does not
     * accept any arguments.
     */
    public void run() {
        for (int i = 0; i < 10; i++) {
            final Product product = new Product();
            product.setId(StringUtils.leftPad(Integer.toString(i), 5, "0"));
            product.setName(String.format("Widget-%s", i));
            product.setDescription(String.format("Description for Widget-%s", i));
            product.setActive(true);
            product.setCreatedAt(System.currentTimeMillis());

            mapper.save(product);
        }
    }

    /**
     * Product record to load into dynamo table.
     */
    @DynamoDBTable(tableName = "catalog.products")
    public static class Product {

        @DynamoDBHashKey
        private String id;

        private String name;
        private String description;
        private boolean active;
        private long createdAt;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public boolean isActive() {
            return active;
        }

        public void setActive(boolean active) {
            this.active = active;
        }

        public long getCreatedAt() {
            return createdAt;
        }

        public void setCreatedAt(long createdAt) {
            this.createdAt = createdAt;
        }
    }
}

5.2.2. Configure Initializer

Table Initializers, once created, can be configured on a CreateDynamoDbTableTask as follows:

Groovy
task setupLocalTable(type: CreateDynamoDbTableTask) {
    tableName = 'catalog.products'
    keySchema = [
            new KeySchemaElement("id", KeyType.HASH)
    ]
    attributeDefinitions = [
            new AttributeDefinition("id", ScalarAttributeType.S)
    ]
    initializer = 'example.buildsrc.dynamodb.ProductTableInitializer'
}

5.3. Examples

Example configurations for the DynamoDB tasks. For information on all available task properties please refer to the Javadocs.

5.3.1. Create Table

Groovy
task setupLocalTable(type: CreateDynamoDbTableTask) {
    tableName = 'catalog.products'
    keySchema = [
            new KeySchemaElement("id", KeyType.HASH)
    ]
    attributeDefinitions = [
            new AttributeDefinition("id", ScalarAttributeType.S)
    ]
}

5.3.2. Delete Table

Bash
./gradlew deleteDynamoDbTable --tableName=catalog.products

5.3.3. List Tables

Bash
./gradlew listDynamoDbTables

6. S3

This plugin provides a set of tasks for working with AWS S3 in your project.

6.1. Tasks

The plugin provides both default and custom tasks.

Task Task Name Type Description

CreateS3BucketsTask

createS3Buckets

Custom

Creates S3 Buckets

DeleteS3BucketsTask

deleteS3Buckets

Default

Deletes S3 Buckets

ListS3BucketsTask

listS3Buckets

Default

Lists all S3 Buckets

PurgeS3BucketsTask

purgeS3Buckets

Default

Purges Objects from S3 Buckets

6.2. Examples

Example configurations for the S3 tasks. For information on all available task properties please refer to the Javadocs.

6.2.1. Create Buckets

Groovy
task setupS3Bucket(type: CreateS3BucketsTask) {
    buckets = [ 'catalog-product-bucket' ]
}

6.2.2. Delete Buckets

Groovy
./gradlew deleteS3Buckets --buckets=bucket1,bucket2

6.2.3. List Buckets

Groovy
./gradlew listS3Buckets

6.2.4. Purge Buckets

Groovy
./gradlew deleteS3Buckets --buckets=bucket1,bucket2

7. SQS

This plugin provides a set of tasks for working with AWS SQS in your project.

7.1. Tasks

The plugin provides both default and custom tasks.

Task Task Name Type Description

CreateSqsQueuesTask

createSqsQueues

Custom

Creates SQS Queues

CreateSqsQueueWithDlqTask

createSqsQueueWithDlq

Custom

Creates an SQS Queue with Attached Deadletter Queue

ListSqsQueuesTask

listSqsQueues

Default

Lists all SQS Queues

PublishSqsTask

publishSqs

Default

Publishes Messages to SQS

PurgeSqsQueuesTask

purgeSqsQueues

Default

Purges Messages on SQS Queues

7.2. Examples

Example configurations for the SQS tasks. For information on all available task properties please refer to the Javadocs.

7.2.1. Create Queues

Groovy
task setupLocalQueue(type: CreateSqsQueuesTask) {
    queueNames = [ 'catalog-product-change-notification' ]
    queueAttributes = [
            VisibilityTimeout: '10'
    ]
}

7.2.2. Create Queue with DLQ

Groovy
task setupLocalQueue(type: CreateSqsQueueWithDlqTask) {
    queueName = 'catalog-product-change-notification'
}

7.2.3. List Queues

Bash
./gradlew listSqsQueues

7.2.4. Publish

Bash
./gradlew publishSqs --queueNames="queue1,queue2" --messages="{path to message file, directory, or archive}"

7.2.5. Purge Queues

Bash
./gradlew purgeSqsQueues --queueNames=queue1,queue2

8. SNS

This plugin provides a set of tasks for working with AWS SNS in your project.

8.1. Tasks

The plugin provides both default and custom tasks.

Task Task Name Type Description

CreateSnsTopicWithSqsEndpoint

createSnsTopicWithSqsEndpoint

Custom

Creates SNS Topic

DeleteSnsTopicTask

deleteSnsTopic

Default

Deletes an SNS Topic

ListSnsTopicsTask

listSnsTopics

Default

Lists all SNS Topics

ListSnsTopicSubscriptionsTask

listSnsTopicSubscriptions

Default

Lists all Subscriptions on SNS Topic

8.2. Examples

Example configurations for the SNS tasks. For information on all available task properties please refer to the Javadocs.

8.2.1. Create Topic with SQS Endpoint

Groovy
task setupLocalTopic(type: CreateSnsTopicWithSqsEndpointTask) {
    topicName = 'catalog-product-drops'
}

8.2.2. Delete Topic

Bash
./gradlew deleteSnsTopic --topicName=catalog-product-drops

8.2.3. List Topics

Bash
./gradlew listSnsTopics

8.2.4. List Topic Subscriptions

Bash
./gradlew listSnsTopicSubscriptions --topicName=catalog-product-drops

9. Spring Boot

This plugin is designed to work seamlessly with Spring Boot. When the Spring Boot plugin is detected within the project this plugin will automatically add tasks that make developing and debugging your Spring Boot application within LocalStack seamless.

9.1. Tasks

The plugin applies default tasks, which can be executed from the Gradle command line:

Task Name Type Usage Description

bootRunLocal

Default

./gradlew bootRunLocal

Starts LocalStack, configures the defined LocalStack environment, and then starts the Spring Boot application.

bootRunLocalDebug

Default

./gradlew bootRunLocalDebug

Starts LocalStack, configures the defined LocalStack environment, and then starts the Spring Boot application in remote debug mode (waits for a debugger to be attached).

9.2. Configuration

The plugin provides a nested extension with the namespace springboot. The following properties can be configured:

Property Name Type Default Value Description

enabled

Property<Boolean>

true

Enables auto-configuration of the bootRunLocal and bootRunLocalDebug tasks.

debugPort

Property<Integer>

5055

Debug port for bootRunLocalDebug task.

profiles

Property<List<String>

[ 'local' ]

List of Spring Profiles with which to start the application.

jvmArgs

Property<List<String>

[]

List of JVM args with which to start the application.

An example configuration can be seen below:

Groovy
localstack {

    // ... LocalStack configuration

    springboot {
        enabled = true
        debugPort = 5055
        profiles = [ 'local' ]
        jvmArgs = [ '-Dlog4j.configurationFile=log4j2-local.xml' ]
    }
}