/ #AWS #Maven 

Using Amazon S3 as a Private Maven Repository

This article is a quick tutorial to setup a private maven repository using Amazon S3 instead of Nexus or Artifactory.

First we need to create a S3 bucket used to store two types of maven artifacts: stores two types of artifacts: releases and snapshots.

repository.example.com/[snapshots, releases]

Since we want a private repository, we can securely control access to this bucket for our users by leveraging AWS Identity and Access Management (IAM). We create a new user, named s3-repo-admin, and subsequently set the permissions to this bucket by using the policy generator. In this example, we allow all actions to the bucket named repository.example.com for user s3-repo-admin.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1425225596000",
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::repository.example.com", "arn:aws:s3:::repository.example.com/*"
      ]
    }
  ]
}

We can also use the IAM policy simulator to verify the effects of our policy.

IAM Policy Simulator

Next we update the local maven setting ~/.m2/settings.xml with the AWS access credentials for the account, i.e., s3-repo-admin.

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      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-release-repo</id>
            <username>ACCESS_KEY_ID</username>
            <password>SECRET_ACCESS_KEY</password>
        </server>
        <server>
            <id>maven-s3-snapshot-repo</id>
            <username>ACCESS_KEY_ID</username>
            <password>SECRET_ACCESS_KEY</password>
        </server>
    </servers>
</settings>

Here we create a project called test-public-lib from simple maven archetypes such as maven-archetype-quickstart. In this example, the groupId, artifactId and version settings are being specified com.example, test-publish-lib and 1.0-SNAPSHOT respectively. Now, then, in order to publish artefacts to S3, the build extension and the repositories must be defined in test-public-lib/pom.xml.

<project>
    ...
    <distributionManagement>
        <repository>
            <id>maven-s3-release-repo</id>
            <name>AWS Release Repository</name>
            <url>s3://repository.example.com/releases</url>
        </repository>
        <snapshotRepository>
            <id>maven-s3-snapshot-repo</id>
            <name>AWS Snapshot Repository</name>
            <url>s3://repository.example.com/snapshots</url>
        </snapshotRepository>
    </distributionManagement>
    ...
    <build>
        ...
        <extensions>
            ...
            <extension>
                <groupId>org.springframework.build</groupId>
                <artifactId>aws-maven</artifactId>
                <version>5.0.0.RELEASE</version>
            </extension>
            ...
        </extensions>
        ...
    </build>
    ...
</project>

Finally, we can execute the mvn deploy command to test out the whole process. As shown in the following, we will have a new timestamped shapshot version each time I run the deploy target. In contrast, we only have an artifact with release-version.

Maven 3 Timestamped Snapshots

Subsequently, we create another project named test-publish-app in the same way and modify the POM file, i.e., test-publish-app/pom.xml, to test whether the dependency management is workable or not.

<project>
    ...
    <repositories>
        <repository>
            <id>maven-s3-release-repo</id>
            <name>S3 Release Repository</name>
            <url>s3://repository.example.com/releases</url>
        </repository>
        <repository>
            <id>maven-s3-snapshot-repo</id>
            <name>S3 Snapshot Repository</name>
            <url>s3://repository.example.com/snapshots</url>
        </repository>
    </repositories>
    ...
    <dependencies>
        ...
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>test-publish-lib</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        ...
    </dependencies>
    ...
    <build>
        ...
        <extensions>
            ...
            <extension>
                <groupId>org.springframework.build</groupId>
                <artifactId>aws-maven</artifactId>
                <version>5.0.0.RELEASE</version>
            </extension>
            ...
        </extensions>
        ...
    </build>
    ...
</project>

Run the mvn compile then will download the artifacts with the specified versions.

AWS S3 Maven Repository

References