Amazon web services 如何在SAM模板中设置阶段名称
我想在SAM template.yaml中设置API网关的阶段名称。 但无论我尝试什么,我都不会成功。在不尝试命名我的stage的情况下,一切都按预期进行,但默认的stage名称为Prod和stage 我的sam cli版本是0.47.0 我确实在Stackoverflow上找到了三个类似的问题,但没有一个答案适合我Amazon web services 如何在SAM模板中设置阶段名称,amazon-web-services,sam,Amazon Web Services,Sam,我想在SAM template.yaml中设置API网关的阶段名称。 但无论我尝试什么,我都不会成功。在不尝试命名我的stage的情况下,一切都按预期进行,但默认的stage名称为Prod和stage 我的sam cli版本是0.47.0 我确实在Stackoverflow上找到了三个类似的问题,但没有一个答案适合我 我总是会遇到这样的错误: Unresolved resource dependencies [ServerlessRestApi] in the Outputs bloc
Unresolved resource dependencies [ServerlessRestApi] in the Outputs block of the template
那么,我如何获得我自己选择的艺名呢。我不在乎Prod和Stage是否与我选择的名字共存
为了完整起见,我的template.yaml文件如下:
AWSTemplateFormatVersion:'2010-09-09'
转换:AWS::Serverless-2016-10-31
说明:>
sam应用程序
SAM应用程序的SAM模板示例
全球:
功能:
超时:3
应用程序编程接口:
Cors:
AllowMethods:“‘期权,看跌期权’”
AllowHeaders:“'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'”
AllowOrigin:“'*'”
资源:
HelloWorldFunction:
类型:AWS::Serverless::Function
特性:
你好,世界/
处理程序:app.lambdaHandler
运行时:nodejs12.x
活动:
HelloWorld:
类型:Api
特性:
路径:/hello world
方法:将
产出:
HelloWorldApi:
描述:“Hello World函数的Prod阶段的API网关端点URL”
值:!Sub“https://${ServerlessRestApi}.execute api.${AWS::Region}.amazonaws.com/dev/hello world/”
HelloWorldFunction:
描述:“Hello World Lambda函数ARN”
值:!GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIAM角色:
描述:“为Hello World函数创建的隐式IAM角色”
值:!GetAtt HelloWorldFunctionRole.Arn
我可能不理解这背后的预期工作流程。当API网关指向的lambda函数相同时,为什么有两个阶段名称
我将使用“dev”和“prod”环境,但它们将使用不同的堆栈名称,因此我永远不会混淆不同的环境
我总是使用deploy-dev.sh和deploy-pod.sh脚本,在实际部署之前检查我是否在开发或主(生产)分支。因此,这些脚本将指向不同的template.yaml文件,因为它们是从不同的git分支调用的。我使用这种方式进行部署已经有很长时间了,而且对我来说效果很好
旁注:为什么现有的舞台名称以大写字母开头?它看起来既丑陋又不寻常。所以我找到了自己的答案,这是我在StackOverflow上找到的问题的两个答案的组合,我在问题中提到了这两个问题 我还是不明白为什么这件事这么复杂 我在template.yaml文件的顶层添加了一个参数。严格来说,不需要使用参数。我添加了这个,这样我就可以有一个从deploy-dev.sh和deploy-prod.sh脚本调用的模板文件。 以下是参数声明:
Parameters:
Stage:
Type: String
Default: dev
然后,在Resources组下,我添加了一个新的ApiDeployment资源。您使用的名称完全取决于您,只要您在其他地方使用完全相同的名称!添加此资源的唯一原因是不允许您在函数事件的Api部分的属性中简单地使用StageName。也不允许将StageName放在Globals Api部分中
正如我在问题中提到的,我收到了一些错误,抱怨yaml文件的输出部分。事实证明,输出部分无论如何都是可选的。所以当我把它评论出来时,一切都正常了
但是我在部署脚本中使用了output部分来显示API网关的URL,因此通过一些尝试,我也实现了这一点。
错误是在第四行中造成的。它最初有${ServerlessRestApi}。只需将其替换为我添加到yaml文件中的新资源名:${ApiDeployment},一切正常
Outputs:
ApiDeployment:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ApiDeployment}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/hello-world/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
因为我在yaml文件中使用了一个参数,所以需要使用参数名称和值调用sam deploy。与许多AWS文档一样,它的确切语法非常隐蔽。因此,以下是开始部署的方式:
sam deploy --parameter-overrides "ParameterKey=Stage,ParameterValue=dev"
您可能在API网关控制台的Stage下仍有Stage,但您可以删除它而不会产生任何影响
为了完整起见,这里是我的完整template.yaml文件,顺便说一句,它是执行sam init时得到的文件
这里是一个更新为任何人登陆这个问题 我不再使用山姆了。我切换到AWS CDK。 CDK允许您用代码定义整个AWS基础设施! 您可以使用Javascript、Typescript、Python、C#和Java,尽管大多数示例似乎都是用Typescript编写的 这不是一个很容易的转变,但它是值得的。山姆似乎是一条死胡同 SAM仅涵盖AWS提供的所有产品的一小部分,但CDK涵盖了所有产品 这是一个全新的、移动的目标,加上开发人员对破坏更新毫不在意,因为他们仍然在模块之间移动东西 但几天后,您将开始掌握它,它具有无限的灵活性,因为您正在使用普通编程语言来设置API网关、lambda、自定义域、IAM规则等。 它也非常紧凑(与SAM模板相比) 我使用它来根据我所在的got分支拥有不同的staging和production堆栈。因此,当我在repo位于dev分支上时进行部署时,我将拥有一个不同的环境(包括不同的域名等),然后从master或prod分支进行部署。不同服务的名称也不同,这取决于git分支 要部署,只需运行“cdk部署” 要开始学习,请观看这个出色的研讨会: 下面是此分支切换的示例。我只展示部分
Outputs:
ApiDeployment:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ApiDeployment}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/hello-world/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
sam deploy --parameter-overrides "ParameterKey=Stage,ParameterValue=dev"
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app: Sample SAM Template for sam-app
Parameters:
Stage:
Type: String
Default: dev
Globals:
Function:
Timeout: 3
Api:
Cors:
AllowMethods: "'OPTIONS,PUT'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowOrigin: "'*'"
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs12.x
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello-world
Method: put
RestApiId: !Ref ApiDeployment
ApiDeployment:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
Outputs:
ApiDeployment:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ApiDeployment}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/hello-world/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
import * as branchName from 'current-git-branch'
const branch = branchName()
/*-------- This is the development stack --------*/
export class StripePaymentsDev extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props)
if (branch !== 'dev') {
throw new Error('Not on dev branch')
}
// Env vars from Parameter Store
const STRIPE_PUBLIC = StringParameter.valueForStringParameter(this, `/${branch}/STRIPE_PUBLIC`)
const STRIPE_SECRET = StringParameter.valueForStringParameter(this, `/${branch}/STRIPE_SECRET`)
const STRIPE_API_VERSION = StringParameter.valueForStringParameter(this, `/${branch}/STRIPE_API_VERSION_PAYMENTS`)
// Names for the dev environment
const domainMapName = 'PaymentsDev'
const eventBusName = 'WebhooksBusDev'
const ruleName = 'WebhooksRuleDev'
const eventBus = new EventBus(stackScope, eventBusName, { eventBusName })
const cert = Certificate.fromCertificateArn(stackScope, certName, certArn)
const stackScope = this
// IAM rules
const lambdaPolicy = new iam.PolicyStatement({
actions: ['events:*'],
resources: ['*']
})
const sqsPolicy = new iam.PolicyStatement({
actions: ['sqs:*'],
resources: ['*']
})
const webhooks = new lambda.Function(stackScope, lambdaWebhooksName, {
runtime: lambda.Runtime.NODEJS_12_X,
code: lambda.Code.fromAsset('webhook-handler'),
handler: 'webhooks.handler',
timeout: Duration.seconds(600),
description: 'Processes Stripe Webhooks',
retryAttempts: 0,
environment: {
STRIPE_PUBLIC,
STRIPE_SECRET,
STRIPE_API_VERSION,
MONGO_URL,
MONGO_DB,
MONGO_PORT,
DEBUG
}
})
webhooks.addToRolePolicy(sqsPolicy)
const rule = new Rule(stackScope, ruleName, {
description: 'Triggers lambda to process stipe webhooks',
enabled: true,
eventBus: eventBus,
eventPattern: {
detailType: ['transaction'],
source: ['custom.payments']
},
ruleName: ruleName
})
rule.addTarget(new eventTargets.LambdaFunction(webhooks))
new HttpApi(stackScope, apiName, {
defaultIntegration: new LambdaProxyIntegration({ handler: payments }),
defaultDomainMapping: {
domainName: new DomainName(stackScope, domainMapName, {
domainName: PAYMENT_DOMAIN,
certificate: cert
})
}
})
}
}
AWSTemplateFormatVersion: 2010-09-09
Description: >-
app-sam
Transform:
- AWS::Serverless-2016-10-31
# ====================================
# PARAMETERS SETUP
# ====================================
Parameters:
StageName:
Type: String
Default: dev
Description: (Required) Enter dev, prod. Default is dev.
AllowedValues:
- dev
- prod
ProjectName:
Type: String
Default: sam-api
Description: (Required) The name of the project
MinLength: 3
MaxLength: 50
AllowedPattern: ^[A-Za-z_-]+$
ConstraintDescription: "Required. Can be characters, hyphen, and underscore only. No numbers or special characters allowed."
ExistingTable:
Type: String
Default: example-table
Description: (Required) The name of existing DynamoDB
MinLength: 3
MaxLength: 50
AllowedPattern: ^[A-Za-z_-]+$
ConstraintDescription: "Required. Can be characters, hyphen, and underscore only. No numbers or special characters allowed."
# ====================================
# GLOBAL SETUP
# ====================================
Globals:
Api:
OpenApiVersion: 3.0.1
Function:
Runtime: nodejs14.x
Timeout: 180
MemorySize: 256
Environment:
Variables:
TABLE_NAME: !Ref ExistingTable
Resources:
# Reference this one to overwrite implicit stage
# https://github.com/aws/serverless-application-model/issues/191#issuecomment-580412747
RestApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ProjectName
StageName: !Ref StageName
# This is a Lambda function config associated with the source code: get-all-items.js
getAllItemsFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/get-all-items.getAllItemsHandler
Description: A simple example includes a HTTP get method to get all items from a DynamoDB table.
Policies:
# Give Create/Read/Update/Delete Permissions to the ExistingTable
- DynamoDBCrudPolicy:
TableName: !Ref ExistingTable
Events:
Api:
Type: Api
Properties:
Path: /
Method: GET
RestApiId: !Ref RestApi
Outputs:
WebEndpoint:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/${StageName}/"