I’m really excited about the S3 repository support in the 2.4!
The AWS Java SDK supports loading credentials from a common profiles file, typically stored in .aws/credentials, which can then be shared between SDKs and projects. I think loading them this way should be an alternative to explicitly specifying the public and secret keys.
Right now, the credentials block is required for an s3 repository. Gradle will generate an error if it is missing.
I think an ideal solution would to instead fetch credentials from the profile file if the credentials block is missing. The AWS SDKs default to loading credentials from a profile file if not explicitly told, so I think it makes sense for this too.
If you don’t think the implicit profile detection is acceptable, or you wanted to support some of the additional profile options, we could make it explicit, like so:
Yes was some discussion with Adrian Kelly (original S3 contributor) regarding improving our Credentials infrastructure to better support different sources and formats for credentials:
In addition, we have an outstanding PR that would allow the forcing of preauthentication of HTTP requests. Adam thought this should be integrated with the Credentials DSL:
@Danny_Kirchmeier if you’re interested in progressing this, a good place to start would be to get your concerns added into that spec that Daz linked to.
Did anything happen with this? I was just looking for this feature today. The linked discussions don’t seem to address S3 credentials from the profile.
@axl Did you use an import to make ProfileCredentialsProvider available in your code? For it work, did you simply add a dependency on AWS SDK to your buildscript? Or maybe something else?
import com.amazonaws.auth.*
import com.amazonaws.auth.profile.*
buildscript {
repositories { jcenter() }
dependencies { classpath 'com.amazonaws:aws-java-sdk-core:1.11.5' }
}
plugins { id 'ivy-publish' }
def fetchAwsCredentials = {
try {
return new ProfileCredentialsProvider().credentials
} catch (Exception exception) {
logger.debug('Unable to retrieve AWS credentials from profile, publishing to S3 will not be available.')
return null
}
}
AWSCredentials awsCredentials = fetchAwsCredentials()
if (awsCredentials != null) {
publishing {
repositories {
ivy {
name 's3'
// Ensures you have the right region sub-domain and bucket here!
url 's3://<bucket>.s3-<region>.amazonaws.com'
credentials(AwsCredentials) {
accessKey awsCredentials.AWSAccessKeyId
secretKey awsCredentials.AWSSecretKey
}
}
}
}
}
Doing only the import was not working correctly (I guess because Gradle S3 subproject classpath was not accessible to my plugin somehow) so I explicitly added a dependency on AWS Java SDK client code. If that not required, I could check why it’s not working.
Some notes about my previous post and lesson learned.
I was using url s3://s3-us-west-1.amazonaws.com/your-bucket-here at first and it seems that was not the format expected by Gradle because it was giving me Access Denied everytime. After a bit of debugging, I found that Gradle expects a specific uri format to extract region, bucketandkey` correctly.
The correct format to use is url s3://<bucket>.s3-<region>.amazonaws.com (and simply s3://<bucket>.s3.amazonaws.com for us-east-1 region). As an example, s3://my-special-s3-bucket.s3-us-west-1.amazonaws.com.
If you use new DefaultAWSCredentialsProviderChain() instead of new ProfileCredentialsProvider() it will respect the AWS credential provider chain (http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html) and get environment variables first, followed by java system properties, etc.