Choosing Between AWS SDK for Rust: from_env(), load_defaults(), or defaults()

natalienatalie
5 min read

Disclaimer: Please remember those are my thoughts, and I’m only human, not your usual GPT. :) ( all the content in mine, including rare typos that I made as a human sometimes). Thank you for reading.

The AWS SDK for Rust provides multiple ways to load login configuration. I couldn’t understand why there were so many methods to do the same thing.

After reviewing the docs, I finally understood how to use it. Methods like from_env (), load_defaults (), and defaults () have slightly different purposes and capabilities. Let me walk you through it, too.

aws_config

It is a module within the AWS SDK for Rust that handles loading and managing AWS configurations, such as credentials, regions, and profiles. It provides different ways to configure the AWS environment for interacting with services.

aws_config::from_env()

Purpose: Flexible and recommended way to load AWS configuration because it allows method chaining (like .region(), .credentials_provider(), etc.) before calling .load(). This method reads the configuration from the environment (environment variables, profile, credentials file, etc.).

Chaining Methods: Allows to chain .region(), .credentials_provider(), and other methods before calling .load().

Usage: This is used when you want to customize the configuration by setting the region, credentials, provider, or other parameters before loading the final configuration.

Code Example:

    let config = aws_config::from_env()
        .region(region_provider) 
        .credentials_provider(credentials_provider) // Set credentials provider
        .load() 
        .await;

aws_config::load_defaults()

Purpose: Loads the default AWS configuration based on a specific BehaviorVersion. This method is simpler but doesn't allow chaining additional configuration options directly. It's intended to load the configuration with default behavior quickly.

No Method Chaining: You cannot chain .region() or .credentials_provider() directly. Instead, you would call .into_builder() after waiting to make any modifications.

Usage: Use this when you want the default configuration but need to apply some customization.

Code Example:

 let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest())
        .await 
        .into_builder() 
        .region(region_provider)
        .build();

aws_config::defaults()

Purpose: Deprecated. In some documentation or blogs, you can find examples with defaults(). Similar to load_defaults(), it's used to configure the defaults for the SDK based on a specific behavior version. It’s not commonly used directly because it doesn't allow method chaining like .from_env() does.

No Usage for Most Scenarios: It's was used by the SDK for loading default configurations and is not as flexible for method chaining.

Usage: has been deprecated.

Code Example:

  let config = aws_config::defaults(aws_config::BehaviorVersion::latest())
        .credentials_provider(credentials_provider) 
        .load()
        .await;

The above methods provide flexibility in how you load and customize AWS settings for your Rust application.

Types of AWS Credentials

Ok, now let’s review the types of AWS Credentials so that you can see the difference:

Environment Variables:

AWS looks for the following environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN* (optional, for temporary credentials)

These are typically used in CI/CD pipelines or when you explicitly set them in your environment for local development.

AWS Credentials File:

Located in ~/.aws/credentials on Linux/Mac or %USERPROFILE%\.aws\credentials on Windows. This file contains profiles, each with credentials (access key and secret key) for different AWS environments. You can specify a profile using the AWS_PROFILE environment variable.

AWS Config File:

Located at ~/.aws/config (or %USERPROFILE%\.aws\config on Windows). Contains configs like regions and custom profiles. Define multiple environments or settings for the credentials files.

IAM Roles: AWS Identity and Access Management (IAM).

AWS STS (Assume Role) The SDK can use the AWS Security Token Service (STS) to assume a different IAM role, typically to access resources in another AWS account. You can set this up in the configuration or via environment variables (e.g., AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE).

Web Identity Token Used for applications where an IAM role is assumed using a web identity token (like an OpenID Connect (OIDC) token). Environment variables like AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE, and AWS_ROLE_SESSION_NAME are used.

SSO (Single Sign-On) AWS SDK can also pull credentials from AWS SSO using profiles defined in the ~/.aws/config file if you've logged in via the AWS CLI. Below, I added a guide on which method to use (from_env() or load_defaults()), depending on the type of AWS credentials you're working with.

Usage method depends on the AWS credentials type

Here's a guide on which method to use (from_env() or load_defaults()) depending on the type of AWS credentials you're coding with:

1. Environment Variables

  • Method: aws_config::from_env()

  • Why: reads from environment variables (e.g., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY). It's the most flexible approach, allowing you to chain additional configuration options like .region() or .credentials_provider() before loading the final configuration.

2. AWS Credentials File (~/.aws/credentials)

  • Method: aws_config::from_env()

  • Why: The SDK will check the credentials file for default or profile-based credentials. You can also customize the profile using .profile("my_profile").

  • Use this when you have multiple profiles defined in your credentials file and want to specify one of them.

3. IAM Roles

  • Method: aws_config::load_defaults()

  • Why: Automatically retrieve credentials from attached IAM roles. load_defaults() will work perfectly here without needing further customization, as the SDK handles fetching the credentials from the instance metadata service.

4. AWS STS (Assume Role)

  • Method: aws_config::from_env()

  • Why: If you're assuming a role with STS, you’ll want to chain a custom .credentials_provider() or pass a role ARN and web identity token via environment variables (AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE). This allows you to set up a specific credentials provider that supports role assumption.

5. Web Identity Token (OpenID Connect)

  • Method: aws_config::from_env()

  • Why: This method allows you to pass the AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE to assume a role using a web identity token. It supports customization of how these tokens are used to obtain temporary credentials.

6. SSO (Single Sign-On)

  • Method: aws_config::load_defaults()

  • Why: The SDK can automatically retrieve credentials from your SSO configuration in the ~/.aws/config file. load_defaults() is ideal for this scenario, as you typically won’t need to customize the configuration unless you're modifying the profile afterward.

7. Static Creds (Hardcoded)

  • Method: aws_config::from_env()

  • Why: You can explicitly set static credentials using .credentials_provider() to use hardcoded AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY values. This method is flexible enough for custom providers.

  • Use Case: Don’t use due to security risks.

Summary

Use aws_config::from_env() for flexibility in credentials (e.g., custom credential providers, profiles, environment variables) and need to chain methods for custom regions or credentials providers.

Use aws_config::load_defaults() when you want the default credentials handling (e.g., IAM roles, SSO). You can modify it later using .into_builder() if you need to :).

I hope this will help.

2
Subscribe to my newsletter

Read articles from natalie directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

natalie
natalie

My name is Natalie. I'm a Staff Cloud Engineer, who also enjoys working on building and automating various tools that help the development teams be more productive and happy. What motivates me at work is the fast pace, team orientation, and creative environment, always new challenges. I'm passionate about helping make infrastructure more accessible. I love solving hard problems and "all things containers." Occasionally, I blog or speak at conferences. Currently, I am learning and blogging about Rust. I'm a technical mentor. In my spare time, I hike or camp with my aussiedoodle Chai and stand-up paddle (SUP) across the Bay Area, CA.