如何使用 AWS 上的无服务器框架获得可选资源
How to have optional resources with Serverless framework on AWS
问题:在基于 Lambda 的无服务器框架上获得可选资源的最佳方式是什么?
我想让 Serverless 关心 Lambda 在较低环境(开发、测试、暂存)中需要的资源,并在较高环境(如生产)中拥有独立的资源。
我正在考虑使用类似
的东西
resources:
Resources: ${file(../${self:provider.stage}-resources.yml)}
我的资源yml如下:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:service}-${self:provider.stage}-queue
SNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: TEST SNS Topic
TopicName: ${self:service}-${self:provider.stage}-topic
SNSSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: mail@email.com
Protocol: email
TopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:resources.Resources.SNSTopic.Properties.TopicName}" ] ] }
但它不起作用。关于实现该目标的最佳做法有什么想法?
替换这个:
TopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:resources.Resources.SNSTopic.Properties.TopicName}" ] ]
有了这个:
TopicArn: {"Ref" : "SNSTopic"}
解决了我的问题。
问题中的描述侧重于将所有资源放在一个资源文件中,并在每个阶段使用不同的此类文件。这可行,但有一个限制,即您必须在每个阶段至少放置一个资源。并且还迫使您将资源组合在一起。
我在 serverless.yml
中使用的另一种包含可选资源的方法如下:
provider:
name: aws
stage: ${opt:stage, 'dev'}
resources:
- ${file(./sls-resources/mandatory-resource.yml)}
- ${file(./sls-resources/optional-resource.${self:provider.stage}.yml), ''}
然后,您只需创建 optional-resource.prod.yml
来保存您的生产专用资源。 Serverless 在为 dev 阶段生成模板时,由于文件不存在,将可选引用解析为空元素,然后忽略它。
注意我使用阶段变量作为示例,但它可以是任何其他变量,例如区域或自定义变量。
问题:在基于 Lambda 的无服务器框架上获得可选资源的最佳方式是什么?
我想让 Serverless 关心 Lambda 在较低环境(开发、测试、暂存)中需要的资源,并在较高环境(如生产)中拥有独立的资源。
我正在考虑使用类似
的东西resources:
Resources: ${file(../${self:provider.stage}-resources.yml)}
我的资源yml如下:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:service}-${self:provider.stage}-queue
SNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: TEST SNS Topic
TopicName: ${self:service}-${self:provider.stage}-topic
SNSSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: mail@email.com
Protocol: email
TopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:resources.Resources.SNSTopic.Properties.TopicName}" ] ] }
但它不起作用。关于实现该目标的最佳做法有什么想法?
替换这个:
TopicArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:provider.region}:", { "Ref" : "AWS::AccountId" }, ":${self:resources.Resources.SNSTopic.Properties.TopicName}" ] ]
有了这个:
TopicArn: {"Ref" : "SNSTopic"}
解决了我的问题。
问题中的描述侧重于将所有资源放在一个资源文件中,并在每个阶段使用不同的此类文件。这可行,但有一个限制,即您必须在每个阶段至少放置一个资源。并且还迫使您将资源组合在一起。
我在 serverless.yml
中使用的另一种包含可选资源的方法如下:
provider:
name: aws
stage: ${opt:stage, 'dev'}
resources:
- ${file(./sls-resources/mandatory-resource.yml)}
- ${file(./sls-resources/optional-resource.${self:provider.stage}.yml), ''}
然后,您只需创建 optional-resource.prod.yml
来保存您的生产专用资源。 Serverless 在为 dev 阶段生成模板时,由于文件不存在,将可选引用解析为空元素,然后忽略它。
注意我使用阶段变量作为示例,但它可以是任何其他变量,例如区域或自定义变量。