Home > Blockchain >  How to handle secrets in a Go function deployed to AWS Lambda
How to handle secrets in a Go function deployed to AWS Lambda

Time:03-10

I have a function that works locally and I have a config file that loads into the app using Viper, I also have viper.AutomaticEnv() set.

After deploying to AWS Lambda, seems like env vars are ignored. I went over to the Viper issues page and found this: https://github.com/spf13/viper/issues/584

Looks like Viper requires a config file to load or it will just stop working even though we can set env vars.

How do you handle local dev vs deployment for lambda secrets in Go?

I would like to avoid AWS Secrets Manager if possible

CodePudding user response:

There are a lot of options how to handle secrets in AWS Lambdas. I'd recommend to not use Viper or any of those tools. Building a Lambda that reads configuration from environment Lambdas is simple.

That said, I would also recommend reading secrets from AWS SSM parameter store.

main.go

func (h handler) handleRequest() error {
    fmt.Printf("My secret: %s", h.config.secret)

    return nil
}

type configuration struct {
    secret string
}

type handler struct {
    config configuration
}

func newConfig() (configuration, error) {
    secret, ok := os.LookupEnv("SECRET")
    if !ok {
        return configuration{}, errors.New("can not read environment variable 'SECRET'")
    }

    return configuration{
        secret: secret
    }, nil
}

func main() {
    cfg, err := newConfig()
    if err != nil {
        fmt.Printf("unable to create configuration: %v\n", err)
        os.Exit(1)
    }

    h := handler{
        config: cfg,
    }

    lambda.Start(h.handleRequest)
}

No need to use Viper and increase your binaries size unnecessarily. Remember: larger binary, longer cold-start time.

How do you handle local dev vs deployment for lambda secrets in Go?

Usually, we only use unit tests locally that use mocked services that do not require secrets. Most of the "integration" testing is done in AWS. Every developer has their own "environment" that they can deploy. To manage this we use Terraform.

If you really need to do test something locally, I'd recommend to create a test file that you do "gitignore" to avoid committing it. In this file I just hard-code the secret.

So for example, you can have a playground_test.go which you ignore in your .gitignore file.

  • Related