如何在部署到AWS Lambda的Go函数中处理密钥

huangapple go评论82阅读模式
英文:

How to handle secrets in a Go function deployed to AWS Lambda

问题

我有一个在本地工作的函数,还有一个使用Viper加载到应用程序中的配置文件,我还设置了viper.AutomaticEnv()

在部署到AWS Lambda后,似乎环境变量被忽略了。我去了Viper的问题页面,找到了这个链接:https://github.com/spf13/viper/issues/584

看起来Viper需要加载一个配置文件,否则它将停止工作,即使我们可以设置环境变量。

你如何处理Go中本地开发与Lambda部署的秘密?

如果可能的话,我想避免使用AWS Secrets Manager。

英文:

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

答案1

得分: 1

在AWS Lambdas中处理密钥有很多选项。我建议不要使用Viper或其他类似的工具。构建一个从环境变量中读取配置的Lambda函数很简单。

另外,我建议从AWS SSM参数存储中读取密钥。

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("无法读取环境变量 'SECRET'")
	}

	return configuration{
		secret: secret
	}, nil
}

func main() {
	cfg, err := newConfig()
	if err != nil {
		fmt.Printf("无法创建配置: %v\n", err)
		os.Exit(1)
	}

	h := handler{
		config: cfg,
	}

	lambda.Start(h.handleRequest)
}

没有必要使用Viper并且不必要地增加二进制文件的大小。记住:二进制文件越大,冷启动时间越长。

如何处理Go中Lambda密钥的本地开发与部署?

通常,我们只在本地使用单元测试,这些测试使用不需要密钥的模拟服务。大部分的“集成”测试在AWS上完成。每个开发人员都有自己的“环境”可以进行部署。为了管理这个,我们使用Terraform。

如果你真的需要在本地测试某些东西,我建议创建一个测试文件,并将其添加到.gitignore文件中,以避免提交它。在这个文件中,你可以直接硬编码密钥。

例如,你可以创建一个名为playground_test.go的文件,并在.gitignore文件中忽略它。

英文:

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.

huangapple
  • 本文由 发表于 2022年3月9日 15:20:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/71405633.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定