我正在尝试使用cloudformation创建一个通过代理指向lambda的api网关:
首先,我创建我的root并授予它权限:
RestApiHamed:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Name: hamed-proxy-test
APIGatewayToLambdaPermission:
Type: AWS::Lambda::Permission
DependsOn: RestApiHamed
Properties:
Action: lambda:invokeFunction
FunctionName: test-stg1-lambda-product-get
Principal: apigateway.amazonaws.com
SourceArn: #!Sub "arn:aws:execute-
api:${AWS::Region}:${AWS::AccountId}:RestApiHamed/*"
Fn::Join:
- ''
- - 'arn:aws:execute-api:'
- Ref: AWS::Region
- ":"
- Ref: AWS::AccountId
- ":"
- Ref: RestApiHamed
- "/*"
然后我创建我的方法:
ChannelsStoriesGetMethod:
Type: AWS::ApiGateway::Method
DependsOn: APIGatewayToLambdaPermission
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: HTTP
IntegrationHttpMethod: GET
IntegrationResponses:
-
StatusCode: 200
Type: AWS_PROXY
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:048947288163:function:zuora-stg1-lambda-product-get/invocations
ResourceId: !Ref ChannelsStoriesPath
RestApiId:
Ref: RestApiHamed
MethodResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
现在,当我运行cloudformation时,它成功了,我可以看到我的网关但是当我尝试网关时,我得到了:
<Message>Unable to determine service/operation name to be
authorized</Message>
</AccessDeniedException>
Execution failed due to configuration error: Malformed Lambda proxy response
但是一旦我转到集成请求并在lambda函数中编辑clcik然后我点击保存我会弹出一个请求权限附件,当我接受它然后它开始工作。问题是什么? 我确实在我的cfn代码中添加了权限,我希望你可以看到这件作品。我应该添加其他东西吗?
完整的cfn代码如下:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "API gateway for TJ services",
"Parameters": {
"BusinessUnit": {
"Description": "BusinessUnit",
"Type": "String",
"ConstraintDescription": "Any string"
},
"project": {
"Description": "project",
"Type": "String",
"ConstraintDescription": "Any string"
},
"EnvironmentApp": {
"Description": "EnvironmentApp",
"Type": "String",
"ConstraintDescription": "Any string"
},
"EnvironmentInfra": {
"Description": "EnvironmentInfra",
"Type": "String",
"ConstraintDescription": "Any string"
}
},
"Resources": {
"LambdaHelloworldRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "${project}-${EnvironmentApp}-lambda-helloworld",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"apigateway.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "${project}-${EnvironmentApp}-lambda-helloworld",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
}]
}
}]
}
},
"LambdaHelloworld": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.lambda_handler",
"Timeout": 180,
"MemorySize": 1536,
"Environment": {
"Variables": {
"test": "test"
}
},
"FunctionName": "${project}-${EnvironmentApp}-lambda-helloworld-pipeline-test",
"Role": {
"Fn::GetAtt": [
"LambdaHelloworldRole",
"Arn"
]
},
"Code": {
"ZipFile": {
"Fn::Join": [
"\n", [
"import boto3",
"import http.client",
"import json",
"import urllib.request",
"import urllib.parse",
"import sys",
"def lambda_handler(event, context):",
" return { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Origin': '*' }, 'body': 'hello world stg2'}"
]
]
}
},
"Runtime": "python3.6"
}
},
"RestApiHellowworld": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "hamed-proxy-test"
}
},
"APIGatewayToLambdaPermission": {
"Type": "AWS::Lambda::Permission",
"DependsOn": "RestApiHellowworld",
"Properties": {
"Action": "lambda:invokeFunction",
"FunctionName": "zuora-stg1-lambda-product-get",
"Principal": "apigateway.amazonaws.com"
}
},
"ChannelsStoriesPath": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "RestApiHellowworld"
},
"ParentId": {
"Fn::GetAtt": [
"RestApiHellowworld",
"RootResourceId"
]
},
"PathPart": "stories"
}
},
"ChannelsStoriesOptionsMethod": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "NONE",
"RestApiId": {
"Ref": "RestApiHellowworld"
},
"ResourceId": "ChannelsStoriesPath",
"HttpMethod": "OPTIONS",
"Integration": {
"IntegrationResponses": [{
"StatusCode": 200,
"ResponseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS,GET,PUT'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"ResponseTemplates": {
"application/json": ""
}
}],
"PassthroughBehavior": "WHEN_NO_MATCH",
"RequestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"Type": "MOCK"
},
"MethodResponses": [{
"StatusCode": 200,
"ResponseModels": {
"application/json": "Empty"
},
"ResponseParameters": {
"method.response.header.Access-Control-Allow-Headers": true,
"method.response.header.Access-Control-Allow-Methods": true,
"method.response.header.Access-Control-Allow-Origin": true
}
}]
}
},
"ChannelsStoriesGetMethod": {
"Type": "AWS::ApiGateway::Method",
"DependsOn": [
"APIGatewayToLambdaPermission",
"LambdaHelloworld"
],
"Properties": {
"AuthorizationType": "NONE",
"HttpMethod": "GET",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "GET",
"IntegrationResponses": [{
"StatusCode": 200,
"ResponseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}],
"Uri": {
"Fn::Join": [
"", [
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":",
"lambda:path/2015-03-31/functions/",
"arn:aws:lambda:us-east-1:048947288163:function:${project}-",
"${stageVariables.stg}-lambda-helloworld-pipeline-test",
"/invocations"
]
]
}
},
"ResourceId": "ChannelsStoriesPath",
"RestApiId": {
"Ref": "RestApiHellowworld"
},
"MethodResponses": [{
"StatusCode": 200
}]
}
},
"ApiGatewayEventLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Properties": {
"LogGroupName": {
"Fn::Join": [
"", [
"/aws/apigateway/",
"${project}-${EnvironmentApp}-helloworld"
]
]
},
"RetentionInDays": 1
}
},
"ApiGatewayEventLogStream": {
"Type": "AWS::Logs::LogStream",
"Properties": {
"LogGroupName": {
"Ref": "ApiGatewayEventLogGroup"
},
"LogStreamName": "${project}-${EnvironmentApp}-helloworld"
},
"DependsOn": [
"ApiGatewayEventLogGroup"
]
},
"ApiGatewayCloudWatchLogsRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [
"apigateway.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}]
},
"Policies": [{
"PolicyName": "ApiGatewayLogsPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": [
[
"ApiGatewayEventLogGroup",
"Arn"
],
"*"
]
}]
}
}]
}
},
"ApiGatewayAccount": {
"Type": "AWS::ApiGateway::Account",
"DependsOn": "ApiGatewayCloudWatchLogsRole",
"Properties": {
"CloudWatchRoleArn": {
"Fn::GetAtt": [
"ApiGatewayCloudWatchLogsRole",
"Arn"
]
}
}
},
"ApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"DependsOn": "ChannelsStoriesGetMethod",
"Properties": {
"RestApiId": {
"Ref": "RestApiHellowworld"
}
}
},
"ApiStage": {
"DependsOn": [
"ApiGatewayAccount"
],
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "ApiDeployment"
},
"MethodSettings": [{
"DataTraceEnabled": true,
"HttpMethod": "*",
"LoggingLevel": "INFO",
"ResourcePath": "/*"
}],
"RestApiId": {
"Ref": "RestApiHellowworld"
},
"StageName": "${EnvironmentApp}",
"Variables": {
"stg": "${EnvironmentApp}"
}
}
}
},
"Outputs": {
"RootResourceId": {
"Description": "Tj Services Rest API root resource id",
"Value": "RestApiHellowworld.RootResourceId",
"Export": {
"Name": "${project}-${EnvironmentApp}-RootResourceId-helloworld"
}
},
"RestTjApi": {
"Description": "Tj Services Rest API",
"Value": "RestApiHellowworld",
"Export": {
"Name": "${project}-restApi-tj-services-helloworld"
}
}
}
}
答案 0 :(得分:2)
我不认为您的cloudformation脚本能够向API网关添加调用lambda函数权限。我宁愿以下列方式实现这个目标
APIName:
Type: "AWS::ApiGateway::RestApi"
Properties:
Description: "Description"
Name: "APIName"
FailOnWarnings: true
APILambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !Ref LambdaFunctionName
Principal: "apigateway.amazonaws.com"
LambdaFunctionName:
Type: "AWS::Serverless::Function"
Properties:
Handler: index.handler
Runtime: nodejs6.10
CodeUri: s3://codeBucketName/index.zip
Role: !GetAtt RoleName.Arn
RoleName:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole