如何获取 Cloud Formation 特定资源 属性 的 AWS Lambda 函数的 ARN?
How do I get the ARN of an AWS Lambda function for a Cloud Formation specific resource property?
我似乎无法获得 Ref
或 Fn:GetAtt
到 return 用于设置资源的有效值。
serverless.yml
...etc...
functions:
bearerTokenAuthentication:
handler: app.bearerTokenAuthentication
name: ${self:service}-auth-bearer
resources:
- ${file(./serverless_resources.yml)}
serverless_resources.yml
Resources:
ApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Name: restapi-${self:provider.stage}
Description: Endpoints
ApiKeySourceType: HEADER # (to read the API key from the X-API-Key header of a request)
ApiGatewayBearerAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Type: token
IdentitySource: method.request.header.Authorization
Name: BearerAuthorization
AuthorizerResultTtlInSeconds: 300
AuthorizerUri: !Join #arn:aws:apigateway:${self:provider.region}:lambda:path/${self:functions.bearerTokenAuthentication.name}
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt
- bearerTokenAuthentication # also tried !Ref bearerTokenAuthentication and '${self:functions.bearerTokenAuthentication.name}'
- Arn
- /invocations
RestApiId: !Ref ApiGateway
无论我做什么,GetAtt
都找不到在 bearerTokenAuthentication
中声明的 Lambda 函数的 ARN。我一直收到这个错误:
Error: The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource bearerTokenAuthentication
... 或者如果尝试 Ref
...
Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [bearerTokenAuthentication] in the Resources block of the template
是否可以从资源部分引用 Lambda ARN?从错误消息看来,它正在寻找 "resource" 名称。我一直认为 lambda 函数声明也被认为是一种资源(当然除了明显的 Resources:
块),也许我误解了什么。
我明白了。我有一个 NodeJS 项目,并使用 "serverless" 命令行 (sls) 来使用 serverless.yml
进行部署。事实证明它创建了一个 .serverless
子目录,其中包含一些文件。其中之一是名为 cloudformation-template-update-stack.json
的 AWS Cloud Formation 编译模板。该实用程序似乎喜欢通过将第一个字符设为大写并将 "LambdaFunction" 添加到所有函数名称(无论出于何种原因)来破坏名称。在这种情况下,bearerTokenAuthentication
被重命名为 BearerTokenAuthenticationLambdaFunction
(实际资源名称)。查看编译后的模板后,一切都清楚了。该实用程序似乎也能找出依赖关系,这很高兴知道。这是最终结果:
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt [ BearerTokenAuthenticationLambdaFunction, Arn ]
- '/invocations'
其他"Gotchas":
如果您还对函数使用 event
映射,请不要定义 AWS::ApiGateway::RestApi
资源(就像我在问题中所做的那样),否则您将创建 2 APIs . event
条目会自动导致创建名为 "ApiGatewayRestApi" 的 API - 这是 sls
实用程序生成的资源名称。上一个文件的最后一行改成这样:
RestApiId: !Ref ApiGatewayRestApi
我的 ApiGateway:
部分被删除了。
归功于此 post 这让我更清楚地了解了真正发生的事情:https://forum.serverless.com/t/fixed-how-do-i-get-reference-api-gateway-restapi-id-in-serverless-yml/3397/5
上一个答案:
我也找到了另一种方法。在找到合适的(更短的)方法之前,我就是这样做的。我能够提取 lambda 名称并手动将所需的 URI 拼接在一起:
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/arn:aws:lambda:'
- !Ref 'AWS::Region'
- ':'
- !Ref 'AWS::AccountId'
- ':function:'
- '${self:functions.bearerTokenAuthentication.name}'
- '/invocations'
我希望这有助于节省一些时间来理解复杂的 .yml 文件。我也不明白为什么很难让它简单易懂。所有人所要做的就是(对我而言)说 "sls takes a 'serverless.yml' file, and optional include files (such as declarations specific to the cloud system itself, like AWS Cloud Formation), and generates a template JSON file that is used by the target cloud services system to deploy your solution. Also, the names you give may get mangled, so check the template." 我也很惊讶,到目前为止还没有人创建一个编辑器来使这一切变得更容易——也许有一天我会研究自己。 ;)
您始终可以转到已部署的 lambda 并查找 aws:cloudformation:logical-id 标记。这样您就可以获得应该在 serverless.yaml 中使用的逻辑 ID。 (也不喜欢这种幕后取名的把戏...)
我似乎无法获得 Ref
或 Fn:GetAtt
到 return 用于设置资源的有效值。
serverless.yml
...etc...
functions:
bearerTokenAuthentication:
handler: app.bearerTokenAuthentication
name: ${self:service}-auth-bearer
resources:
- ${file(./serverless_resources.yml)}
serverless_resources.yml
Resources:
ApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Name: restapi-${self:provider.stage}
Description: Endpoints
ApiKeySourceType: HEADER # (to read the API key from the X-API-Key header of a request)
ApiGatewayBearerAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Type: token
IdentitySource: method.request.header.Authorization
Name: BearerAuthorization
AuthorizerResultTtlInSeconds: 300
AuthorizerUri: !Join #arn:aws:apigateway:${self:provider.region}:lambda:path/${self:functions.bearerTokenAuthentication.name}
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt
- bearerTokenAuthentication # also tried !Ref bearerTokenAuthentication and '${self:functions.bearerTokenAuthentication.name}'
- Arn
- /invocations
RestApiId: !Ref ApiGateway
无论我做什么,GetAtt
都找不到在 bearerTokenAuthentication
中声明的 Lambda 函数的 ARN。我一直收到这个错误:
Error: The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource bearerTokenAuthentication
... 或者如果尝试 Ref
...
Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [bearerTokenAuthentication] in the Resources block of the template
是否可以从资源部分引用 Lambda ARN?从错误消息看来,它正在寻找 "resource" 名称。我一直认为 lambda 函数声明也被认为是一种资源(当然除了明显的 Resources:
块),也许我误解了什么。
我明白了。我有一个 NodeJS 项目,并使用 "serverless" 命令行 (sls) 来使用 serverless.yml
进行部署。事实证明它创建了一个 .serverless
子目录,其中包含一些文件。其中之一是名为 cloudformation-template-update-stack.json
的 AWS Cloud Formation 编译模板。该实用程序似乎喜欢通过将第一个字符设为大写并将 "LambdaFunction" 添加到所有函数名称(无论出于何种原因)来破坏名称。在这种情况下,bearerTokenAuthentication
被重命名为 BearerTokenAuthenticationLambdaFunction
(实际资源名称)。查看编译后的模板后,一切都清楚了。该实用程序似乎也能找出依赖关系,这很高兴知道。这是最终结果:
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt [ BearerTokenAuthenticationLambdaFunction, Arn ]
- '/invocations'
其他"Gotchas":
如果您还对函数使用 event
映射,请不要定义 AWS::ApiGateway::RestApi
资源(就像我在问题中所做的那样),否则您将创建 2 APIs . event
条目会自动导致创建名为 "ApiGatewayRestApi" 的 API - 这是 sls
实用程序生成的资源名称。上一个文件的最后一行改成这样:
RestApiId: !Ref ApiGatewayRestApi
我的 ApiGateway:
部分被删除了。
归功于此 post 这让我更清楚地了解了真正发生的事情:https://forum.serverless.com/t/fixed-how-do-i-get-reference-api-gateway-restapi-id-in-serverless-yml/3397/5
上一个答案:
我也找到了另一种方法。在找到合适的(更短的)方法之前,我就是这样做的。我能够提取 lambda 名称并手动将所需的 URI 拼接在一起:
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/arn:aws:lambda:'
- !Ref 'AWS::Region'
- ':'
- !Ref 'AWS::AccountId'
- ':function:'
- '${self:functions.bearerTokenAuthentication.name}'
- '/invocations'
我希望这有助于节省一些时间来理解复杂的 .yml 文件。我也不明白为什么很难让它简单易懂。所有人所要做的就是(对我而言)说 "sls takes a 'serverless.yml' file, and optional include files (such as declarations specific to the cloud system itself, like AWS Cloud Formation), and generates a template JSON file that is used by the target cloud services system to deploy your solution. Also, the names you give may get mangled, so check the template." 我也很惊讶,到目前为止还没有人创建一个编辑器来使这一切变得更容易——也许有一天我会研究自己。 ;)
您始终可以转到已部署的 lambda 并查找 aws:cloudformation:logical-id 标记。这样您就可以获得应该在 serverless.yaml 中使用的逻辑 ID。 (也不喜欢这种幕后取名的把戏...)