AWS - Playing With S3 and Spring Boot

This article is about getting a Spring Boot application into production on AWS. So to achieve this goal, we will need to have Docker installed, and created accounts at and Moreover, we will use AWS CLI.

Installing the AWS CLI

AWS CLI is a powerful tool and provides commands for many and many different AWS services (224 at the time of this writing).

Please follow the official instructions for your operating system to install version 2 of the AWS CLI on your machine.

After the installation, run aws configure. You will be asked to provide 4 parameters:

For “AWS Access Key ID” and “AWS Secret Access Key” you can find them under your AWS account > account menu > “My Security Credentials” > “Access keys” tab. Once find, create new access key and copy the values into the prompt of the AWS CLI.

For “Region Name”, you can find it in the menu and You can choose between “json” and “yaml” for output format.

$ aws configure --profile dev
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]:

This command will store a configuration file under for the dev profile ${user.home}/.aws/credentials.

To check if everything is fine use this command:

$  aws ec2 describe-regions

Congrats, AWS CLI is now authorized to call the AWS APIs in your name.

Building an S3 Sample Application

We will use Spring Cloud for Amazon Web Services as wrapped higher-level API operations for AWS that reduce the amount of boilerplate code. So next, let’s create the Spring Boot app project.

Spring Cloud doesn’t follow Spring Boot versions and it needs to be loaded via imported POM or directly via dependency. To be more precise, the spring-cloud-dependencies dependency bundles all the cloud starter dependencies to work with cloud libraries unlike the spring-cloud-starter-aws which is useful to communicate with AWS services like S3. To make it easier, here’s a list of the required dependencies:

<!-- option 1 -->

<!-- option 2 -->

Of course, we will need spring-boot-starter-web dependency to build Rest controllers.

Just as with any other Spring Boot application, we need to manage and store the app configuration:

      auto: false # we don’t rely on AWS CloudFormation service
      profile-name: dev
	  # profilePath: ${user.home}/.aws/credentials
      amazonaws: # fix for known errors
          EC2MetadataUtils: error
          InstanceMetadataServiceResourceFetcher: error

The main class to handle communications with S3 is called AmazonS3Client. For example, we can create a S3Repository as follows:

public class S3Repository {

  private final AmazonS3Client s3Client;

  public S3Repository(AmazonS3Client s3Client) {
    this.s3Client = s3Client;

  public void create(String bucket) {
    s3Client.createBucket(bucket);"Requested create " + bucket);
        .run(new WaiterParameters<>(new HeadBucketRequest(bucket)));"Bucket " + bucket + " is ready");
  public List<String> findAllBuckets() {
    return s3Client.listBuckets()
  public FileObject saveFile(String bucket, 
                         String key, 
                         String name, 
                         File file) {
    ObjectMetadata md = new ObjectMetadata();
    md.addUserMetadata("name", name);
    s3Client.putObject(bucket, key, file, md);
      // also s3Client.putObject(bucket, key, <String>, md);
      // also s3Client.putObject(bucket, key, <InputStream>, md);"Requested save file " + bucket + "/" + key);

    return FileObject.builder()
        .url(s3Client.getUrl(bucket, key))
  public void makeFilePublic(String bucket, String key) {
    s3Client.setObjectAcl(bucket, key, PublicRead);"Requested " + bucket + "/" + key + " as public");

  public void makeFilePrivate(String bucket, String key) {
    s3Client.setObjectAcl(bucket, key, BucketOwnerFullControl);"Requested " + bucket + "/" + key + " as private");
  public void deleteFile(String bucket, String key) {
    s3Client.deleteObject(bucket, key);"Requested delete " + bucket + "/" + key + ");

There many features and use cases to implement but here are the most used operations. Of course, we can use them inside a Rest controller.

@RequestMapping(value = "/s3/bucket")
public class S3BucketApi {

  private S3Repository s3Repository;

  public S3BucketApi(S3Repository s3Repository) {
    this.s3Repository = s3Repository;

  public ResponseEntity<String> createBucket(@PathVariable String bucket)
      throws URISyntaxException {
    return ResponseEntity.created(new URI("/bucket/" + bucket)).build();

  public ResponseEntity<String> deleteBucket(@PathVariable String bucket) {
    return ResponseEntity.noContent().build();

  public ResponseEntity<List<String>> findAllBucket() {
    return ResponseEntity.ok(s3Repository.findAllBuckets());

In this article, we’ve configured AWS CLI and configured a project to run operations against AWS Simple Storage Service (S3) APIs inside a Spring Boot and the Spring Cloud project.