如何在 serverless.yml 中使用 lambda 的条件配置?

Zha*_* Yi 5 amazon-web-services aws-lambda serverless-framework

我需要配置 lambda viaserverless.yml以针对不同环境使用不同的配置并发。下面是我的 lambda 配置:

 myLambda:
   handler: src/lambdas
   name: myLambda
   provisionedConcurrency: ${self:custom.pc}

...

custom:
  pc: ${env:PC}
Run Code Online (Sandbox Code Playgroud)

PC 值是从环境变量加载的。它适用于大于 0 的值,但我无法0在一种环境中设置值。我想要做的是禁用dev环境中的配置并发。

我已阅读此文档https://forum.serverless.com/t/conditional-serverless-yml-based-on-stage/1763/3,但它似乎对我的情况没有帮助。

如何provisionedConcurrency根据环境设置条件?

Far*_*ley 5

方法 1:通过默认值实现基于阶段的变量

这是使用级联值变量的相当简单的技巧。第一个值是您想要的值,第二个值是默认值或后备值。也称为级联变量。

// serverless.yml
provider:
  stage: "dev"

custom:
  provisionedConcurrency:
    live: 100
    staging: 50
    other: 10

 myLambda:
   handler: src/lambdas
   name: myLambda
   provisionedConcurrency: ${self:custom.provisionedConcurrency.${self:provider.stage}, self:custom.provisionedConcurrency.other}
Run Code Online (Sandbox Code Playgroud)

上面的 stage 设置为 dev 将默认为“其他”值 10,但如果你设置 stage viaserverless deploy --stage live那么它将使用实时值 100。

有关更多详细信息,请参阅此处: https: //www.serverless.com/framework/docs/providers/aws/guide/variables#syntax

方法 2:通过 Javascript 异步值

您可以使用 js include 并将条件逻辑放在那里。这称为“异步值支持”。基本上,这允许您将逻辑放入您包含的 JavaScript 文件中,并且它可以根据各种情况返回不同的值(例如,您所在的 AWS 账户,或者是否设置了某些变量,等等)。基本上,它允许你这样做......

provisionedConcurrency: ${file(./detect_env.js):get_provisioned_concurrency}
Run Code Online (Sandbox Code Playgroud)

如果您在此文件夹中创建一个名为 detector_env.js 的 javascript 文件,并且它的内容类似于...

module.exports.get_provisioned_concurrency = () => {
  if ("put logic to detect which env you are deploying to, eg for live") {
    return Promise.resolve('100');
  } else {
    // Otherwise fallback to 10
    return Promise.resolve('10');
  }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅: https: //www.serverless.com/framework/docs/providers/aws/guide/variables#with-a-new-variables-resolver

我觉得我必须在这里回复,尽管这是几个月前提出的,因为没有一个答案与正确答案相差甚远,我真的为作者或来到这里的任何人感到抱歉。


Tob*_*bin 1

对于真正棘手的问题,我发现转至 Cloudformation 脚本并使用 Cloudformation 内部函数非常有用。

对于这种情况,如果您知道可以使用的所有环境Fn::FindInMap

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html

或者,如果只是生产需要 0,那么您可以在 Cloudformation 模板中使用条件Fn::If和布尔测试来测试环境是否等于生产,使用 0,否则使用 SLS 中的模板化值。Condition

潜在的 SLS:

resources:
  Conditions:
    UseZero: !Equals ["production", ${provider.stage}]
  Resources:
    myLambda:
      ProvisionedConcurrency: !If [UseZero, 0, ${self:custom.pc}]
Run Code Online (Sandbox Code Playgroud)

ProvisionedConcurrency如果需要,您也可以显式删除该属性:

resources:
  Conditions:
    UseZero: !Equals ["production", ${provider.stage}]
  Resources:
    myLambda:
      ProvisionedConcurrency: !If [UseZero, AWS::NoValue, ${self:custom.pc}]
Run Code Online (Sandbox Code Playgroud)

编辑:您仍然可以使用SLS进行部署;它只是编译成 Cloudformation JSON 模板,您可以使用 SLSresources字段显式修改该模板。