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

secret store on lambda produces a variety of surprising errors but no valid responses #905

Closed
rseymour opened this issue Sep 28, 2023 · 18 comments
Labels
bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.

Comments

@rseymour
Copy link

rseymour commented Sep 28, 2023

Describe the bug

I have the params+secrets layer attached v11. I have been repeatedly trying as is my bad habit, and so far neither of 2 methods have worked to retrieve the secret. I have followed the secretmanager example which "works on my machine" but on lambda I get the following surprising errors (w/ debug and full tracing on for smithy, afaict):

1st method: SDK:

2023-09-28T14:02:43.737563Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: credentials cache miss occurred; added new AWS credentials (took Ok(23.901µs))
-- | --
2023-09-28T14:02:43.737603Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: close time.busy=55.3µs time.idle=2.36µs
EXTENSION Name: AWSParametersAndSecretsLambdaExtension State: Ready Events: [INVOKE, SHUTDOWN]

As you can see nothing happens, the debug! trace from inside of the lazy_caching doesn't seem to fire off either, but no credentials are returned.

2nd method: http://localhost:2773/secretsmanager/get...
This one is more surprising to me because I haven't seen anyone getting this error.

Ok(Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(2773), path: "/secretsmanager/get", query: Some("secretId={tried everything from full arn to just name}"), fragment: None }, status: 400, headers: {"content-type": "text/plain", "x-amzn-errortype": "BadRequestException", "date": "Thu, 28 Sep 2023 17:56:29 GMT", "content-length": "39"} }) 

At the end of my rope as I got in a loop of "just one more thing" over and over.

Expected Behavior

I wanted to get a working response that I could decode into JSON, instead I get timeouts or the BadRequest error

    let v: serde_json::Value = serde_json::from_str(resp.secret_string().unwrap()).unwrap();
    println!("Value: {}", v["password"]);

^ this code (with my aws creds local) works fine.

Current Behavior

BadRequestException 400 with plain http to localhost 2773.
[edit] SDK secretmanager errors like this (I had to up the exec time to get this): Err(DispatchFailure(DispatchFailure { source: ConnectorError { kind: Timeout, source: hyper::Error(Connect, HttpTimeoutError { kind: "HTTP connect", duration: 3.1s }), connection: Unknown } }))

Reproduction Steps

  1. Create lambda function (excitingly easy)
  2. Put secret in secret manager.
  3. Add roles to allow access to lambda runner role. Allow: secretsmanager:GetSecretValue
  4. Allow: secretsmanager:DescribeSecret
  5. Add a kms role for good luck: Allow: kms:Decrypt
  6. Add secrets layer to lambda function
  7. Attempt to do 1 http request from a rust lambda fn to get the secret. (hardest thing I've ever attempted to do in AWS apparently)

Possible Solution

Permissions? Bad urls in the docs? Broken SDK function, that works on my (ARM) machine but not on ARM lambdas? Some terrifying feature issue?

It is a truly next level problem where I have to write an issue. I'm praying this is just that I didn't allow my lambda to read a secret in some way and it's just a documentation failure, otherwise I honestly can't understand how this code could fail so opaquely. Thanks for reading at least.

Additional Information/Context

I went through hoping this would just work, but somewhere around hour 3 I realized wait a second, this really should just work or at least throw an error that someone can search for. This is on arm64, which I hope isn't the issue. I'm hoping this is a permissions issue that isn't mentioned in the documentation, but I know that (a) I have an AWS_SESSION_TOKEN (b) that 2773 on localhost is open to the running function (c) that I've tried 3% of the possible ways of getting the json to return (d) I have not tried POST-ing (d) reaching out to the externally hosted secrets managers doesn't seem to work either, but the exact URLs for individual requests are not given in the documentation at this time.

Version

├── aws-config v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   ├── aws-smithy-http-tower v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-sdk-sso v0.0.0-local (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-sigv4 v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-json v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   └── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-sdk-sts v0.0.0-local (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-json v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-query v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   │   ├── aws-smithy-xml v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   │   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-http-tower v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-json v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
├── aws-sdk-secretsmanager v0.0.0-local (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535)
│   ├── aws-credential-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-async v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-client v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-http v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-json v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-runtime v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-runtime-api v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-smithy-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)
│   ├── aws-types v0.56.1 (https://github.com/awslabs/aws-sdk-rust?branch=next#8108b535) (*)

Environment details (OS name and version, etc.)

arm64

Logs

The code that made this log is trying both the plain http request and the SDK.

INIT_START Runtime Version: provided:al2.v23 Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:febdf188505e3a7c9cad819ea0b63328df31e9eefeb8eed817c3137edf3a93b4
--
  | 2023-09-28T13:56:28.932-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL is debug. Log level set to debug.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED is not present. Cache is enabled by default.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE is not present. Using default cache size: 1000 objects.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG SECRETS_MANAGER_TTL is not present. Setting default time-to-live: 5m0s.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG SSM_PARAMETER_STORE_TTL is not present. Setting default time-to-live: 5m0s.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG SECRETS_MANAGER_TIMEOUT_MILLIS is not present. Setting default timeout: 0s.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG SSM_PARAMETER_STORE_TIMEOUT_MILLIS is not present. Setting default timeout: 0s.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS is not present. Setting default value: 3.
  | 2023-09-28T13:56:28.933-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG PARAMETERS_SECRETS_EXTENSION_HTTP_PORT is not present. Setting default port: 2773.
  | 2023-09-28T13:56:28.935-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 INFO Systems Manager Parameter Store and Secrets Manager Lambda Extension 1.0.143
  | 2023-09-28T13:56:28.935-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 DEBUG Creating a new cache with size 1000
  | 2023-09-28T13:56:28.935-04:00 | [AWS Parameters and Secrets Lambda Extension] 2023/09/28 17:56:28 INFO Serving on port 2773
  | 2023-09-28T13:56:28.978-04:00 | not a problem, no .env file found, ok if running in container with docker handling external .env -> Container Environment
  | 2023-09-28T13:56:29.048-04:00Copyresponse or error: Ok(Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(2773), path: "/secretsmanager/get", query: Some("secretId=rds!db-03212a4c-03fc-40f1-8b2d-0658dd9ac02a&versionStage=AWSCURRENT"), fragment: None }, status: 400, headers: {"content-type": "text/plain", "x-amzn-errortype": "BadRequestException", "date": "Thu, 28 Sep 2023 17:56:29 GMT", "content-length": "39"} }) | response or error: Ok(Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(2773), path: "/secretsmanager/get", query: Some("secretId=rds!db-03212a4c-03fc-40f1-8b2d-0658dd9ac02a&versionStage=AWSCURRENT"), fragment: None }, status: 400, headers: {"content-type": "text/plain", "x-amzn-errortype": "BadRequestException", "date": "Thu, 28 Sep 2023 17:56:29 GMT", "content-length": "39"} })
  | 2023-09-28T13:56:34.048-04:00 | one more time with just the id!
  | 2023-09-28T13:56:34.078-04:00 | response or error: Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(2773), path: "/secretsmanager/get", query: Some("secretId=thisissomebull{I put swearwords in here because I'd really hit my limit and just wanted some error that made sense}"), fragment: None }, status: 400, headers: {"content-type": "text/plain", "x-amzn-errortype": "BadRequestException", "date": "Thu, 28 Sep 2023 17:56:34 GMT", "content-length": "39"} }
  | 2023-09-28T13:56:34.078-04:00 | reqwest style:
  | 2023-09-28T13:56:34.078-04:00 | [server/src/main.rs:166] &on_aws = Ok(
  | 2023-09-28T13:56:34.078-04:00 | "oops",
  | 2023-09-28T13:56:34.078-04:00 | )
  | 2023-09-28T13:56:34.078-04:00 | sdk style:
  | 2023-09-28T13:56:34.078-04:00 | getting shared_config
  | 2023-09-28T13:56:34.093-04:00 | 2023-09-28T17:56:34.093425Z INFO load_region{provider=EnvironmentVariableRegionProvider { env: Env(Real) }}: aws_config::meta::region: new
  | 2023-09-28T13:56:34.093-04:00 | 2023-09-28T17:56:34.093462Z INFO load_region{provider=EnvironmentVariableRegionProvider { env: Env(Real) }}: aws_config::meta::region: enter
  | 2023-09-28T13:56:34.093-04:00 | 2023-09-28T17:56:34.093468Z INFO load_region{provider=EnvironmentVariableRegionProvider { env: Env(Real) }}: aws_config::meta::region: exit
  | 2023-09-28T13:56:34.093-04:00 | 2023-09-28T17:56:34.093472Z INFO load_region{provider=EnvironmentVariableRegionProvider { env: Env(Real) }}: aws_config::meta::region: close time.busy=6.15µs time.idle=46.5µs
  | 2023-09-28T13:56:34.123-04:00 | getting client
  | 2023-09-28T13:56:34.128-04:00 | got the client but who cares
  | 2023-09-28T13:56:34.128-04:00 | looooop
  | 2023-09-28T13:56:34.132-04:00 | 2023-09-28T17:56:34.132864Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: new
  | 2023-09-28T13:56:34.132-04:00 | 2023-09-28T17:56:34.132898Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: enter
  | 2023-09-28T13:56:34.132-04:00 | 2023-09-28T17:56:34.132918Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: credentials cache miss occurred; added new AWS credentials (took Ok(64.147µs))
  | 2023-09-28T13:56:34.132-04:00 | 2023-09-28T17:56:34.132924Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: exit
  | 2023-09-28T13:56:34.132-04:00 | 2023-09-28T17:56:34.132927Z INFO lazy_load_credentials: aws_credential_types::cache::lazy_caching: close time.busy=26.7µs time.idle=39.7µs
  | 2023-09-28T13:56:38.891-04:00CopyEXTENSION	Name: AWSParametersAndSecretsLambdaExtension	State: Ready	Events: [INVOKE, SHUTDOWN] | EXTENSION Name: AWSParametersAndSecretsLambdaExtension State: Ready Events: [INVOKE, SHUTDOWN]
@rseymour rseymour added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 28, 2023
@rseymour
Copy link
Author

Little bonus, I did the add a VPC endpoint, with a proper routable name, secretsmanager.us-east-1.amazonaws.com and I still get this:

Err(DispatchFailure(DispatchFailure { source: ConnectorError { kind: Timeout, source: hyper::Error(Connect, HttpTimeoutError { kind: "HTTP connect", duration: 3.1s }), connection: Unknown } }))

I will try hitting that with reqwest, which I imagine will work.

@rseymour
Copy link
Author

Tried hitting it with a get from reqwest. Also timed out. I'm not doing any rocket surgery here, they're just on the default VPC for ease of testing. Looking at the Go and Python libraries there's almost no code around handling timeouts, but a lot of code for various other failure modes. I'm assuming I'm hitting timeouts on something obvious, wrt to routing, etc, but that still doesn't explain why a call to localhost:2773 also times out, unless there's a typo my coworkers and I can't see in the path or something? Looking at this now: https://repost.aws/knowledge-center/lambda-function-retry-timeout-sdk

The rds setup creates this secret, which I thought was a really cool feature in comparison to GCP's "screw you" approach to database secrets, but if I can't access it from the SDK I'm going to end up turning off rotation and just passing it in as an ENV var (which for sure works, since it was the first thing I tried, prior to taking an eternity getting the same error, writing up said error, and still continuing to get said errors)

@jdisanti
Copy link
Contributor

I'm sorry I can't be more helpful here since I'm not so familiar with this Lambda feature. However, I can say for certain that we don't have any built-in support for accessing these secrets on localhost in Lambda in the SDK.

It sounds to me like there's a configuration issue happening somewhere. It's almost as if nothing is actually listening on localhost:2773, and hence, it never connects.

@rseymour
Copy link
Author

Yea I tried using TcpStream to connect to 2773, and that worked, but whatever it is expecting isn't what the rust library is sending. Now I'm just piecing together how much (header) auth is needed to interact with the secretsmanager via https via VPC endpoint. This one was a real shocker since everything up to this point with the SDK had 'just worked' including the SAM watch feature and cargo lambda.

Thanks for reading, this is the closest I've been to smashing a computer in 5+ years so I haven't exactly scoped this bug down to its bare minimum.

@jdisanti
Copy link
Contributor

Since you're using reqwest, you can enable trace level logging for the hyper crate to get the exact thing it sends over the socket. That might be helpful in diagnosing the issue.

@rseymour
Copy link
Author

rseymour commented Sep 28, 2023

tracing helped (setting it in RUST_LOG didn't work, but it did when I set the max level for the subscriber) ... this gets interesting, because it shows, yep it can do DNS, yep it can do the right POST stuff... but somehow that takes over 3 seconds. Perhaps timing out is a proper failure mode for the secrets manager when something else is wrong?

2023-09-28T22:09:03.793573Z TRACE invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: transmitting request request=Request { method: POST, uri: https://secretsmanager.us-east-1.amazonaws.com/, version: HTTP/1.1, headers: {"content-type": "application/x-amz-json-1.1", "x-amz-target": "secretsmanager.GetSecretValue", "content-length": "118", "user-agent": "aws-sdk-rust/0.56.1 os/linux lang/rust/1.72.1", "x-amz-user-agent": "aws-sdk-rust/0.56.1 api/secretsmanager/0.0.0-local os/linux lang/rust/1.72.1", "x-amz-date": "20230928T220903Z", "authorization": "AWS4-HMAC-SHA256 Credential=ASIA3ZMCO63J3E5KM37V/20230928/us-east-1/secretsmanager/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=c471bc54ba868fd949a7b0aabf5ec57abfad1253fdd9fcc56909e4e13853611c", "x-amz-security-token": Sensitive, "amz-sdk-request": "attempt=1; max=3", "amz-sdk-invocation-id": "faac0a58-2712-4109-8201-bb6557409268"}, body: SdkBody { inner: Once(Some(b"{\"SecretId\":\"arn:aws:secretsmanager:us-east-1:810411816659:secret:rds!db-03212a4c-03fc-40f1-8b2d-0658dd9ac02a-s9UdUC\"}")), retryable: true } }
--
2023-09-28T22:09:03.793601Z TRACE invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: hyper::client::pool: checkout waiting for idle connection: ("https", secretsmanager.us-east-1.amazonaws.com)
2023-09-28T22:09:03.793618Z TRACE invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: hyper::client::connect::http: Http::connect; scheme=Some("https"), host=Some("secretsmanager.us-east-1.amazonaws.com"), port=None
2023-09-28T22:09:03.793643Z DEBUG hyper::client::connect::dns: resolving host="secretsmanager.us-east-1.amazonaws.com"
2023-09-28T22:09:03.793813Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:03.793872Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:03.793883Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:03.794743Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:03.794764Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:03.794770Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:03.794788Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: hyper::client::connect::http: connecting to 172.31.7.95:443
2023-09-28T22:09:03.794859Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:03.794868Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:03.794872Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:06.895137Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:06.895174Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:06.895182Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: enter
2023-09-28T22:09:06.895247Z TRACE invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: hyper::client::pool: checkout dropped for ("https", secretsmanager.us-east-1.amazonaws.com)
2023-09-28T22:09:06.895271Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: encountered orchestrator error; halting
2023-09-28T22:09:06.895276Z TRACE invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime_api::client::interceptors::context: orchestrator is transitioning to the 'failure' phase from the 'Transmit' phase
2023-09-28T22:09:06.895282Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: exit
2023-09-28T22:09:06.895285Z DEBUG invoke{service=secretsmanager operation=GetSecretValue}:try_op:try_attempt: aws_smithy_runtime::client::orchestrator: close time.busy=697µs time.idle=3.10s

the checkout dropped for ("https", secretsmanager.us-east-1.amazonaws.com) is the first sign of the problem afaict.

@rseymour
Copy link
Author

More searching on that "checkout dropped for" phrase and I found this rather unhappy many year thread: hyperium/hyper#2312

@rseymour
Copy link
Author

rseymour commented Sep 29, 2023

After a lot of poking, I finally figured out where to change the endpoint for this library (to localhost) and now I think I have some sort of answer:

Err(ServiceError(ServiceError { source: Unhandled(Unhandled { source: DeserializeError { kind: ExpectedLiteral("null"), offset: Some(0) }, meta: ErrorMetadata { code: None, message: None, extras: None } }), raw: Response { status: 400, version: HTTP/1.1, headers: {"content-type": "text/plain", "x-amzn-errortype": "BadRequestException", "date": "Fri, 29 Sep 2023 14:54:09 GMT", "content-length": "39"}, body: SdkBody { inner: Once(Some(b"not ready to serve traffic, please wait")), retryable: true } } }))

Gave it 6 retries over six seconds and the poor thing still replied it wasn't ready... Not sure what's happening there, the layer config is a single click add practically, and it is definitely hosting something on localhost:2773
This may be some sort of order of operations thing as per: https://stackoverflow.com/questions/75624681/aws-secrets-and-parameters-lambda-extension-throw-not-ready-to-serve-traffic but not sure why (in my case and his) the layer logs ready to serve, and then responds with not ready. :(

@hxk1633
Copy link

hxk1633 commented Sep 29, 2023

I'm also having an issue accessing secrets in lambda functions using the SDK when I run sam local start-api. Is there a workaround to get it working locally?

@rseymour
Copy link
Author

Tried many things, came to this one which is the secrets manager hitting localhost:

Lambda runtime invoke�{�requestId�=�"730b14ee-a75e-499a-b699-28731294b672" �xrayTraceId�=�"Root=1-65173223-2f769c830a71f32e6e3d416e;Parent=3a1d37725e7c21eb;Sampled=0;Lineage=8c09e47e:0" }�:�lazy_load_credentials:� credentials cache miss occurred; added new AWS credentials (took Ok(16.172µs))
--
response run: Err(ServiceError(ServiceError { source: Unhandled(Unhandled { source: DeserializeError { kind: UnexpectedToken('b', "'{', '[', '\"', 'null', 'true', 'false', <number>"), offset: Some(0) }, meta: ErrorMetadata { code: None, message: None, extras: None } }), raw: Response { status: 401, version: HTTP/1.1, headers: {"content-type": "text/plain", "x-amzn-errortype": "AccessDeniedException", "date": "Fri, 29 Sep 2023 20:24:32 GMT", "content-length": "31"}, body: SdkBody { inner: Once(Some(b"bad session token or header key")), retryable: true } } }))

bad token in the session token or header key?! weird.

The code that generates this (I went back to hello world and stuffed the secret gathering into the function_handler):

    let shared_config = aws_config::from_env()
            .endpoint_url("http://127.0.0.1:2773/secretsmanager")
            .load()
            .await;
        println!("shared config: {:?}", &shared_config);
        let client = Client::new(&shared_config);
        let resp = client
        .get_secret_value()
        .secret_id("{REDACTED}")
        .send()
        .await;
        println!("response run: {:?}", resp);

The print on the config doesn't seem to show any working credential sources.

@rseymour
Copy link
Author

Here is a debug print of the SdkConfig shared_config above w/ no obvious cred providers from the env:

SdkConfig { app_name: None,
credentials_cache: Some(CredentialsCache { inner: Lazy(Builder { sleep: Some(SharedAsyncSleep(TokioSleep)),
time_source: Some(SharedTimeSource(SystemTimeSource)),
load_timeout: None,
buffer_time: None,
buffer_time_jitter_fraction: None,
default_credential_expiration: None }) }),
credentials_provider: Some(SharedCredentialsProvider(DefaultCredentialsChain { provider_chain: CredentialsProviderChain { providers: [("Environment", EnvironmentVariableCredentialsProvider { env: Env(Real) }),
("Profile", ProfileFileCredentialsProvider { factory: NamedProviderFactory { providers: {"environment": EnvironmentVariableCredentialsProvider { env: Env(Real) },
"ecscontainer": EcsCredentialsProvider { inner: OnceCell { value: None },
env: Env(Real),
builder: Builder { provider_config: Some(ProviderConfig { env: Env(Real),
fs: Fs(Real),
sleep: Some(SharedAsyncSleep(TokioSleep)),
region: Some(Region("us-east-1")) }),
dns: None,
connect_timeout: None,
read_timeout: None } },
"ec2instancemetadata": ImdsCredentialsProvider { client: LazyClient { client: OnceCell { value: None },
builder: Builder { max_attempts: None,
endpoint: None,
mode_override: None,
token_ttl: None,
connect_timeout: None,
read_timeout: None,
config: Some(ProviderConfig { env: Env(Real),
fs: Fs(Real),
sleep: Some(SharedAsyncSleep(TokioSleep)),
region: Some(Region("us-east-1")) }) } },
env: Env(Real),
profile: None,
time_source: SharedTimeSource(SystemTimeSource),
last_retrieved_credentials: RwLock { data: None,
poisoned: false,
.. } }} },
sts_config: Builder { config: CloneableLayer(Layer { name: "", items: [TypeErasedBox[Clone]:Set(Prebuilt(DynConnector)),
TypeErasedBox[Clone]:Set(Region("us-east-1")),
TypeErasedBox[Clone]:Set(RetryConfig { mode: Standard,
max_attempts: 3, initial_backoff: 1s,
max_backoff: 20s,
reconnect_mode: ReconnectOnTransientError,
use_static_exponential_base: false })] }),
runtime_components: RuntimeComponentsBuilder { builder_name: "service config", auth_scheme_option_resolver: None,
http_connector: None,
endpoint_resolver: None,
auth_schemes: [], identity_resolvers: [], interceptors: [], retry_classifiers: None,
retry_strategy: None,
time_source: Some(Tracked { _origin: "service config", value: SharedTimeSource(SystemTimeSource) }),
sleep_impl: Some(Tracked { _origin: "service config", value: SharedAsyncSleep(TokioSleep) }) },
runtime_plugins: [] },
provider_config: ProviderConfig { env: Env(Real),
fs: Fs(Real),
sleep: Some(SharedAsyncSleep(TokioSleep)),
region: Some(Region("us-east-1")) } }),
("WebIdentityToken", WebIdentityTokenCredentialsProvider { source: Env(Env(Real)),
time_source: SharedTimeSource(SystemTimeSource),
fs: Fs(Real),
sts_client: Client { handle: Handle { conf: Config { config: FrozenLayer(Layer { name: "aws_sdk_sts::config::Config", items: [TypeErasedBox[Clone]:Set(RetryConfig { mode: Standard,
max_attempts: 3, initial_backoff: 1s,
max_backoff: 20s,
reconnect_mode: ReconnectOnTransientError,
use_static_exponential_base: false }),
TypeErasedBox[Clone]:Set(SigningName("sts")),
TypeErasedBox[Clone]:Set(RetryPartition { inner: "sts" }),
TypeErasedBox[Clone]:Set(SigningRegion("us-east-1")),
TypeErasedBox[Clone]:Set(ApiMetadata { service_id: "sts", version: "0.0.0-local" }),
TypeErasedBox[Clone]:Set(Region("us-east-1")),
TypeErasedBox[Clone]:Set(Prebuilt(DynConnector)),
TypeErasedBox[Clone]:Set(TimeoutConfig { connect_timeout: None,
read_timeout: None,
operation_timeout: None,
operation_attempt_timeout: None }),
TypeErasedBox[Clone]:Set(TokenBucket { semaphore: Semaphore { ll_sem: Semaphore { permits: 500 } },
max_permits: 500, timeout_retry_cost: 10, retry_cost: 5 })] }),
cloneable: CloneableLayer(Layer { name: "", items: [TypeErasedBox[Clone]:Set(RetryConfig { mode: Standard,
max_attempts: 3, initial_backoff: 1s,
max_backoff: 20s,
reconnect_mode: ReconnectOnTransientError,
use_static_exponential_base: false }),
TypeErasedBox[Clone]:Set(SigningName("sts")),
TypeErasedBox[Clone]:Set(RetryPartition { inner: "sts" }),
TypeErasedBox[Clone]:Set(SigningRegion("us-east-1")),
TypeErasedBox[Clone]:Set(ApiMetadata { service_id: "sts", version: "0.0.0-local" }),
TypeErasedBox[Clone]:Set(Region("us-east-1")),
TypeErasedBox[Clone]:Set(Prebuilt(DynConnector)),
TypeErasedBox[Clone]:Set(TimeoutConfig { connect_timeout: None,
read_timeout: None,
operation_timeout: None,
operation_attempt_timeout: None }),
TypeErasedBox[Clone]:Set(TokenBucket { semaphore: Semaphore { ll_sem: Semaphore { permits: 500 } },
max_permits: 500, timeout_retry_cost: 10, retry_cost: 5 })] }),
runtime_components: RuntimeComponentsBuilder { builder_name: "service config", auth_scheme_option_resolver: None,
http_connector: Some(Tracked { _origin: "service config", value: SharedHttpConnector(DynConnectorAdapter { dyn_connector: Mutex { data: DynConnector,
poisoned: false,
.. } }) }),
endpoint_resolver: Some(Tracked { _origin: "service config", value: SharedEndpointResolver(DefaultEndpointResolver { inner: SharedEndpointResolver }) }),
auth_schemes: [], identity_resolvers: [], interceptors: [], retry_classifiers: None,
retry_strategy: Some(Tracked { _origin: "service config", value: SharedRetryStrategy(StandardRetryStrategy { base: 0xaaaabb8b9e00, initial_backoff: 1s,
max_attempts: 3, max_backoff: 20s,
retry_permit: Mutex { data: None,
poisoned: false,
.. } }) }),
time_source: Some(Tracked { _origin: "service config", value: SharedTimeSource(SystemTimeSource) }),
sleep_impl: Some(Tracked { _origin: "service config", value: SharedAsyncSleep(TokioSleep) }) },
runtime_plugins: [] },
runtime_plugins: RuntimePlugins { client_plugins: [SharedRuntimePlugin(StaticRuntimePlugin { config: Some(FrozenLayer(Layer { name: "aws_sdk_sts::config::Config", items: [TypeErasedBox[Clone]:Set(RetryConfig { mode: Standard,
max_attempts: 3, initial_backoff: 1s,
max_backoff: 20s,
reconnect_mode: ReconnectOnTransientError,
use_static_exponential_base: false }),
TypeErasedBox[Clone]:Set(SigningName("sts")),
TypeErasedBox[Clone]:Set(RetryPartition { inner: "sts" }),
TypeErasedBox[Clone]:Set(SigningRegion("us-east-1")),
TypeErasedBox[Clone]:Set(ApiMetadata { service_id: "sts", version: "0.0.0-local" }),
TypeErasedBox[Clone]:Set(Region("us-east-1")),
TypeErasedBox[Clone]:Set(Prebuilt(DynConnector)),
TypeErasedBox[Clone]:Set(TimeoutConfig { connect_timeout: None,
read_timeout: None,
operation_timeout: None,
operation_attempt_timeout: None }),
TypeErasedBox[Clone]:Set(TokenBucket { semaphore: Semaphore { ll_sem: Semaphore { permits: 500 } },
max_permits: 500, timeout_retry_cost: 10, retry_cost: 5 })] })),
runtime_components: Some(RuntimeComponentsBuilder { builder_name: "service config", auth_scheme_option_resolver: None,
http_connector: Some(Tracked { _origin: "service config", value: SharedHttpConnector(DynConnectorAdapter { dyn_connector: Mutex { data: DynConnector,
poisoned: false,
.. } }) }),
endpoint_resolver: Some(Tracked { _origin: "service config", value: SharedEndpointResolver(DefaultEndpointResolver { inner: SharedEndpointResolver }) }),
auth_schemes: [], identity_resolvers: [], interceptors: [], retry_classifiers: None,
retry_strategy: Some(Tracked { _origin: "service config", value: SharedRetryStrategy(StandardRetryStrategy { base: 0xaaaabb8b9e00, initial_backoff: 1s,
max_attempts: 3, max_backoff: 20s,
retry_permit: Mutex { data: None,
poisoned: false,
.. } }) }),
time_source: Some(Tracked { _origin: "service config", value: SharedTimeSource(SystemTimeSource) }),
sleep_impl: Some(Tracked { _origin: "service config", value: SharedAsyncSleep(TokioSleep) }) }),
order: None }),
SharedRuntimePlugin(ServiceRuntimePlugin { config: None,
runtime_components: RuntimeComponentsBuilder { builder_name: "ServiceRuntimePlugin", auth_scheme_option_resolver: None,
http_connector: None,
endpoint_resolver: None,
auth_schemes: [Tracked { _origin: "ServiceRuntimePlugin", value: SharedAuthScheme(SigV4AuthScheme { signer: SigV4Signer }) }], identity_resolvers: [], interceptors: [Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: ConnectionPoisoningInterceptor } },
Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: ServiceClockSkewInterceptor } },
Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: RequestInfoInterceptor } },
Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: UserAgentInterceptor } },
Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: InvocationIdInterceptor { default: DefaultInvocationIdGenerator { rng: Mutex { data: Rng(7422905397715655268),
poisoned: false,
.. } } } } },
Tracked { _origin: "ServiceRuntimePlugin", value: SharedInterceptor { interceptor: RecursionDetectionInterceptor { env: Env(Real) } } }], retry_classifiers: None,
retry_strategy: None,
time_source: None,
sleep_impl: None } }),
SharedRuntimePlugin(NoAuthRuntimePlugin(RuntimeComponentsBuilder { builder_name: "NoAuthRuntimePlugin", auth_scheme_option_resolver: None,
http_connector: None,
endpoint_resolver: None,
auth_schemes: [Tracked { _origin: "NoAuthRuntimePlugin", value: SharedAuthScheme(NoAuthScheme { signer: NoAuthSigner }) }], identity_resolvers: [Tracked { _origin: "NoAuthRuntimePlugin", value: ConfiguredIdentityResolver { auth_scheme: AuthSchemeId { scheme_id: "no_auth" },
identity_resolver: SharedIdentityResolver(NoAuthIdentityResolver) } }], interceptors: [], retry_classifiers: None,
retry_strategy: None,
time_source: None,
sleep_impl: None }))], operation_plugins: [] } } } }),
("EcsContainer", EcsCredentialsProvider { inner: OnceCell { value: None },
env: Env(Real),
builder: Builder { provider_config: Some(ProviderConfig { env: Env(Real),
fs: Fs(Real),
sleep: Some(SharedAsyncSleep(TokioSleep)),
region: Some(Region("us-east-1")) }),
dns: None,
connect_timeout: None,
read_timeout: None } }),
("Ec2InstanceMetadata", ImdsCredentialsProvider { client: LazyClient { client: OnceCell { value: None },
builder: Builder { max_attempts: None,
endpoint: None,
mode_override: None,
token_ttl: None,
connect_timeout: None,
read_timeout: None,
config: Some(ProviderConfig { env: Env(Real),
fs: Fs(Real),
sleep: Some(SharedAsyncSleep(TokioSleep)),
region: Some(Region("us-east-1")) }) } },
env: Env(Real),
profile: None,
time_source: SharedTimeSource(SystemTimeSource),
last_retrieved_credentials: RwLock { data: None,
poisoned: false,
.. } })] } })),
region: Some(Region("us-east-1")),
endpoint_url: Some("http://127.0.0.1:2773/secretsmanager"),
retry_config: Some(RetryConfig { mode: Standard,
max_attempts: 3, initial_backoff: 1s,
max_backoff: 20s,
reconnect_mode: ReconnectOnTransientError,
use_static_exponential_base: false }),
sleep_impl: Some(SharedAsyncSleep(TokioSleep)),
time_source: Some(SharedTimeSource(SharedTimeSource(SystemTimeSource))),
timeout_config: Some(TimeoutConfig { connect_timeout: Some(3.1s),
read_timeout: None,
operation_timeout: None,
operation_attempt_timeout: None }),
http_connector: Some(ConnectorFn(<function pointer>)),
use_fips: None,
use_dual_stack: None }

@rseymour
Copy link
Author

One final note before the weekend, where I started was in essence this lambda example examples/examples/lambda/src/main.rs w/ secretsmanager instead of s3. It could be the entire issue is roles/permissions but no error message seems to reflect that.

@rcoh
Copy link
Contributor

rcoh commented Oct 2, 2023

If you're running on lambda, I'd expect credentials to come from the environment. If you want to check to see if you have credentials, you can call the credential provider directly:

  let shared_config = aws_config::from_env()
            .endpoint_url("http://127.0.0.1:2773/secretsmanager")
            .load()
            .await;
  let creds = shared_config.credentials_provider().unwrap().provide_credentials().await; // probably need to import the trait
  println!("{:?}", creds); // will be redacted

@rcoh
Copy link
Contributor

rcoh commented Oct 2, 2023

Your message #905 (comment) shows a log line where it is in fact setting the token properly (see Authorization header). It's possible that with the URL with a port in it we aren't signing properly though?

@rseymour
Copy link
Author

rseymour commented Oct 2, 2023

Thanks so much for these responses. I think I may have run into a dreaded two path -> two different issues situation. I haven't resolved it, but I wouldn't be surprised if

  • path 1 the layer add (ie creating the 127.0.0.1:2773 endpoint) wasn't working with the rust library
  • path 2 connecting to secretsmanager.us-east1. ... was succeeding at DNS resolution to the VPC endpoint, but failing due to VPC + Lambda issues.

For now I'm going to punt on this, but I think path 2 is fixable by me via config (ie starting from cloudformation/SAM scratch), and path 1 might be fixable if I knew more about this sdk code.

@rseymour
Copy link
Author

rseymour commented Oct 2, 2023

My nightmare is over. I can point to exactly where I went wrong and what the fix was. The fix was this comment by Ribeiro: https://stackoverflow.com/questions/62274069/aws-lambda-access-secrets-manager-from-within-vpc#comment121571222_62274140

My mistake was from this post from amazon: https://aws.amazon.com/blogs/security/how-to-connect-to-aws-secrets-manager-service-within-a-virtual-private-cloud/ < Step 6 is ... not enough if you don't have a 'wide open' security group and I think it blocked all of this from working regardless of what the code was doing by putting in any old security group for "the security group [...] created earlier".

Still not sure if this was also preventing the Layer from communicating to the secrets manager (I assume it was) but otherwise if you don't have your groups set up neatly like that comment on stack overflow (allow 443 into the secrets vpc endpoint from the lambda subnets with one SG on the secrets endpoint and allow the lambda to speak outbound on 443 to the secrets manager SG you just created or the subnet the secrets manager is on)

Sorry for my frustration, It was rather simple underneath the errors. Timeouts are disallowed routes or nonexistent routes, nothing more or less, sadly there's nothing screaming at you saying "don't take a 5 year old blog post at its word". Whoops. Thanks for all your help. Once I get this going I may experiment with the layer vs vpc endpoint setup.

@rseymour rseymour closed this as completed Oct 2, 2023
@github-actions
Copy link

github-actions bot commented Oct 2, 2023

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@jdisanti
Copy link
Contributor

jdisanti commented Oct 2, 2023

Glad to hear you figured it out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

No branches or pull requests

4 participants