我正在尝试使用CloudFormation创建Api-Gateway作为Lambda代理 . 在Lambda函数上获得正确的权限似乎存在问题,即使我已经看了一遍并且似乎尝试了所有可能的事情,但我无处可去 . 围绕一些重要的小细节的文档似乎缺失了,(或者我只是误解了它们?) .
这是我有的:
{
"Description": "",
"Parameters": {
"IngressLambdaName": {
"Type": "String",
"Description": "Name of the lambda behind Api Gateway",
"Default": "LambdaIngress"
}
},
"Mappings": {
},
"Resources": {
"ApiGatewayToLambdaRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": {
"Service": [ "apigateway.amazonaws.com" ]
},
"Action": "sts:AssumeRole"
}]
},
"Policies": [{
"PolicyName": "ApiGatewayToLambdaPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*"
}]
}
}]
}
},
"IngressLambda":{
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.handler",
"FunctionName": {"Ref": "IngressLambdaName"},
"Runtime": "nodejs4.3",
"Role": { "Fn::GetAtt": ["**Role that isn't shown here**", "Arn"]},
"Code": {
"ZipFile": { "Fn::Join": ["", [
"exports.handler = function(event, context) {",
" console.log('invoked the lambda!');",
" context.succeed({statusCode: 200, headers: {}, body: JSON.stringify({message: 'invoked the lambda!'})});",
"};"
]]}
}
}
},
"IngressLambdaPermission":{
"Type" : "AWS::Lambda::Permission",
"Properties" : {
"Action" : "lambda:InvokeFunction",
"FunctionName" : { "Ref" : "IngressLambdaName"},
"Principal" : "apigateway.amazonaws.com",
"SourceArn" : {"Fn::Sub": "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${RestApi}/*/POST/*"}
},
"DependsOn": ["IngressLambda"]
},
"RestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "API Gateway"
}
},
"TagModel": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "Tag",
"RestApiId": { "Ref": "RestApi" },
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "TagModel",
"type": "object",
"properties": {
"payload": {"type": "object"},
"domain": {"type": "string"}
}
}
}
},
"TagsResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": { "Ref": "RestApi" },
"ParentId": { "Fn::GetAtt": ["RestApi", "RootResourceId"] },
"PathPart": "tag"
}
},
"TagsPost": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ApiKeyRequired": "False",
"AuthorizationType": "NONE",
"HttpMethod": "POST",
"RestApiId": {"Ref": "RestApi"},
"ResourceId": { "Fn::GetAtt": ["RestApi", "RootResourceId"] },
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"PassthroughBehavior": "NEVER",
"Uri": {"Fn::Join" : ["", ["arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/", {"Fn::GetAtt": ["IngressLambda", "Arn"]}, "/invocations"]]}
}
}
},
"RestApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": { "Ref": "RestApi" },
"StageName": "v1"
},
"DependsOn": ["RestApi", "TagModel", "TagsResource", "TagsPost"]
},
},
"Outputs": {
}
}
在aws Web门户控制台中的API网关中运行测试时,我收到错误: Execution failed due to configuration error: Invalid permissions on Lambda function
这让我很生气 . 这里任何方向都会很棒 . 我猜我的权限在某种程度上是错误的,但我不确定如何(这是我在文档中挣扎的地方) .
3 回答
与wjordan最近的评论相似,我认为来源arn就是问题所在 . 它应该是这样的格式:
因为这是我用CLI执行命令的方式:
我做了一些挖掘,可能是因为您错过了帐户ID . 我在GitHub上的例子是'm editing my answer based on Michael Wittig':https://github.com/AWSinAction/apigateway/blob/master/template.json
你:
"SourceArn" : { "Fn::Join" : ["", ["arn:aws:execute-api:us-west-2::", {"Fn::GetAtt": ["RestApi", "RootResourceId"]}, "/null/POST" ]]}
他:
"SourceArn": {"Fn::Join": ["", ["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "RestApi"}, "/*"]]}
请注意他是如何使用该引用的:
亚马逊说"ARNs for some resources don't require an account number, so this component might be omitted."但是's unclear which ones require and which don' t .
参考:http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
根据API网关文档部分Resource Format of Permissions for Executing API in API Gateway,SourceArn属性应具有以下结构:
哪里:
您提供的当前模板:
尝试这样的事情(使用Fn::Sub和
${}
语法来简化引用):此外,代理集成Lambda函数必须根据Output Format of a Lambda Function for Proxy Integration返回输出,否则将返回
502 Bad Gateway
错误:将Lambda函数更改为以下内容:
这是一个完整的,自包含的工作示例模板,它演示了一个从API网关正确执行的Lambda代理函数(为了便于阅读,我将原始示例转换为YAML):
此堆栈在其堆栈输出中返回
Invoked the lambda!
,表示对由简单Lambda函数支持的新创建的API网关的成功HTTP请求 . 如果失败,您的CloudFormation堆栈可能缺少IAM权限,或者您的AWS区域中存在不受支持的服务 .您的ApiGateway可能没有权利调用您的lambda函数 . 尝试以下步骤;
选择你的API网关休息终点选择资源选择你的一种方法选择'整合请求'点击你的'Lambda函数'点击确认按钮旁边的编辑按钮,这一步将要求你批准你正在给你的ApiGateway打电话给你的lambda功能确认访问权限
---现在你可以重新测试你的方法了