Special Configurations
4 minute read
Introduction
LocalStack allows users to inject intentional errors, particularly in Kinesis and DynamoDB. You can introduce controlled chaos into your development environment enhance to enhance service resilience. By configuring environment variables, you can simulate disruptions. This simple setup helps improve the response mechanisms of these key AWS services, ensuring robust architecture under challenging conditions with minimal initial configuration.
This guide demonstrates the DYNAMODB_ERROR_PROBABILITY
and KINESIS_ERROR_PROBABILITY
configuration flags. The guide assumes basic knowledge of the AWS CLI and our awslocal
wrapper script.
Kinesis Error Probability
The KINESIS_ERROR_PROBABILITY
setting allows users to introduce ProvisionedThroughputExceededException
errors randomly into Kinesis API responses. The value for this setting ranges from 0.0 (default) to 1.0.
To demonstrate, set up LocalStack with KINESIS_ERROR_PROBABILITY
at 0.5, indicating a 50% chance of receiving a ProvisionedThroughputExceededException
from Kinesis.
$ KINESIS_ERROR_PROBABILITY=0.5 localstack start
Next, create a Kinesis stream using the AWS CLI with the CreateStream
API. For example, to create a stream named “ProductsStream” with one shard, use:
$ awslocal kinesis create-stream \
--stream-name ProductsStream \
--shard-count 1
Assuming you have a product JSON converted into a Base64-encoded string, you can add this record to the stream like so:
$ awslocal kinesis put-record \
--stream-name ProductsStream \
--partition-key "12345" \
--data "eyJwcm9kdWN0SWQiOiIxMjMiLCJwcm9kdWN0TmFtZSI6IlN1cGVyV2lkZ2V0IiwicHJvZHVjdFByaWNlIjoiMTk5Ljk5In0="
After performing similar operations repeatedly, you can check the logs to verify that the configuration is working as intended. Remember, records will only be added during successful calls.
2023-11-09T23:33:49.867 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.CreateStream => 200
2023-11-09T23:34:01.003 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 200
2023-11-09T23:34:05.114 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 200
2023-11-09T23:34:08.178 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:34:08.346 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 200
2023-11-09T23:34:09.726 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:34:10.499 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 200
2023-11-09T23:34:11.982 INFO --- [ asgi_gw_0] localstack.request.aws : AWS kinesis.PutRecord => 200
DynamoDB Error Probability
The DYNAMODB_ERROR_PROBABILITY
setting, similar to the Kinesis configuration, allows for random ProvisionedThroughputExceededException
responses from the DynamoDB service. It also accepts a decimal value between 0.0 (default) and 1.0.
To start LocalStack with a high error probability for DynamoDB, set DYNAMODB_ERROR_PROBABILITY
to 0.8:
$ DYNAMODB_ERROR_PROBABILITY=0.8 localstack start
Next, create a DynamoDB table using the AWS CLI with the CreateTable
API. For example, to create a table named “Products” with a primary key of “ProductId”, use:
$ awslocal dynamodb create-table \
--table-name Products \
--attribute-definitions AttributeName=ProductId,AttributeType=S \
--key-schema AttributeName=ProductId,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
You can add items to the table using the PutItem
API. For example, to add a product with an ID of “123”, a name of “SuperWidget”, and a price of “199.99”, use:
awslocal dynamodb put-item \
--table-name Products \
--item '{
"ProductId": {"S": "123"},
"ProductName": {"S": "SuperWidget"},
"ProductPrice": {"N": "199.99"}
}'
The logs will now show a higher frequency of ProvisionedThroughputExceededException
errors, followed by successful attempts due to the boto3
retry mechanism:
2023-11-09T23:59:12.836 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.CreateTable => 200
2023-11-09T23:59:27.889 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:27.968 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:28.089 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:28.410 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 200
2023-11-09T23:59:35.845 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:35.911 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:36.028 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:36.249 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:36.673 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:37.484 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:39.101 INFO --- [ asgi_gw_0] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:42.326 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-09T23:59:48.737 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 400 (ProvisionedThroughputExceededException)
2023-11-10T00:00:01.606 INFO --- [ asgi_gw_1] localstack.request.aws : AWS dynamodb.PutItem => 200
Despite these errors, the retry mechanism ensures that all items are eventually added to the DynamoDB table.