【问题标题】:Passing secrets to lambda during deployment stage (CodePipeline) with Serverless?在使用无服务器的部署阶段(CodePipeline)将秘密传递给 lambda?
【发布时间】:2020-05-02 08:24:15
【问题描述】:

我有一个以 GitHub 为源的 CodePipeline,已设置。我试图在 CodePipeline 执行的部署阶段将单个秘密参数(在本例中为 Stripe 密钥,当前在 .env 文件中定义-> 下面的解释)传递给特定的 Lambda,但没有成功。

在我的例子中,部署阶段基本上是一个运行 deployment.sh 脚本的 CodeBuild 项目:

#! /bin/bash npm install -g serverless@1.60.4 serverless deploy --stage $env -v -r eu-central-1

解释:

我已经尝试使用 serverless-dotenv-plugin 执行此操作,它可以在本地完成部署时达到目的,但是当通过 CodePipeline 完成时,它会在 lambda 的执行中返回错误,原因如下:

由于 CodePipeline 的 Source 设置为 GitHub(.env 文件未提交),因此每当将更改提交到 git 存储库时,就会触发 CodePipeline 的执行。当它到达部署阶段时,所有节点模块都已安装(serverless-dotenv-plugin 连同它们),当serverless deploy --stage $env -v -r eu-central-1 命令执行时 serverless-dotenv-plugin 将搜索存储我的秘密的 .env 文件,赢了找不到它,因为没有 .env 文件,因为我们超出了“本地”范围,并且当 lambda 需要此秘密触发器时,它会抛出如下所示的错误:

所以我的问题是,是否可以使用 dotenv/serverless-dotenv-plugin 来做到这一点,还是应该放弃这种方法?我应该使用 SSM Parameter Store 还是 Secrets Manager?如果是的话,有人可以解释一下吗? :)

【问题讨论】:

    标签: aws-lambda aws-codepipeline aws-serverless dotenv ssm


    【解决方案1】:

    因此,在进一步调查该主题后,我认为我有解决方案。 SSM 参数存储与 Secrets Manager 是一个完全不同的主题,但就我的目的而言,SSM 参数存储是我为解决此问题而选择的选择。基本上它可以通过两种方式完成。

    1.使用 AWS 参数存储

    只需在您的 AWS Parameter Store 控制台中添加一个密钥,然后将您的 serverless.yml 中的值引用为 Lambda 环境变量。无服务器框架能够在部署时从您的 AWS Parameter Store 帐户中获取值。

    provider: environement: stripeSecretKey: ${ssm:stripeSecretKey}

    最后,您可以像以前一样在代码中引用它:

    const stripe = Stripe(process.env.stripeSecretKey);

    优点:这可以与本地 .env 文件一起用于本地和远程使用,同时保持 Lambda 代码相同,即。 process.env.stripeSecretKey

    缺点:由于机密被解密,然后在部署时设置为 Lambda 环境变量,因此如果您转到 Lambda 控制台,您将能够以纯文本形式查看机密值。 (这有点表明一些安全问题)

    这让我想到了第二种方法,我发现它更安全,我最终选择了它:

    2。存储在 AWS Parameter Store 中,并在运行时解密 为避免在 AWS Lambda 控制台中以纯文本形式公开机密,您可以改为在运行时解密它们。方法如下:

    • 与上述步骤一样,在您的 AWS Parameter Store 控制台中添加密钥。

    • 更改您的 Lambda 代码以直接调用 Parameter Store 并在运行时解密该值:

      import stripePackage from 'stripe'; const aws = require('aws-sdk'); const ssm = new aws.SSM();

      const stripeSecretKey = ssm.getParameter( {Name: 'stripeSecretKey', WithDecryption: true} ).promise(); const stripe = stripePackage(stripeSecretKey.Parameter.Value);

    (小提示:如果您的 Lambda 被定义为异步函数,请确保在 ssm.getParameter(.. .).promise();)

    优点:您的秘密在任何时候都不会以纯文本形式公开。

    缺点:您的 Lambda 代码确实有点复杂,并且由于需要从存储中获取值,因此会增加延迟。 (但考虑到它只是一个参数而且是免费的,我想这是一个很好的权衡)

    对于结论,我只想提一下,所有这一切都需要您调整 lambda 的策略,以便它可以访问 Systems Manager 和您存储在 Parameter Store 中的密钥,但可以通过 CloudWatch 轻松检查。

    p>

    希望这可以帮助某人,愉快的编码:)

    【讨论】:

    • 只是想补充一下,还有第三个选项。无服务器框架具有带有免费层的 Pro 包,它基本上允许您通过将代码合并到适当的分支中来将自动部署设置到您选择的多个环境(暂存、开发、生产等)中。 dashboard.serverless.com
    • @GarethMcCumskey 感谢您提供的信息,以后一定会在某个地方尝试一下!
    猜你喜欢
    • 2021-10-04
    • 2019-03-06
    • 2023-03-28
    • 2017-03-16
    • 2019-04-24
    • 2021-11-03
    • 1970-01-01
    • 2022-01-20
    • 2021-09-16
    相关资源
    最近更新 更多