Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose IMDS Client Command #9266

Open
2 tasks
commiterate opened this issue Jan 30, 2025 · 2 comments
Open
2 tasks

Expose IMDS Client Command #9266

commiterate opened this issue Jan 30, 2025 · 2 comments
Labels
feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged.

Comments

@commiterate
Copy link

commiterate commented Jan 30, 2025

Describe the feature

Expose a command for IMDS requests (e.g. aws imds get --path /latest/user-data) which automatically handles IMDS session token fetching + caching.

Use Case

Shell scripts are often used to set up EC2 instances manually (e.g. via SSH or SSM sessions) or automatically (e.g. EC2 user data scripts, CodeDeploy Agent hooks, SSM documents). They are also used for simple on-instance EC2 Auto Scaling lifecycle hook daemons (e.g. systemd service units).

These may need to fetch data from IMDS (e.g. user data, auto scaling target lifecycle state).

Today, this requires using curl to manually fetch IMDS session tokens for use in subsequent get requests.

Proposed Solution

The AWS SDKs implement an IMDS client. This is used to support IMDS region + credentials providers.

Some AWS SDKs expose the IMDS client to let users make IMDS calls without having to worry about fetching + caching session tokens. For example:

The idea is to do the same for the AWS SDK for Python (boto) and the AWS CLI.

  1. Update botocore to make the IMDSFetcher or a similar class expose a general-purpose public get() method.
  2. Add a CLI for the general-purpose public get() method.

Tangent: Rather than manually write an IMDS client in all AWS SDKs, is there a Smithy (or its internal predecessor) model describing IMDS which can be fed into the Smithy code generators?

This would probably need new Smithy auth and protocol traits like aws.auth#imdsv2 and aws.protocols#imds.

(cc: @mtdowling)

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CLI version used

2.*

Environment details (OS name and version, etc.)

All

@commiterate commiterate added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jan 30, 2025
@imSanko
Copy link

imSanko commented Feb 3, 2025

To implement a feature that exposes a command for IMDS (Instance Metadata Service) requests in the AWS CLI and SDK for we can prefer this:

1. Update botocore to Expose IMDSFetcher

The botocore library, which is the foundation of boto3, already contains an IMDSFetcher class that handles IMDSv2 session token fetching and caching. The first step is to expose a public get() method in this class to allow general-purpose IMDS requests.

Changes in botocore:

  • Add a Public get() Method: Modify the IMDSFetcher class to include a get() method that takes a path (e.g., /latest/user-data) and returns the corresponding metadata.
  • Handle Token Fetching and Caching: Ensure the get() method automatically handles the fetching and caching of IMDSv2 session tokens, so users don’t need to manage this manually.
  • Error Handling: Implement robust error handling for cases where the IMDS is unreachable or the requested path is invalid.
class IMDSFetcher:
    def __init__(self, timeout=None, num_attempts=None):
        # Existing initialization code
        pass

    def get(self, path):
        """
        Fetches metadata from IMDS at the specified path.
        Automatically handles IMDSv2 session token fetching and caching.
        """
        token = self._fetch_token()  # Fetches and caches the token if needed
        headers = {"X-aws-ec2-metadata-token": token}
        response = self._get_request(path, headers)
        return response

2. Add IMDS Command to AWS CLI

Next, add a new command to the AWS CLI that leverages the updated botocore functionality to make IMDS requests.

Changes in AWS CLI:

  • Add imds Command: Introduce a new imds command in the AWS CLI with a get subcommand.
  • Path Argument: Allow users to specify the IMDS path (e.g., /latest/user-data) as an argument.
  • Output Handling: Output the fetched metadata directly to the terminal.
aws imds get --path /latest/user-data

Implementation:

  • CLI Command Registration: Register the imds command in the AWS CLI command structure.
  • Integration with botocore: Use the IMDSFetcher.get() method to fetch the metadata and display it.
import botocore.session

def imds_get(args):
    session = botocore.session.get_session()
    fetcher = session.create_client('imds').meta.imds_fetcher
    response = fetcher.get(args.path)
    print(response)

def main():
    parser = argparse.ArgumentParser(description='Fetch metadata from IMDS.')
    parser.add_argument('--path', required=True, help='The IMDS path to fetch.')
    args = parser.parse_args()
    imds_get(args)

if __name__ == '__main__':
    main()

3. Smithy Model for IMDS (Optional)

To standardize IMDS client implementations across AWS SDKs, consider creating a Smithy model for IMDS. This would allow SDKs to generate IMDS clients automatically, reducing the need for manual implementation.

Smithy Model:

  • Define IMDS Protocol: Create a new Smithy protocol (e.g., aws.protocols#imds2) that describes the IMDS API.
  • Generate SDK Code: Use the Smithy code generator to produce IMDS client code for various SDKs.
namespace aws.protocols

@protocolDefinition
structure IMDS2 {
    version: "2023-01-01"
    operations: [GetMetadata]
}

operation GetMetadata {
    input: GetMetadataInput
    output: GetMetadataOutput
}

structure GetMetadataInput {
    @required
    path: string
}

structure GetMetadataOutput {
    metadata: string
}

4. Backward Compatibility

  • Deprecation Warning: If the changes introduce breaking changes, provide clear deprecation warnings and migration guides.
  • Fallback Mechanism: Ensure the new get() method can handle IMDSv1 for backward compatibility if needed.

@commiterate
Copy link
Author

commiterate commented Feb 3, 2025

Looks like an LLM-generated comment that's just taken the issue and fluffed it up with some trivial tasks and code snippets. The Smithy model is very incorrect and IMDSv1 support should not be considered as the AWS SDK IMDS clients should only support IMDSv2 as per the docs (IMDSv1 is deprecated).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

No branches or pull requests

2 participants