Adi
Adi

Reputation: 4230

How to initialize AWS SDK in spring boot application?

I am writing a spring boot application which reads messages from SQS. I am able to run the application using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. However, I was wondering it would be simpler to pass this configuration via a file similar to application.properties. How to achieve this?

Upvotes: 14

Views: 52349

Answers (6)

kj007
kj007

Reputation: 6254

There are couple of ways you can manage it.

  1. You can configure aws configure (on your local or Linux machine) which will be required your secret key and access key then you don't need to pass these in api by default constructor you can create connection as it will pick secret key, etc from system path.

    AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
    

How to configure aws cli

  1. If you are using AWS EC2 then when you create ec2 instance, make sure assign it a role which has permission to SQS then you don't need to even configure on that machine.

  2. You can define your ACCESS KEY AND SECRET KEY in application/properties and load in sqs class by @Value.

  3. You can create aws.keys in your classpath and can load properties from a file.

  4. Of course you can define them as constant in your Constant class.

Upvotes: 3

Prasanth Rajendran
Prasanth Rajendran

Reputation: 5502

If you are running your service in EC2(mostly non-development environments) then there is no need for configuring the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, because of EC2ContainerCredentialsProviderWrapper the credentials will be automatically fetched from the AWS container.

    @Profile({"non-prod", "prod"})
    @Bean("AWSCredentialsProvider")
    public AWSCredentialsProvider amazonAWSCredentialsProvider() {
        return new EC2ContainerCredentialsProviderWrapper();
    }

NOTE: If you decided to use any of below mentioned AWSCredentialsProviderChain then use AWSCredentialsProvider and not AWSStaticCredentialsProvider otherwise you will endup with com.amazonaws.AmazonServiceException: The security token included in the request is expired exception.

  • DefaultAWSCredentialsProviderChain
  • EnvironmentVariableCredentialsProvider
  • SystemPropertiesCredentialsProvider
  • ProfileCredentialsProvider
  • EC2ContainerCredentialsProviderWrapper

If the application running outside the AWS then you can use AWSStaticCredentialsProvider with hard coded values of awsAccessKeyId and awsSecretAccessKey

aws.awsAccessKeyId:AWS_ACCESS_KEY_ID
aws.awsSecretAccessKey:AWS_SECRET_ACCESS_KEY
    @Value("${aws.awsAccessKeyId:}")
    private String awsAccessKeyId;

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

    @Profile({"dev", "test"})
    @Bean("AWSCredentialsProvider")
    public AWSStaticCredentialsProvider amazonAWSCredentialsProviderDevelopment() {
        return new AWSStaticCredentialsProvider(new BasicAWSCredentials(
                awsAccessKeyId, awsSecretAccessKey));
    }

Upvotes: 4

Kru
Kru

Reputation: 71

I avoid using property file, rather use Credential Provider Chain more here, AWS Documentation

Although, property file can also be overridden by environment variable, but If I always need to do so, why should I even mention it in property file. Also I would also like to avoid from committing keys in code ( in properties file)

Moreover, when I look at my CI/CD , it makes sense and also easy to just set environment variable for your Spring Boot Environment - specially on cloud. If using docker env, even more easier and much more cleaner.

Upvotes: 4

Rajesh
Rajesh

Reputation: 231

Change for aws sdk 2.0 is as follows..

    AwsBasicCredentials awsCreds = AwsBasicCredentials.create(this.accessKey, this.secretKey);

    S3Client client = S3Client.builder().region(Region.AP_SOUTH_1)
            .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
            .build();

Upvotes: 9

David
David

Reputation: 8196

If you utilise spring cloud AWS with spring boot, some AWS clients (like SQS and SNS) and EC2 meta data can be setup for you via auto-configuration. For local testing you can use static providers set via application properties.

Documentation: https://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.1.RELEASE/single/spring-cloud-aws.html#_spring_boot_auto_configuration

Specifically, you can set properties such as cloud.aws.credentials.accessKey and cloud.aws.region.static.

Upvotes: 8

fatCop
fatCop

Reputation: 2576

In spring boot application you can access properties mentioned in application.yml file with @value annotation. You can create a service like this:

@Service
public class AmazonClient {  
    private AmazonSQS sqsClient;

    @Value("${amazonProperties.accessKey}")
    private String accessKey;
    @Value("${amazonProperties.secretKey}")
    private String secretKey;

    @PostConstruct
    private void initializeAmazon() {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(this.accessKey, this.secretKey);
        this.sqsClient = AmazonSQSClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .build();

    }
}

In application.yml file:

amazonProperties:
   accessKey: <your_access_key>
   secretKey: <your_secret_key>

Upvotes: 17

Related Questions