Redirect default AWD sdks endpoint to mock local endpoints
I have several Java spring boot services (about 20 of them) using Amazon SDK for S3, SQS, DynamoDB, etc.
Currently, I only need to provide my AWS key and secret to use the Amazon web service.
ACCESS_AWS_KEY=<MY_KEY>
ACCESS_AWS_SECRET=<MY_SECRET>
However, I wanted to set up a standalone development environment, so I started to dockerize my services and set up one multi-docker container with all my services connected and localstack should be used instead of a remote AWS service to allow full offline development.
docker-compose.yml looks something like this:
version: '3'
services:
service_1:
build: ./repos/service_1
links:
- service_2:
- localstack
service_2:
build: ./repos/service_2
links:
- localstack
service_3:
build: ./repos/service_3
links:
- localstack
localstack:
image: localstack/localstack
Amazon SDK provides an AWS_REGION env variable, but not an endpoint environment variable that I can easily use across all services.
I also don't want to make code changes in my services to accommodate a new endpoint other than the default.
I want a generic solution to send requests like this:
dynamodb.eu-west-1.amazonaws.com => localstack_1:4569
s3-eu-west-1.amazonaws.com => localstack_1:4572
where localstack_1 is a linked docker container with local stack and available to other containers.
I came across extra_hosts: in docker-compose, but it only redirects to IPs and has no host permission.
Also note that I have dozens of ports open on the local stack from 4569 to 4582.
I was thinking about running a script on every machine that configured a vhost in some way, or forwarding all outgoing connections from all containers to a centralized forwarder, but have no idea where to start.
This will only be used as a standalone development environment and will not receive any real traffic.
source to share
Ok, I was able to finally find a solution for this. I needed to go through my local codebase to find a solution. A couple of quick things:
- Localstack is not integrated with IAM. Therefore, it simply ignores the secret key or password.
- If you are using IAM, now you need to have a flag to override the endpoint. You can probably have a flag indicating localstack mode.
A couple of classes I've found helpful if you're debugging issues:
https://github.com/atlassian/localstack/blob/master/localstack/ext/java/src/test/java/com/atlassian/localstack/SQSMessagingTest.java https://github.com/atlassian/localstack/blob/master/localstack/ext/java/src/test/java/com/atlassian/localstack/TestUtils.java
Now for the solution:
AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration("http://localhost:4576/", awsRegion.getName());
AmazonSQSClient client = (AmazonSQSClient) AmazonSQSClientBuilder.standard()
.withCredentials(configuration.getSqsConfiguration().getCredentialsProvider())
.withEndpointConfiguration(endpoint)
.build();
Here http: // localhost: 4576 / where localstacks runs SQS. Don't miss the trailing slash. To use this in camel route is the same as using AWS resources. Hope this helps!
source to share