Setting the AWS region programmatically

2019-06-21 04:56发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

Try this:

AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)).withRegion("us-east-1").build();