我们正在尝试使用Amazon CloudFormation和Swagger自动部署AWS lambda和API网关 . 为此,我们创建了一个CloudFormation模板来创建APIGateway所需的Lambda和其他资源(包括 endpoints ) . 我们想从外部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"
}
在上面的集成方法中,我需要从 Cloud 形成模板中动态替换uri的值 .
我的 Cloud 形成脚本如下:
"myApi":{
"Type" : "AWS::ApiGateway::RestApi",
"Properties" : {
"BodyS3Location" : S3Location of the swagger definition file,
..,
..
}
}
4 回答
New solution:
现在可以使用新的AWS::Include Transform直接从CloudFormation模板引用上传的模板:
其中
ArtifactsBucket
指的是在创建或更新堆栈之前上载Swagger规范的存储桶 . 然后,在Swagger模板中,您可以使用内在函数,例如这里我使用的是长
Fn::Sub
符号而不仅仅是!Sub
,因为Swagger本身并不支持后者,也因为AWS::Include
Transform上的文档说不支持缩写形式 .如果使用SAM,也可以使用
AWS::Serverless::Api
和DefinitionBody
.Old workaround:
另一个(有点hacky,但很简单)解决方案是将Api列为CloudFormation模板中的最后一个资源,并在末尾指定一个带有
: !Sub |-
的空Body .然后,您可以将此模板与实际的Swagger文件连接,并使用该文件中的标准
${}
语法引用任何参数 .唯一的一个小问题是,当你为JSON模板工作时,你必须正确地缩进Swagger文件;如果你使用这些,你将不得不用
jq
替换Body .我只是碰到了同样的障碍......这不是一个简单的答案,而是一种解决方法,可以自动解决你在招摇模板中使用的Lambda ARN的问题;它对我有用 . 开始...
创建Lambda的
Refer to the Lambda ARN Export within the swagger template - 代替lambda的ARN,输入包含步骤1中的导出名称的可替换标记,例如"MyLambdaStack-LambdaARN",如果您将步骤1中的堆栈创建为"MyLambdaStack" .
对于令牌语法,让我们使用 wish 实际工作的内容ImportValue function,这样我们的令牌变为
!ImportValue(MyLambdaStack-LambdaARN)
.在我们的招摇模板中,集成扩展使用我们的令牌,如下所示:
!ImportValue(MyLambdaStack-LambdaARN)
标记替换为我们需要的实际Lambda ARN .这是这个脚本的作用
使用
aws cloudformation list-exports
抓取堆栈导出列表使用
--query 'Exports[*].[Name,Value]'
参数过滤到导出名称和值将导出格式化为一串sed替换,将使用
awk '{print "s/!ImportValue(" $1 ")/" $2 "/g"}' ORS='; '
替换实际导出值的标记值最后,使用
sed
将swagger文件中的替换作为脚本的第一个参数传入 .例如,如果您将此脚本创建为
resolve-arns.sh
,则可以按如下方式调用它:resolved-swagger.yml
文件,例如BodyS3Location: resolved-swagger.yml
CAVEATS:
当然
aws
命令行工具需要可用和配置此实现不够复杂,无法处理AWS区域参数......但可以对其进行修改
这是一个bash脚本......如果你're on a different OS like windows the same approach should work but the implementation would be different (I'从PowerShell开始可能......)
这是
"x-amazon-apigateway-integration"
您的CloudFormation模板的一部分吗?如果是这样,那么按照https://blog.jayway.com/2016/09/18/introduction-swagger-cloudformation-api-gateway/中的示例,我认为您可以使用Ref函数来传递该信息 .
还有另一种方法,即 less complicated 方法 . 如果使用
Body
属性而不是BodyS3Location
AWS::ApiGateway::RestApi
,则可以使用Cloud Formation Instrinsic Functions在swagger模板中引用或动态构建所需的ARN ....当然缺点是你的招摇模板嵌入在CF脚本中而不是单独的文件中 .