AWS Developer Tools Blog
Updates to Credential and Region Handling
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:
- If an explicit access key/secret access key or profile name is found in the application’s app.config/web.config files, use it.
- If a credential profile named “default” exists, use it. (This profile can contain AWS credentials or it can be a SAML role profile.)
- If credentials are found in environment variables, use them.
- 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:
- Is an AWSRegion appsetting key present in the application’s app.config/web.config files? If so, use it.
- Is the
AWS_REGION
environment variable set? If so, use it. - 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:
- 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. - If the current shell has been configured with default credentials (held in the $StoredAWSCredentials variable), use them.
- 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.)
- If the new
AWS_ACCESS_KEY_ID
/AWS_SECRET_ACCESS_KEY
environment variables are set, use the credentials they contain. - 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:
- If a
-Region
parameter was supplied to the cmdlet, use it. - If the current shell contains a default region ($StoredAWSRegion variable), use it.
- If the
AWS_REGION
environment variable is set, use it. - If the credential profile ‘default’ exists and it contains a default region value (set by previous use of
Initalize-AWSDefaults
), use it. - 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!