How to Use and Configure Amazon S3 as a Private Maven Repository

Amazon S3 (Simple Storage Service) is a great service to store, protect, and recover any information or data from “buckets” (containers for objects). When it comes to Maven artifacts, AWS S3 Bucket has become widely common due to its high scalability, versatility, and lifecycle management. 

This article will show a step by step process on how to set up a private Maven repository.

Host a Private Maven Repo

You’re keeping public artifacts in Maven Central if you want to make them visible to anyone who has access to Amazon S3. But if you want only members of your team to see them, you’ll need to configure AWS first, and then, configure your Spring Boot Project to deploy your .jar files. These are the steps you need to follow:

  1. Configure AWS
    • Create an S3 Bucket.
    • Create an IAM User to access the bucket.
  2. Configure Spring Boot Project
    • Configure Spring Boot Project Stored to be stored on S3 Bucket.
    • Import Spring Boot Project Stored on S3 Bucket into another Spring Boot Project.

Create and Configure Objects in AWS S3

Create an S3 Bucket on AWS

  • Select ‘S3 service’ in AWS control panel.

  • Select ‘Create Bucket’ button, give a name to the bucket, and select a region.

  • Select ‘Create bucket’ at the bottom of the page.

Create an IAM User

To allow access and permissions only to specific people:

  • Select ‘IAM service’ in AWS control panel.

  • Select ‘Users’ from left side menu and then “Add user” button.

  • Give the user a name and check the box to give the user ‘Programmatic access.’

  • On permissions screen select ‘Attach existing policies directly’. Then choose ‘Create Policy.’

  • Select ‘JSON Tab’ and add the new permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListObjectsInBucket",
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": [“arn:aws:s3:::bucket_name"]
        },
        {
            "Sid": "AllObjectActions",
            "Effect": "Allow",
            "Action": "s3:*Object",
            "Resource": ["arn:aws:s3:::bucket_name/*"]
        }
    ]
}
  • Select ‘Next:Tags.’
  • Add some tags(optional) and then select ‘Next:Review.’
  • Add a name for the policy and a description(optional). Then, click on ‘Create Policy.’
  • Go back to ‘Add User Window/Tab’ and select the newly created policy.

  • Select ‘Next:Tags’ and then ‘Next:Review’. Check to make sure you completed all the data correctly; then select ‘Create User’ button.

  • After creating new users, AWS S3 provides an ‘Access key’ and ‘Secret access key’.
  • Copy/download file with access key and secret access key. The secrets will be shown only this time so be sure you store them right. If you lose them, you can at any time generate a new key secret pair, but you are allowed only 2 per account.

How to Configure Spring Boot Projects

Configure Spring Boot Project Stored on S3 Bucket

  • Use Gradle to publish .jar to Maven repositories. Add the following code snippet to the build.gradle file in the root folder or your project:
plugins {
id 'maven-publish'
}

task fatJar(type: Jar) {
zip64 = true
manifest {
attributes 'Implementation-Title': 'spring-boot-project-title',
   'Implementation-Version':  'spring-boot-project-version',
   'Main-Class': 'spring-boot-project-main-class'
}
baseName = 'spring-boot-project-name'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}


publishing {
repositories {
maven {
def releasesRepoUrl = "s3://bucket_name/releases"
def snapshotsRepoUrl = "s3://bucket_name/snapshots"
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl

credentials(AwsCredentials) {
accessKey ACCESS_KEY_ID
secretKey SECRET_ACCESS_KEY
}
}
}

publications {
mavenJava(MavenPublication) {
groupId 'spring-boot-project-group'
artifactId 'spring-boot-project-name'
version 'spring-boot-project-version'
artifact fatJar
}
}
}

Make sure you also create a gradle.properties file in the same folder as the build.gradle file where you can keep the credentials downloaded above. Also, don’t push this file to a Git repository for security reasons.

ACCESS_KEY_ID = *access key value*
SECRET_ACCESS_KEY = *secret key value *
  • Update the Maven repository:

  • maven settings.xml file (includes the credentials username and username password)
<?xml version="1.0" encoding="UTF-8"?>
<settings 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
      http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
        <server>
            <id>maven-s3-releases-repo</id>
            <username>ACCESS_KEY_ID</username>
            <password>SECRET_ACCESS_KEY</password>
        </server>
        <server>
            <id>maven-s3-snapshots-repo</id>
            <username>ACCESS_KEY_ID</username>
            <password>SECRET_ACCESS_KEY</password>
        </server>
    </servers>
</settings>
  • After updating your settings, define the artifacts’ pom.xml of your Maven project:

...
<build>
    <extensions>
        <extension>
            <groupId>spring-boot-project-group</groupId>
            <artifactId>spring-boot-project-name</artifactId>
            <version>spring-boot-project-version</version>
        </extension>
    </extensions>
</build>
<distributionManagement>
    <snapshotRepository>
        <id>s3-bucket-name-snapshots</id>
        <url>s3://bucket_name/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>s3-bucket-name-releases</id>
        <url>s3://bucket_name/releases</url>
    </repository>
</distributionManagement>
...

Import Spring Boot Project Stored on S3 Bucket into another Spring Boot Project

  • Configure Gradle for authentication by providing AWS credentials:
repositories {
maven {
url "s3://bucket_name/releases"
credentials(AwsCredentials) {
accessKey ACCESS_KEY_ID
secretKey SECRET_ACCESS_KEY
}
}
maven {
url "s3://bucket_name/snapshots"
credentials(AwsCredentials) {
accessKey ACCESS_KEY_ID
secretKey SECRET_ACCESS_KEY
}
}
mavenCentral()
}


dependencies {
implementation ‘groupId:artifactId:version'
}
  • Add Maven repositories and dependencies to your projects:

...
<repositories>
    <repository>
        <id>maven-s3-releases-repo</id>
        <name>S3 Release Repository</name>
        <url>s3://bucket_name/releases</url>
    </repository>
    <repository>
        <id>maven-s3-snapshots-repo</id>
        <name>S3 Snapshot Repository</name>
        <url>s3://bucket_name/snapshots</url>
    </repository>
</repositories>
...
<dependencies>
    <dependency>
        <groupId>groupId</groupId>
        <artifactId>artifactId</artifactId>
        <version>version</version>
    </dependency>
</dependencies>

Conclusion

If you follow all the steps from above, you’ll allow access to private artifacts stored in private Maven repositories. This method allows you to optimize costs and it gives extra security to your data since they are only visible to authorized individuals.