Question:
I use Localstack with Testcontainers((testcontainers:localstack:1.15.2 )) for integration tests and set up the secret in the test setup like this:
Code sample
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import com.amazonaws.services.secretsmanager.AWSSecretsManager; import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder; import com.amazonaws.services.secretsmanager.model.CreateSecretRequest; import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.localstack.LocalStackContainer; import org.testcontainers.utility.DockerImageName; import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SECRETSMANAGER; public class QueueServiceTest { DockerImageName localstackImage = DockerImageName.parse("localstack/localstack:0.11.3"); @Rule public LocalStackContainer localstack = new LocalStackContainer(localstackImage) .withServices(SECRETSMANAGER).withEnv("LOCALSTACK_HOSTNAME", "localhost").withEnv("HOSTNAME", "localhost"); @Test public void someTestMethod() { AWSSecretsManager secretsManager = AWSSecretsManagerClientBuilder.standard() .withCredentials(localstack.getDefaultCredentialsProvider()).withRegion(localstack.getRegion()) .build(); String secretString = "usrnme"; CreateSecretRequest request = new CreateSecretRequest().withName("test") .withSecretString(secretString) .withRequestCredentialsProvider(localstack.getDefaultCredentialsProvider()); secretsManager.createSecret(request); } } |
Now the test crashes with an error:
com.amazonaws.services.secretsmanager.model.AWSSecretsManagerException:
The security token included in the request is invalid. (Service:
AWSSecretsManager; Status Code: 400; Error Code:
UnrecognizedClientException; Request ID:
314b0dee-69ed-4b08-9cd0-2618b8e14b25; Proxy: null)at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at
com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at
com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at
com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at
com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.doInvoke(AWSSecretsManagerClient.java:2625)
at
com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.invoke(AWSSecretsManagerClient.java:2594)
at
com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.invoke(AWSSecretsManagerClient.java:2583)
at
com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.executeCreateSecret(AWSSecretsManagerClient.java:557)
at
com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.createSecret(AWSSecretsManagerClient.java:528)
I think I am missing some parameters, could anyone please helo me figure it out.
Answer:
The endpoint configuration for the AWSSecretsManagerClientBuilder
is missing. Right now your client targets the real AWS endpoint, e.g.: https://secretsmanager.us-east-1.amazonaws.com:443
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class LocalStackSecretsManagerTest { DockerImageName localstackImage = DockerImageName.parse("localstack/localstack:0.11.3"); @Rule public LocalStackContainer localstack = new LocalStackContainer(localstackImage) .withServices(SECRETSMANAGER) .withEnv("LOCALSTACK_HOSTNAME", "localhost") .withEnv("HOSTNAME", "localhost"); @Test void someTestMethod() { AWSSecretsManager secretsManager = AWSSecretsManagerClientBuilder.standard() .withCredentials(localstack.getDefaultCredentialsProvider()) .withEndpointConfiguration(localstack.getEndpointConfiguration(SECRETSMANAGER)) // this is the important line .build(); String secretString = "usrnme"; CreateSecretRequest request = new CreateSecretRequest() .withName("test") .withSecretString(secretString); secretsManager.createSecret(request); } } |
When specifying the endpoint, you can remove the region configuration.
The additional .withRequestCredentialsProvider(localstack.getDefaultCredentialsProvider());
on CreateSecretRequest
is redundant and only required if you want to override the credentials provider per CreateSecretRequest
.