Lambda parameter from Secret Manager🤫
Tags: aws, serverless, go, lambda
Published: 2023-08-19 13:54:25

Hey everyone, I'm back and ready to dive into some Serverless func with AWS Lambda. Today, I've set myself a cool goal: I want to figure out how to use a Lambda function to grab a secret credential from AWS Secret Manager, you know, the stuff that's locked up tight by AWS KMS service. I'm all about learning how Lambda can smoothly handle secrets from Secret Manager and whatever other secret stashes are out there.

Alright, check it out. This lab is hooking me up with some sweet Golang code. It's like magic – this code can summon that parameter from Secret Manager and stash it in Lambda’s memory, all sorted out by the code itself. Talk about slick, right? So, here's to cracking open the door to the secrets realm, and getting cozy with Lambda's skills and the hidden treasures they can unlock. Let's rock this journey! 🚀

## Required Golang library

1. [github.com/aws/aws-lambda-go/lambda](http://github.com/aws/aws-lambda-go/lambda)
2. [github.com/aws/aws-secretsmanager-caching-go/secretcache](http://github.com/aws/aws-secretsmanager-caching-go/secretcache)
3. errors
4. log
5. os

## Coding

Create a new Golang project.

```bash
go mod init $YOUR_PROJECT_NAME
# Example
go mod init lamda-secret
```

Let’s start with first function to ask Lambda handle it.

```go
func main() {
	// Parameter in Start(...) is func name to handled
	lambda.Start(ExportSecret)
}
```

Create a function to export your secret value

```go
func ExportSecret() {
	// Define new variable for cache object
	sc, _ := secretcache.New()

	// Get a result from getter function and logged it
	word, _ := GetterSecret(sc)
	log.Printf("We have a secret word is %s", word)
}
```

Create a function that get secret from Secret Manager API into cache memory

```go
func GetterSecret(sc *secretcache.Cache) (string, error) {
	// Request secret from SecretManager API with Secret ID from ENV
	secr, err := sc.GetSecretString(os.Getenv("SECRET_WORD_ID"))
	if err != nil {
		return "", errors.New("Can't get you secret")
	}
	return secr, nil
}
```

Build and upload them to S3 bucket

```bash
export BINARY_NAME="lsc"
export GOOS="linux"
export GOARCH="amd64"
export CGO_ENABLED="0"
export S3_BUCKET_NAME=$(aws s3api list-buckets --query 'Buckets[0].Name' --output text)

# Build binary file from code
go build -o $BINARY_NAME lamda-secret

# Compress this file into ZIP format
zip ../../lambda-$BINARY_NAME.zip $BINARY_NAME

# Upload to s3 with aws cli
aws s3api put-object --bucket $S3_BUCKET_NAME --key lambda-$BINARY_NAME.zip --body ./lambda-$BINARY_NAME.zip
```

## Proof your result

Create AWS lambda function and upload your ZIP binary file. Example CLI to create 

```bash
aws lambda create-function \
--function-name YourFunctionName \
--runtime go1.x \
--role your-iam-role-arn \
--handler your-bin-name \
--zip-file s3-url-with-zip
```

Manual trigger to Lambda function and you can see result on CloudWatch log group.

```bash
aws lambda invoke \
--function-name YourFunctionName
```

!! Before execute function you should attach IAM role to Lambda and that role will provide below permission.

```bash
{
    "Id": "AllowLambdaAccessSecret",
    "Statement": [
        {
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Sid": "AllowLambdaAccessToSecretManager"
        },
        {
            "Action": [
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:Decrypt"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:kms:ap-southeast-1:xxxxxx:key/xxxxx-xxx-xxxx-xxxx-xxxxxd96cc",
            "Sid": "AllowLambdaAccessToKMSKey"
        }
    ],
    "Version": "2012-10-17"
}
```

Or you can create and invoke function via web console

![Lambda test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f91gv1teh46720vd5ypx.png)

## Reference

1. https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_cache-go.html
2. https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_cache-go_cache.html
3. https://docs.aws.amazon.com/lambda/latest/dg/golang-logging.html

## Conclusion

👾 Handling secrets within a Lambda function becomes a breeze with the assistance of the AWS SDK. This concept can be seamlessly extended to explore alternative techniques, such as accessing retained secrets, orchestrating secret updates, or even orchestrating the deletion of secrets through automated processes.

Excitingly, my forthcoming blog will delve into the practical implementation of the aforementioned functionalities, all achievable with a single click using the powerful tool that is Terraform. Stay tuned for the upcoming content! Catch you later! ✌️😋