I am building a rest service in .NET Core 6 in Visual Studio 2022. This service is using dynamodb for its database. I am running both of these inside Docker with a single docker-compose file.
If I startup dynamodb-local in it's own docker-compose file like this
version: '3.4'
services:
dynamodb-local:
image: amazon/dynamodb-local:latest
container_name: dynamodb-local
command: "-jar DynamoDBLocal.jar -sharedDb"
ports:
- "8000:8000"
I configure the client in the Program.cs like this
var clientConfig = new AmazonDynamoDBConfig {ServiceURL = "http://localhost:8000" };
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(clientConfig));
If I run the service from IIS Express, everything works perfectly.
However, I enabled containerization for the project and want to run everything together inside docker. When I do this my, my docker-compose looks like this:
version: '3.4'
services:
dynamodb-local:
image: amazon/dynamodb-local:latest
container_name: dynamodb-local
command: "-jar DynamoDBLocal.jar -sharedDb"
ports:
- "8000:8000"
api:
image: ${DOCKER_REGISTRY-}api
container_name: insurance-service
build:
context: .
dockerfile: src/Api/Dockerfile
depends_on:
- dynamodb-local
Then my docker-compose-override.yml
looks like this (this was generated by VS):
version: '3.4'
services:
api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- "80"
- "443"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
When I start this up using docker-compose inside VS 2022, everything loads up fine. But when I go to save a record to the database this error is thrown:
Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.
It's like the client registering is trying to access localhost:8000
but there seems to be nothing there so it defaults back to EC2 IAM Security Creds. I think this is being caused by some weird networking between the 2 services that I don't realize. Like API can't access dynamodb-local with referencing localhost.
Edit: I have also tried throwing arbitrary basic creds in there like this:
var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "http://localhost:8000" };
var creds = new BasicAWSCredentials("xxx", "xxx");
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));
This doesn't give me the IAM issue but keeps trying in an infinite loop like it's waiting for localhost to become available and it isn't.
Why don't you try using networking between containers? You can create a network and then access the DynamoDB using the container name, this way the DynamoDB container is accessible internally.
version: '3.4'
services:
dynamodb-local:
image: amazon/dynamodb-local:latest
container_name: dynamodb-local
command: "-jar DynamoDBLocal.jar -sharedDb"
ports:
- "8000:8000"
api:
image: ${DOCKER_REGISTRY-}api
container_name: insurance-service
build:
context: .
dockerfile: src/Api/Dockerfile
depends_on:
- dynamodb-local
networks:
default:
external:
name: dynamodb-api
And your can replace the URL with the container name like this:
var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "dynamodb-local" };
var creds = new BasicAWSCredentials("xxx", "xxx");
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));
You will also have to create a docker network with this command
docker network create dynamodb-api
Hope this helps!