AWS Developer Blog

Updates to Credential and Region Handling

by Steve Roberts | on | in .NET | Permalink | Comments |  Share

Version 3.1.73.0 of the AWS Tools for Windows PowerShell and AWS SDK for .NET (AWSSDK.Core version 3.1.6.0),  released today, contain enhancements to the way credentials and region data can be supplied to your SDK applications and PowerShell scripts, including the ability to use SAML federated credentials in your SDK applications. We’ve also refactored support for querying Amazon EC2 instance metadata and made it available to your code. Let’s take a look at the changes.

SDK Updates

Credential Handling

In 2015, we launched support for using SAML federated credentials with the AWS PowerShell cmdlets. (See New Support for Federated Users in the AWS Tools for Windows PowerShell.) We’ve now extended the SDK so that applications written against it can also use the SAML role profiles described in the blog post. To use this support in your application, you must first set up the role profile. The details for using the PowerShell cmdlets to do this appear in the blog post. Then, in the same way you do with other credential profiles, you simply reference the profile in your application’s app.config/web.config files with the AWSProfileName appsetting key. The SAML support to obtain AWS credentials is contained in the SDK’s Security Token Service assembly (AWSSDK.SecurityToken.dll), which is loaded at runtime. Be sure this assembly is available to your application at runtime.

The SDK has also been updated to support reading credentials from the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables (the same variables used with other AWS SDKs). For legacy support, the AWS_SECRET_KEY variable is still supported.

If no credentials are supplied to the constructors of the service clients, the SDK will probe to find a set to use. As of this release, the current probing tests are followed:

  1. If an explicit access key/secret access key or profile name is found in the application’s app.config/web.config files, use it.
  2. If a credential profile named "default" exists, use it. (This profile can contain AWS credentials or it can be a SAML role profile.)
  3. If credentials are found in environment variables, use them.
  4. Finally, check EC2 instance metadata for instance profile credentials.

Specifying Region

To set the region when you instantiated AWS service clients in your SDK applications, you used to have to two options: hard-code the region in the application code using the system name (for example, ‘us-east-1’) or the RegionEndpoint helper properties (for example, RegionEndpoint.USEast1) or supply the region system name in the application’s app.config/web.config files using the AWSRegion appsetting key. The SDK has now been updated to enable region detection through an environment variable or, if your code is running on an EC2 instance, from instance metadata.

To use an environment variable to set the AWS region, you simply set the variable AWS_REGION to the system name of the region you want service clients to use. If you need to override this for a specific client, simply pass the required region in the service client constructor. The AWS_REGION variable is used by the other AWS SDKs.

When running on an EC2 instance, your SDK-based applications will auto-detect the region in which the instance is running from EC2 instance metadata if no explicit setting is found. This means you can now deploy code without needing to hard-code any region in your app.config/web.config files. You can instead rely on the SDK to auto-detect the region when your application instantiates clients for AWS services.

Just as with credentials, if no region information is supplied to a service client constructor, the SDK probes to see if the region can be determined automatically. As of right now, these are the tests performed:

  1. Is an AWSRegion appsetting key present in the application’s app.config/web.config files? If so, use it.
  2. Is the AWS_REGION environment variable set? If so, use it.
  3. Attempt to read EC2 instance metadata and obtain the region in which the instance is running.

PowerShell Updates

Credential Handling

You can now supply credentials to the cmdlets by using the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables. (You might find this helpful when you attempt to run the cmdlets in a user identity where credential profiles are inconvenient to set up, for example, the local system account.)

If you have enabled SAML federated authentication for use with the cmdlets, they now support the use of proxy data configured using the Set-AWSProxy cmdlet when making authentication requests against the ADFS endpoint. Previously, a proxy had to be set at the machine-wide level.

When the AWS cmdlets run, they follow this series of tests to obtain credentials:

  1. If explicit credential parameters (-AccessKey, -SecretKey, -SessionToken, for example) have been supplied to the cmdlet or if a profile has been specified using the -ProfileName parameter, use those credentials. The profile supplied to -ProfileName can contain regular AWS credentials or it can be a SAML role profile.
  2. If the current shell has been configured with default credentials (held in the $StoredAWSCredentials variable), use them.
  3. If a credential profile with the name "default" exists, use it. (This profile can contain regular AWS credentials or it can be a SAML role profile.)
  4. If the new AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment variables are set, use the credentials they contain.
  5. If EC2 instance metadata is available, look for instance profile credentials.

Specifying Region

In addition to existing support for specifying region using the -Region parameter on cmdlets (or setting a shell-wide default using Set-DefaultAWSRegion), the cmdlets in the AWSPowerShell module can now detect region from the AWS_REGION environment variable or from EC2 instance metadata.

Some users may run the Initialize-AWSDefaults cmdlet when opening a shell on an EC2 instance. Now that you can detect region from instance metadata, the first time you run this cmdlet on an EC2 instance, you are no longer prompted to select a region from the menu. If you want to run PowerShell scripts using a region for the AWS services different from the region in which the instance is running, you can override the default detection by supplying the -Region parameter, with appropriate value, to the cmdlet. You can also continue to use the Set-DefaultAWSRegion cmdlet in your shell or scripts, or add the -Region parameter to any cmdlet to direct calls to a region that differs from the region hosting the instance.

Just as with credentials, the cmdlets will search for the appropriate region to use when invoked:

  1. If a -Region parameter was supplied to the cmdlet, use it.
  2. If the current shell contains a default region ($StoredAWSRegion variable), use it.
  3. If the AWS_REGION environment variable is set, use it.
  4. If the credential profile ‘default’ exists and it contains a default region value (set by previous use of Initalize-AWSDefaults), use it.
  5. If EC2 instance metadata is available, inspect it to determine the region.

Reading EC2 Instance Metadata

As part of extending the SDK and PowerShell tools to read region information from EC2 instance metadata, we have refactored the metadata reader class (Amazon.EC2.Util.EC2Metadata) from the AWSSDK.EC2.dll assembly into the core runtime (AWSSDK.Core.dll) assembly. The original class has been marked obsolete.

The replacement class is Amazon.Util.EC2InstanceMetadata. It contains additional helper methods to read more of the EC2 instance metadata than the original class. For example, you can now read from the dynamic data associated with the instance. For more information, see [http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-metadata.html ec2-instance-metadata.html]. Region information is held in what is known as the identity document for the instance. The document is in JSON format. The class contains a helper property, Region, which extracts the relevant data for you and returns it as a RegionEndpoint instance, making it super easy to query this in your own applications. You can also easily read the instance monitoring, signature, and PKCS7 data from convenient properties.

We’ve not forgotten scripters either! Previously, to read instance metadata from PowerShell, you had to have run the Invoke-WebRequest cmdlet against the metadata endpoint and parsed the data yourself. The AWSPowerShell module now contains a cmdlet dedicated to the task: Get-EC2InstanceMetadata. Some examples:

PS C:UsersAdministrator> Get-EC2InstanceMetadata -Category LocalIpv4
10.232.46.188

PS C:UsersAdministrator> Get-EC2InstanceMetadata -Category AvailabilityZone
us-west-2a

PS C:UsersAdministrator> Get-EC2InstanceMetadata -ListCategory
AmiId
LaunchIndex
ManifestPath
AncestorAmiId
BlockDeviceMapping
InstanceId
InstanceType
LocalHostname
LocalIpv4
KernelId
AvailabilityZone
ProductCode
PublicHostname
PublicIpv4
PublicKey
RamdiskId
Region
ReservationId
SecurityGroup
UserData
InstanceMonitoring
IdentityDocument
IdentitySignature
IdentityPkcs7

PS C:UsersAdministrator> Get-EC2InstanceMetadata -path /public-keys/0/openssh-key
ssh-rsa AAAAB3N...na27jfTV keypairname

We hope you find these new capabilities helpful. Be sure to let us know in the comments if there are other scenarios we should look at!