我一直在尝试使用CloudFormation部署到API网关,但是,我经常遇到与我的方法资源相同的问题。堆栈部署因“指定了无效的资源标识符”而失败。
以下是我的CloudFormation模板中的方法资源:
"UsersPut": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": "UsersResource",
"RestApiId": "MyApi",
"ApiKeyRequired": true,
"AuthorizationType": "NONE",
"HttpMethod": "PUT",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": ["", ["arn:aws:apigateway:", {
"Ref": "AWS::Region"
}, ":lambda:path/2015-03-31/functions/", {
"Fn::GetAtt": ["MyLambdaFunc", "Arn"]
}, "/invocations"]]
}
},
"MethodResponses": [{
"StatusCode": 200
}]
}
}
是否有人能够帮助我弄清楚为什么这会导致堆栈部署失败?
更新:我忘了提到我还尝试使用引用来添加资源ID,这也给了我同样的错误:
"UsersPut": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": {
"Ref": "UsersResource"
},
"RestApiId": "MyApi",
"ApiKeyRequired": true,
"AuthorizationType": "NONE",
"HttpMethod": "PUT",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": ["", ["arn:aws:apigateway:", {
"Ref": "AWS::Region"
}, ":lambda:path/2015-03-31/functions/", {
"Fn::GetAtt": ["MyLambdaFunc", "Arn"]
}, "/invocations"]]
}
},
"MethodResponses": [{
"StatusCode": 200
}]
}
}
以下是完整的CloudFormation模板:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"LambdaDynamoDBRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "DynamoReadWritePolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Sid": "1",
"Action": [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem"
],
"Effect": "Allow",
"Resource": "*"
}, {
"Sid": "2",
"Resource": "*",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow"
}]
}
}]
}
},
"MyFirstLambdaFn": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "myfirstlambdafn",
"S3Key": "lambda_handler.py.zip"
},
"Description": "",
"FunctionName": "MyFirstLambdaFn",
"Handler": "lambda_function.lambda_handler",
"MemorySize": 512,
"Role": {
"Fn::GetAtt": [
"LambdaDynamoDBRole",
"Arn"
]
},
"Runtime": "python2.7",
"Timeout": 3
},
"DependsOn": "LambdaDynamoDBRole"
},
"MySecondLambdaFn": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "mysecondlambdafn",
"S3Key": "lambda_handler.py.zip"
},
"Description": "",
"FunctionName": "MySecondLambdaFn",
"Handler": "lambda_function.lambda_handler",
"MemorySize": 512,
"Role": {
"Fn::GetAtt": [
"LambdaDynamoDBRole",
"Arn"
]
},
"Runtime": "python2.7",
"Timeout": 3
},
"DependsOn": "LambdaDynamoDBRole"
},
"MyApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "Project Test API",
"Description": "Project Test API",
"FailOnWarnings": true
}
},
"FirstUserPropertyModel": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "FirstUserPropertyModel",
"RestApiId": {
"Ref": "MyApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "FirstUserPropertyModel",
"type": "object",
"properties": {
"Email": {
"type": "string"
}
}
}
}
},
"SecondUserPropertyModel": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "SecondUserPropertyModel",
"RestApiId": {
"Ref": "MyApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "SecondUserPropertyModel",
"type": "object",
"properties": {
"Name": {
"type": "string"
}
}
}
}
},
"ErrorCfn": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "ErrorCfn",
"RestApiId": {
"Ref": "MyApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Error Schema",
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
},
"UsersResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "MyApi"
},
"ParentId": {
"Fn::GetAtt": ["MyApi", "RootResourceId"]
},
"PathPart": "users"
}
},
"UsersPost": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": {
"Ref": "UsersResource"
},
"RestApiId": "MyApi",
"ApiKeyRequired": true,
"AuthorizationType": "NONE",
"HttpMethod": "POST",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": ["", ["arn:aws:apigateway:", {
"Ref": "AWS::Region"
}, ":lambda:path/2015-03-31/functions/", {
"Fn::GetAtt": ["MyFirstLambdaFn", "Arn"]
}, "/invocations"]]
}
},
"MethodResponses": [{
"ResponseModels": {
"application/json": {
"Ref": "FirstUserPropertyModel"
}
},
"StatusCode": 200
}, {
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 404
}, {
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 500
}]
}
},
"UsersPut": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": {
"Ref": "UsersResource"
},
"RestApiId": "MyApi",
"ApiKeyRequired": true,
"AuthorizationType": "NONE",
"HttpMethod": "PUT",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": ["", ["arn:aws:apigateway:", {
"Ref": "AWS::Region"
}, ":lambda:path/2015-03-31/functions/", {
"Fn::GetAtt": ["MySecondLambdaFn", "Arn"]
}, "/invocations"]]
}
},
"MethodResponses": [{
"ResponseModels": {
"application/json": {
"Ref": "SecondUserPropertyModel"
}
},
"StatusCode": 200
}, {
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 404
}, {
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 500
}]
}
},
"RestApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "MyApi"
},
"StageName": "Prod"
},
"DependsOn": ["UsersPost", "UsersPut"]
}
},
"Description": "Project description"
}
答案 0 :(得分:4)
ResourceId必须是对cloudformation资源的引用,而不是简单的字符串。
e.g。
ResourceId:
Ref: UsersResource
答案 1 :(得分:2)
我认为实际上它也是RestApiId,它也需要作为参考:
"RestApiId": {
"Ref": "MyApi"
},