How to connect with DynamoDB using WebIdentityTokenFileCredentialsProvider

Viewed 622

I have the access key, secret key, region and DynamoDB endpoint through which I am able to connect to the database and I have kept the configurations in the application.properties file. Now the requirement is to not to keep the access key and secret keys in the application.properties file and follow the Web identity token from AWS STS. I have removed the access key and secret from the application.properties file and have the below configurations. When I start the application I am getting the below message

Consider defining a bean of type 'com.amazonaws.services.dynamodbv2.AmazonDynamoDB' in your configuration.

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.DefaultTableNameResolver;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.TableNameOverride;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverterFactory;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.WebIdentityTokenFileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

@Configuration
@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "dynamoDBMapperConfig", basePackages = "com.xyz.repository")
public class DynamoDBConfiguration {

  @Value("${aws.dynamodb.endpoint}")
  private String endpoint;

  @Value("${aws.region}")
  private String region;

  @Value("${aws.dynamodb.table.name}")
  private String tableName;

  @Bean
  public DynamoDBMapperConfig dynamoDBMapperConfig(TableNameOverride tableNameOverrider) {
    DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
    builder.withTypeConverterFactory(DynamoDBTypeConverterFactory.standard());
    builder.withTableNameResolver(DefaultTableNameResolver.INSTANCE);
    builder.withTableNameOverride(tableNameOverrider());
    return builder.build();
  }

  @Bean
  public TableNameOverride tableNameOverrider() {
    return TableNameOverride.withTableNamePrefix(tableName);
  }

  @Bean
  public DynamoDbClient amazonDynamoDB() {
    return DynamoDbClient.builder()
        .region(Region.of(region))
        .credentialsProvider(WebIdentityTokenFileCredentialsProvider.create())
        .build();
  }

} 

In pom.xml I have the below dependency related to AWS.

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.15.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

        <dependency>
            <groupId>io.github.boostchicken</groupId>
            <artifactId>spring-data-dynamodb</artifactId>
            <version>5.2.5</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>dynamodb</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sts</artifactId>
        </dependency> 
1 Answers

You have more then creds issues in your Java code. The bigger issue is you are mixing up V1 and V2.

The Java DynamoDB V1 API is:

com.amazonaws.services.dynamodbv2.*

The Java DyanamoDB V2 API is:

software.amazon.awssdk.services.dynamodb.*

Now your POM file references V2 API:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.15.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

You should not mix up V1 and V2. You are using V2 for the Service Client, and V1 for the DynamoDBMapperConfig object. This is not good practice and will not work.

Get rid of V1 API and replace with only V2 API. You seem to want to use DynamoDBMapper functionality. For V2, this is now part of Enhanced Client.

Using the DynamoDB Enhanced Client in the AWS SDK for Java 2.x

To see an AWS Tutorial that shows you how to build a Spring BOOT app using the AWS SDK for Java V2 (including the Enhanced Client), see:

Creating the Amazon DynamoDB web application item tracker

In this tutorial, the EnvironmentVariableCredentialsProvider is used to handle the AWS key values.

Related