2

playing with a small project on AWS:

  • golang app
  • RDS/MySQL database
  • secret manager
  • API gateway and lambda

I'm running the go app locally to verify the interaction with the database, but I can't get it to work with the secret manager.

using this sample code:

func getCreds() {
    config, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
    if err != nil {
        log.Fatal(err)
    }

    svc := secretsmanager.NewFromConfig(config)
    input := &secretsmanager.GetSecretValueInput{
        SecretId:     aws.String(secretName),
        VersionStage: aws.String("AWSCURRENT"),
    }

    result, err := svc.GetSecretValue(context.TODO(), input)
    if err != nil {
        log.Fatal(err.Error())
    }

    var secretString string = *result.SecretString
    log.Printf("pwd: %s", secretString)
}

I'm getting

operation error Secrets Manager: GetSecretValue, exceeded maximum number of attempts, 3, failed to sign request: failed to retrieve credentials: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds

If I understand correctly, I need to add a permission to a user/policy. But where to add this? In the IAM console? Or the secret manager console?

And what should it be?

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Principal": {"AWS": "<what to add here>"},
            "Resource": "<and here>"
        }
    ]
}
mbmc
  • 5,024
  • 5
  • 25
  • 53

1 Answers1

0

The Go Application doesn't find the credentials to use the AWS API.

According to (Configuring Credentials) you can use this code to automagically use ~/.aws/config for credentials locally

sess := session.Must(session.NewSessionWithOptions(session.Options{
    SharedConfigState: session.SharedConfigEnable,
}))

if you supply a custom config, the credentials must be supplied. There are other methods, pick one that suits you. AWS proposes the method above.

This covers running with your users. For AWS execution you need to give the Lambda function access to the secret:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-west-2:111122223333:secret:aes128-1a2b3c"
            ]
        }
}

The above policy must be applied to the IAM Role the Lambda is executed with. You can find the role AWS Console -> Lambda -> You Lambda -> Configuration -> Permissions -> Execution Role

Augunrik
  • 1,866
  • 1
  • 21
  • 28
  • Thanks for the answer. The last missing piece was adding an endpoint to the VPC https://aws.amazon.com/blogs/security/how-to-connect-to-aws-secrets-manager-service-within-a-virtual-private-cloud/#:~:text=Open%20the%20Amazon%20VPC%20console,Manager%20endpoint%20service%20named%20com. – mbmc Mar 22 '23 at 17:56
  • True. If lambdas are not connected to VPCs, they have internet access and can access the secrets manager. If they are put into a VPC, they adhere to the VPC networking. If internet access is missing, you need an interface endpoint for all AWS services you are trying to connect (including SM). – Augunrik Mar 23 '23 at 05:11