我们正在尝试使用Amazon CloudFormation和Swagger自动部署AWS lambda和API网关。为此,我们创建了一个CloudFormation模板来创建APIGateway所需的Lambda和其他资源(包括端点)。我们希望从外部swagger文件导入API定义,以便相同的CloudFormation模板可用于多个lambda和APIGateways。有没有办法可以在外部swagger文件(在同一个CloudFormation模板中引用)中引用由CloudFormation模板创建的lambda的ARN来保存API定义?
Swagger内容:
"x-amazon-apigateway-integration": {
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:TestSimpleProxy/invocations",
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"type": "aws_proxy"
}
在上面的集成方法中,我需要从云形成模板中动态替换uri的值。
我的云形成脚本如下:
"myApi":{
"Type" : "AWS::ApiGateway::RestApi",
"Properties" : {
"BodyS3Location" : S3Location of the swagger definition file,
..,
..
}
}
答案 0 :(得分:6)
新解决方案:
现在可以使用新的AWS::Include
Transform直接从CloudFormation模板引用上传的模板:
Api:
Type: AWS::ApiGateway::RestApi
Properties:
Body:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: !Sub s3://${ArtifactsBucket}/swagger.yaml
其中ArtifactsBucket
是指在创建或更新堆栈之前上载Swagger规范的存储桶。然后,在Swagger模板中,您可以使用内在函数,例如
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations
我在这里使用长Fn::Sub
符号而不只是!Sub
,因为Swagger本身不支持后者,也因为AWS::Include
上的文档变换说不支持速记形式。
如果您使用SAM,也可以使用AWS::Serverless::Api
和DefinitionBody
。
旧的解决方法:
另一个(有点hacky,但很简单)的解决方案是将Api列为CloudFormation模板中的最后一个资源,并在末尾指定一个带有: !Sub |-
的空正文。
然后,您可以将此模板与实际的Swagger文件连接,并使用该文件中的标准${}
语法引用任何参数。
唯一的小问题是,当你使用YAML连接时,你必须正确缩进Swagger文件(这种方法不适用于JSON模板;你必须替换如果您使用这些内容,请使用jq
之类的内容。
答案 1 :(得分:1)
还有另一种不太复杂的方法。如果您使用Body
属性而不是BodyS3Location
AWS::ApiGateway::RestApi
,则可以使用Cloud Formation Instrinsic Functions来引用或动态构建您在swagger模板中所需的ARN。
...当然缺点是你的招摇模板嵌入在CF脚本中而不是单独的文件中。
答案 2 :(得分:0)
这是您的CloudFormation模板的"x-amazon-apigateway-integration"
部分吗?
如果是这样,那么请关注https://blog.jayway.com/2016/09/18/introduction-swagger-cloudformation-api-gateway/中的示例,我认为您可以使用Ref函数传递该信息。
答案 3 :(得分:0)
我遇到了同样的障碍......这是 NOT 一个简单的答案,但是一种解决方法可以自动解决你想要使用的Lambda ARN招摇模板;它对我有用。这就是......
导出创建Lambda的CF模板中的Lambda ARN,以及稍后要在swagger模板中使用的内容,例如
。Outputs:
MyLambdaARN:
Value: !Ref "LambdaFuncThatIsDefinedInTheTemplate"
Export:
Name: !Sub "${AWS::StackName}-LambdaARN"
请参阅招摇模板中的Lambda ARN导出 - 代替lambda的ARN ,输入可替换令牌包括步骤1中的导出名称,例如“MyLambdaStack-LambdaARN”,如果您将步骤1中的堆栈创建为“MyLambdaStack”。
!ImportValue(MyLambdaStack-LambdaARN)
。在我们的招摇模板中,集成扩展程序使用我们的令牌:
x-amazon-apigateway-integration:
passthroughBehavior: "when_no_match"
uri: "!ImportValue(MyLambdaStack-LambdaARN)"
httpMethod": "POST"
type: "AWS-PROXY"
用实际Lambda ARN替换令牌 - 我们将使用以下脚本将!ImportValue(MyLambdaStack-LambdaARN)
令牌替换为我们需要的实际Lambda ARN。
#!/bin/bash
SWAGGER_FILE=$1
REPLACEMENTS=$( \
aws cloudformation list-exports --query 'Exports[*].[Name,Value]'\
| awk '{print "s/!ImportValue(" $1 ")/" $2 "/g"}' ORS='; '\
)
sed "$REPLACEMENTS" "$SWAGGER_FILE"
这是这个脚本的作用
aws cloudformation list-exports
--query 'Exports[*].[Name,Value]'
参数awk '{print "s/!ImportValue(" $1 ")/" $2 "/g"}' ORS='; '
sed
将swagger文件中的替换作为脚本的第一个参数传入。例如,如果您将此脚本创建为resolve-arns.sh
,则可以按如下方式调用它:
./resolve-arns.sh swagger.yml > resolved-swagger.yml
引用已解决的Swagger定义 - 最后,您将引用您用于创建API的CF模板中的resolved-swagger.yml
文件,例如BodyS3Location: resolved-swagger.yml
<强>注意事项:强>
aws
命令行工具需要可用且已配置