8

I use aws-java-sdk version 1.11.104. According to the AWS credentials doc the default region is us-east-1, however when I don't set the region manually when I create a client, like this:

AWSCredentialsProvider awsCredentialsProvider =
    new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey));
AmazonS3 s3Client = 
    AmazonS3ClientBuilder.standard().withCredentials(awsCredentialsProvider).build();

I get this error:

com.amazonaws.SdkClientException:
   Unable to find a region via the region provider chain.
   Must provide an explicit region in the builder or setup environment to supply a region.
  1. Why isn't the default region used?

    I tried to add the following before my code above but it still doesn't work.

    System.setProperty(SDKGlobalConfiguration.AWS_REGION_ENV_VAR, "us-east-1");
    
  2. How to set the AWS region programmatically? (I would like to set it at runtime for all classes of my project).

Thanks.

Edit:

I know I can use .withRegion() on the clients' builder, but I was expecting a default region, or, the region picked from an environment variable through the default region provider chain.

Gray
  • 115,027
  • 24
  • 293
  • 354
Maxime Laval
  • 4,068
  • 8
  • 40
  • 60
  • 2nd question http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/client/builder/AwsClientBuilder.html#withRegion-com.amazonaws.regions.Regions- – Iłya Bursov May 08 '17 at 21:31
  • 1st question http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html – Iłya Bursov May 08 '17 at 21:33
  • http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/client/builder/AwsClientBuilder.html#setRegion-java.lang.String- – Nir Alfasi May 08 '17 at 21:36
  • @Lashane and @alfasin your links don't explain how to set the environment variable programmatically, and it doesn't explain either why `System.setProperty(SDKGlobalConfiguration.AWS_REGION_ENV_VAR, "us-east-1");` doesn't work... – Maxime Laval May 09 '17 at 02:30

4 Answers4

10

I have a similar scenario, we are building an AWS abstraction layer so programmers don't have to touch any AWS Code. And I were also having problems with unit testing and tried to set the variable AWS_REGION with System.setProperty(String, String).

The solution I've found is to set the property aws.region instead. The class AwsSystemPropertyRegionProvider it is on the "region provider chain" and will get the value from this property.

I'm setting the property before my tests, in @BeforeClass:

@BeforeClass
public static void setUp() {
    System.setProperty("aws.region", "us-west-2");
}

Hope it helps.

Matheus Silva
  • 101
  • 1
  • 4
3

I was expecting a default region, or, the region picked from an environment variable through the default region provider chain.

Yeah as I read the code, it doesn't have a default region:

  • AmazonEC2ClientBuilder extends (up a bit) AwsClientBuilder.
  • AwsClientBuilder by default uses the DefaultAwsRegionProviderChain.
  • DefaultAwsRegionProviderChain uses 3 mechanisms to determine the region:
    • AwsEnvVarOverrideRegionProvider which looks in the AWS_REGION environmental variable which you can't set at runtime. Or shouldn't (see below).
    • AwsProfileRegionProvider which reads it out of you AWS profile file.
    • InstanceMetadataRegionProvider which tries to lookup which EC2 instance you are on and take its region.
  1. Why isn't the default region used? (see these aws docs)

I did not see in the code any reference to us-east-1 in the source except in AwsHostNameUtils.parseRegionName(...). I'm not sure where that is used however.

System.setProperty(SDKGlobalConfiguration.AWS_REGION_ENV_VAR, "us-east-1");

Yeah the environment is not the same thing as a system property. There are gross hacks that allow you to alter the environmental variables at runtime but user beware.

Community
  • 1
  • 1
Gray
  • 115,027
  • 24
  • 293
  • 354
  • Thanks for answering. Your AWS doc link is the same as the one I put in my question, and it says "If you don't select a region, then us-east-1 will be used by default." which then is confusing... Regarding the environment variables, it's just for testing, locally, because my other environments such as production grab the region from `AwsEnvVarOverrideRegionProvider`or `AwsProfileRegionProvider`. I don't want to use `.withRegion()` and I don't want all the developers in my team to touch their system just to test AWS clients. – Maxime Laval May 09 '17 at 14:52
  • If you want that @MaximeLaval then I would use a different `AwsRegionProviderChain`. You can take the default one and then add in your own class which looks for a system property or env variable. – Gray May 09 '17 at 18:39
  • But then I would need to pass it to every client I create, same as using `.withRegion()`, and I don't want to modify the existing code, I want to be able to test it as is. I guess I'll use reflection to set environment variables. – Maxime Laval May 09 '17 at 20:15
  • Again ideally I don't want developers to have to do anything on their system (outside of the project). I want any developer to be able to test the project just after pulling it from the VC. I am ok with modifying src/test/resources config though. – Maxime Laval May 10 '17 at 14:40
  • @MaximeLaval : Did u find any solution for the same. I am looking for something similar where I just have to set the region for once . -Thanks Arpan – Arpan Sep 12 '18 at 16:51
0

I met the same issue. And my problem is the permission to read the ~/.aws/config file. I change it to 644, which everyone can read it. Then it work. Hope this could help.

-1

Try this:

AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)).withRegion("us-east-1").build();
Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84
ram p
  • 3
  • 3