The article shows how S3 can be used as a maven repository for gradle.

We currently do not have a privately deployed artifact repository to easily share pre-built artifacts. While the goal is to stand up an artifact server (Artifactory), in the interim S3 is our artifact repository.

It is rather simple to get going with S3, be cognizant of the cons:

  • No search facility
  • Maintenance tasks such as removing old versions are manual tasks

1. Provision S3 bucket

Create a S3 bucket (or create in a S3 bucket).

s3bucket/artifacts/releases

2. Setup Users, Groups and IAM Policies

We have two IAM users and groups with policies attached to the groups. The user with write access is set up only on the build server so that only tested and vetted versions are published. As a best practice, set up groups and group policy and add users to the group rather than attach permissions directly to the user.

All consumers of the repository can either use the read only id or their userid gets added to the read only IAM group.

We will look at the publish user, group and policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowListingOfReleasesFolder",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::s3bucket"
      ],
      "Condition": {
        "StringLike": {
          "s3:prefix": [
            "artifacts/releases/*"
          ]
        }
      }
    },
    {
      "Sid": "AllowAccessToWriteDeleteReleases",
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::s3bucket/artifacts/releases/*"
      ]
    }
  ]
}
policy.json
$ aws iam create-group --group-name artifacts-publish

$ aws iam put-group-policy --group-name artifacts-publish \
  --policy-name artifacts-publish-policy --policy-document file://policy.json
  
$ aws iam create-user --user-name artifacts-publisher

# The command return the access key id and secret key. 
# Save it to the config file on the build server
$ aws iam create-access-key --user-name artifacts-publisher

$ aws iam add-user-to-group --user-name artifacts-publisher \
  --group-name artifacts-publish

3. Gradle Build file

The relevant sections of the build file are below. Note the use of AwsImAuthentication. This allows us to use the credentials from the config files without specifying it in build properties.

plugins {
  id("maven-publish")
}

repositories {
  mavenCentral()

  maven {
    url("s3://s3bucket/artifacts/releases")
    authentication {
      awsIm(AwsImAuthentication)
    }
  }
}

publishing {
  publications {
    mavenJava(MavenPublication) {
      from(components.java)
    }
  }
  repositories {
    maven {
      url("s3://s3bucket/artifacts/releases")
      authentication {
        awsIm(AwsImAuthentication)
      }
    }
  }
}
$ ./gradlew publish

With the above buildfile, consuming the published artifact is covered. The script will look at the s3 location in addition to mavencentral.