aws-sdk-java
aws-sdk-java copied to clipboard
ProfileCredentialsProvider fails if credentials file has a profile with an assume role configuration when using Ec2InstanceMetadata
Hey,
I have a problem with the credentials file with the following profile:
[default] region = eu-central-1 credential_source=Ec2InstanceMetadata
[profile1] role_arn = arn:aws:iam::xxxxxx:role/Jenkins-Deployment-Role credential_source=Ec2InstanceMetadata source_profile=default
When using the credentials file and specifying profile1
, I am getting the following error:
Exception in thread "main" com.amazonaws.SdkClientException: Unable to load credentials into profile
[default]: AWS Access Key ID is not specified. at com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider.fromStaticCredentials(ProfileStaticCredentialsProvider.java:55) at com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider.
(ProfileStaticCredentialsProvider.java:40) at com.amazonaws.auth.profile.internal.ProfileAssumeRoleCredentialsProvider.fromAssumeRole(ProfileAssumeRoleCredentialsProvider.java:72) at com.amazonaws.auth.profile.internal.ProfileAssumeRoleCredentialsProvider. (ProfileAssumeRoleCredentialsProvider.java:46) at com.amazonaws.auth.profile.ProfilesConfigFile.fromProfile(ProfilesConfigFile.java:204) at com.amazonaws.auth.profile.ProfilesConfigFile.getCredentials(ProfilesConfigFile.java:160) at com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:161) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1166) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:762) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:724) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) at com.amazonaws.services.ecs.AmazonECSClient.doInvoke(AmazonECSClient.java:2745) at com.amazonaws.services.ecs.AmazonECSClient.invoke(AmazonECSClient.java:2721) at com.amazonaws.services.ecs.AmazonECSClient.executeDescribeClusters(AmazonECSClient.java:951) at com.amazonaws.services.ecs.AmazonECSClient.describeClusters(AmazonECSClient.java:926)
Version of sdk used for this test: 1.11.374
I was not able to find out of using Ec2InstanceMetadata is supported as "default" profile officially, but based on the documentation I read above should be correct.
We have now been able to workaround this problem by using
private void initEcsClient(){ AWSStaticCredentialsProvider credentialsProvider;
logger.debug("DBG: roleArn=" + this.roleArn); AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() .withRegion(awsRegion) .build(); AssumeRoleRequest roleRequest = new AssumeRoleRequest() .withRoleArn(this.roleArn) .withRoleSessionName(customer + "-" + environment + "-restart-acm-tool"); AssumeRoleResult assumeRoleResult = stsClient.assumeRole(roleRequest); logger.info ("assumed user arn: " + assumeRoleResult.getAssumedRoleUser()); Credentials sessionCredentials = assumeRoleResult.getCredentials(); logger.info ("assumed user credentials: " + sessionCredentials.toString()); BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials( sessionCredentials.getAccessKeyId(), sessionCredentials.getSecretAccessKey(), sessionCredentials.getSessionToken() ); credentialsProvider = new AWSStaticCredentialsProvider(basicSessionCredentials); AmazonECSClientBuilder ecsClientBuilder = AmazonECSClientBuilder.standard().withRegion(awsRegion) .withCredentials(credentialsProvider); amazonECS = ecsClientBuilder.build(); logger.debug("ECSClient: Using credentials Acc-Key: "+ecsClientBuilder.getCredentials().getCredentials().getAWSAccessKeyId()); logger.debug("ECSClient: Using credentials Sec-Key: "+ecsClientBuilder.getCredentials().getCredentials().getAWSSecretKey());
}
...but this doesnt solve the original problem that we can not use the Java SDK with the same strategy as the aws-cli where the assumeRole stuff is handled automatically.
Looks like we don't support the credentials_source at the moment. I'll go ahead and mark this as a feature request so others can +1 to aide in prioritization.
As for the workaround I suggest using the STSAssumeRoleSessionCredentialsProvider which handles automatically refreshing credentials when close to expiry and actually making the call to STS.
STSAssumeRoleSessionCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(roleArn, customer + "-" + environment + "-restart-acm-tool")
.withStsClient(AWSSecurityTokenServiceClientBuilder.defaultClient())
.build();
AmazonECSClientBuilder ecsClientBuilder = AmazonECSClientBuilder.standard().withRegion(awsRegion)
.withCredentials(credentialsProvider);
amazonECS = ecsClientBuilder.build();
👍 I just ran into this.
possible duplicate of #1521.
Just ran into this issue myself Other SDKs already support the credential_source setting so this caught me by surprise
Would like this feature in SDK and SDK 2, breaks our dev work flow.
Supported in 2.5.30 https://github.com/aws/aws-sdk-java-v2/issues/1169