{ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Description": "AWS CloudFormation sample template that contains a single Lambda function behind an API Gateway", | |
"Resources": { | |
"GreetingLambda": { | |
"Type": "AWS::Lambda::Function", | |
"Properties": { | |
"Code": { | |
"ZipFile": { "Fn::Join": ["\n", [ | |
"'use strict';", | |
"", | |
"// Greeter Lambda", | |
"exports.handler = (event, context, callback) => {", | |
" console.log('Event:', JSON.stringify(event));", | |
" const name = event.name || 'World';", | |
" const response = {greeting: `Hello, ${name}!`};", | |
" callback(null, response);", | |
"};" | |
]]} | |
}, | |
"Description": "A greeting function", | |
"FunctionName": "GreetingLambda", | |
"Handler": "index.handler", | |
"Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"]}, | |
"Runtime": "nodejs4.3" | |
} | |
}, | |
"LambdaExecutionRole": { | |
"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"] | |
} | |
}, | |
"GreetingApi": { | |
"Type": "AWS::ApiGateway::RestApi", | |
"Properties": { | |
"Name": "Greeting API", | |
"Description": "API used for Greeting requests", | |
"FailOnWarnings": true | |
} | |
}, | |
"LambdaPermission": { | |
"Type": "AWS::Lambda::Permission", | |
"Properties": { | |
"Action": "lambda:invokeFunction", | |
"FunctionName": {"Fn::GetAtt": ["GreetingLambda", "Arn"]}, | |
"Principal": "apigateway.amazonaws.com", | |
"SourceArn": {"Fn::Join": ["", ["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "GreetingApi"}, "/*"]]} | |
} | |
}, | |
"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:CreateLogGroup", | |
"logs:CreateLogStream", | |
"logs:DescribeLogGroups", | |
"logs:DescribeLogStreams", | |
"logs:PutLogEvents", | |
"logs:GetLogEvents", | |
"logs:FilterLogEvents" | |
], | |
"Resource": "*" | |
}] | |
} | |
}] | |
} | |
}, | |
"ApiGatewayAccount": { | |
"Type": "AWS::ApiGateway::Account", | |
"Properties": { | |
"CloudWatchRoleArn": {"Fn::GetAtt": ["ApiGatewayCloudWatchLogsRole", "Arn"] } | |
} | |
}, | |
"GreetingApiStage": { | |
"DependsOn": ["ApiGatewayAccount"], | |
"Type": "AWS::ApiGateway::Stage", | |
"Properties": { | |
"DeploymentId": {"Ref": "ApiDeployment"}, | |
"MethodSettings": [{ | |
"DataTraceEnabled": true, | |
"HttpMethod": "*", | |
"LoggingLevel": "INFO", | |
"ResourcePath": "/*" | |
}], | |
"RestApiId": {"Ref": "GreetingApi"}, | |
"StageName": "LATEST", | |
"Variables": { | |
"Tom": "Maslen-v4" | |
} | |
} | |
}, | |
"ApiDeployment": { | |
"Type": "AWS::ApiGateway::Deployment", | |
"DependsOn": ["GreetingRequestGET", "GreetingRequestPOST"], | |
"Properties": { | |
"RestApiId": {"Ref": "GreetingApi"}, | |
"StageName": "DummyStage" | |
} | |
}, | |
"GreetingResource": { | |
"Type": "AWS::ApiGateway::Resource", | |
"Properties": { | |
"RestApiId": {"Ref": "GreetingApi"}, | |
"ParentId": {"Fn::GetAtt": ["GreetingApi", "RootResourceId"]}, | |
"PathPart": "greeting" | |
} | |
}, | |
"GreetingRequestGET": { | |
"DependsOn": "LambdaPermission", | |
"Type": "AWS::ApiGateway::Method", | |
"Properties": { | |
"AuthorizationType": "NONE", | |
"HttpMethod": "GET", | |
"Integration": { | |
"Type": "AWS", | |
"IntegrationHttpMethod": "POST", | |
"Uri": {"Fn::Join": ["", | |
["arn:aws:apigateway:", {"Ref": "AWS::Region"}, ":lambda:path/2015-03-31/functions/", {"Fn::GetAtt": ["GreetingLambda", "Arn"]}, "/invocations"] | |
]}, | |
"IntegrationResponses": [{ | |
"StatusCode": 200, | |
"ResponseTemplates": { | |
"application/json": "$input.json('$.body')" | |
} | |
}], | |
"RequestTemplates": { | |
"application/json": {"Fn::Join": ["", [ | |
"#set($allParams = $input.params())\n", | |
"{\n", | |
" \"body-json\": \"$input.json('$')\",\n", | |
" \"params\" : {\n", | |
" #foreach($type in $allParams.keySet())\n", | |
" #set($params = $allParams.get($type))\n", | |
" \"$type\" : {\n", | |
" #foreach($paramName in $params.keySet())\n", | |
" \"$paramName\" : \"$util.escapeJavaScript($params.get($paramName))\"\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" }\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" },\n", | |
" \"stage-variables\": {\n", | |
" #foreach($key in $stageVariables.keySet())\n", | |
" \"$key\" : \"$util.escapeJavaScript($stageVariables.get($key))\"\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" },\n", | |
" \"context\" : {\n", | |
" \"account-id\" : \"$context.identity.accountId\",\n", | |
" \"api-id\" : \"$context.apiId\",\n", | |
" \"api-key\" : \"$context.identity.apiKey\",\n", | |
" \"authorizer-principal-id\" : \"$context.authorizer.principalId\",\n", | |
" \"caller\" : \"$context.identity.caller\",\n", | |
" \"cognito-authentication-provider\" : \"$context.identity.cognitoAuthenticationProvider\",\n", | |
" \"cognito-authentication-type\" : \"$context.identity.cognitoAuthenticationType\",\n", | |
" \"cognito-identity-id\" : \"$context.identity.cognitoIdentityId\",\n", | |
" \"cognito-identity-pool-id\" : \"$context.identity.cognitoIdentityPoolId\",\n", | |
" \"http-method\" : \"$context.httpMethod\",\n", | |
" \"stage\" : \"$context.stage\",\n", | |
" \"source-ip\" : \"$context.identity.sourceIp\",\n", | |
" \"user\" : \"$context.identity.user\",\n", | |
" \"user-agent\" : \"$context.identity.userAgent\",\n", | |
" \"user-arn\" : \"$context.identity.userArn\",\n", | |
" \"request-id\" : \"$context.requestId\",\n", | |
" \"resource-id\" : \"$context.resourceId\",\n", | |
" \"resource-path\" : \"$context.resourcePath\"\n", | |
" }\n", | |
"}" | |
]]} | |
} | |
}, | |
"RequestParameters": { | |
"method.request.querystring.name": false | |
}, | |
"ResourceId": {"Ref": "GreetingResource"}, | |
"RestApiId": {"Ref": "GreetingApi"}, | |
"MethodResponses": [{ | |
"StatusCode": 200 | |
}] | |
} | |
}, | |
"GreetingRequestPOST": { | |
"DependsOn": "LambdaPermission", | |
"Type": "AWS::ApiGateway::Method", | |
"Properties": { | |
"AuthorizationType": "NONE", | |
"HttpMethod": "POST", | |
"Integration": { | |
"Type": "AWS", | |
"IntegrationHttpMethod": "POST", | |
"Uri": {"Fn::Join": ["", | |
["arn:aws:apigateway:", {"Ref": "AWS::Region"}, ":lambda:path/2015-03-31/functions/", {"Fn::GetAtt": ["GreetingLambda", "Arn"]}, "/invocations"] | |
]}, | |
"IntegrationResponses": [{ | |
"StatusCode": 200, | |
"ResponseTemplates": { | |
"application/json": "$input.json('$.body')" | |
} | |
}], | |
"RequestTemplates": { | |
"application/json": {"Fn::Join": ["", [ | |
"#set($allParams = $input.params())\n", | |
"{\n", | |
" \"body-json\": \"$input.json('$')\",\n", | |
" \"params\" : {\n", | |
" #foreach($type in $allParams.keySet())\n", | |
" #set($params = $allParams.get($type))\n", | |
" \"$type\" : {\n", | |
" #foreach($paramName in $params.keySet())\n", | |
" \"$paramName\" : \"$util.escapeJavaScript($params.get($paramName))\"\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" }\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" },\n", | |
" \"stage-variables\": {\n", | |
" #foreach($key in $stageVariables.keySet())\n", | |
" \"$key\" : \"$util.escapeJavaScript($stageVariables.get($key))\"\n", | |
" #if($foreach.hasNext),#end\n", | |
" #end\n", | |
" },\n", | |
" \"context\" : {\n", | |
" \"account-id\" : \"$context.identity.accountId\",\n", | |
" \"api-id\" : \"$context.apiId\",\n", | |
" \"api-key\" : \"$context.identity.apiKey\",\n", | |
" \"authorizer-principal-id\" : \"$context.authorizer.principalId\",\n", | |
" \"caller\" : \"$context.identity.caller\",\n", | |
" \"cognito-authentication-provider\" : \"$context.identity.cognitoAuthenticationProvider\",\n", | |
" \"cognito-authentication-type\" : \"$context.identity.cognitoAuthenticationType\",\n", | |
" \"cognito-identity-id\" : \"$context.identity.cognitoIdentityId\",\n", | |
" \"cognito-identity-pool-id\" : \"$context.identity.cognitoIdentityPoolId\",\n", | |
" \"http-method\" : \"$context.httpMethod\",\n", | |
" \"stage\" : \"$context.stage\",\n", | |
" \"source-ip\" : \"$context.identity.sourceIp\",\n", | |
" \"user\" : \"$context.identity.user\",\n", | |
" \"user-agent\" : \"$context.identity.userAgent\",\n", | |
" \"user-arn\" : \"$context.identity.userArn\",\n", | |
" \"request-id\" : \"$context.requestId\",\n", | |
" \"resource-id\" : \"$context.resourceId\",\n", | |
" \"resource-path\" : \"$context.resourcePath\"\n", | |
" }\n", | |
"}" | |
]]} | |
} | |
}, | |
"RequestParameters": { | |
"method.request.querystring.name": false | |
}, | |
"ResourceId": {"Ref": "GreetingResource"}, | |
"RestApiId": {"Ref": "GreetingApi"}, | |
"MethodResponses": [{ | |
"StatusCode": 200 | |
}] | |
} | |
} | |
}, | |
"Outputs": { | |
"RootUrl": { | |
"Description": "Root URL of the API gateway", | |
"Value": {"Fn::Join": ["", ["https://", {"Ref": "GreetingApi"}, ".execute-api.", {"Ref": "AWS::Region"}, ".amazonaws.com"]]} | |
} | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
bryanleekw
commented
Oct 11, 2017
and also, I am not quite familiar with AWS Cloud formation, may I know what is the intention of the code being comment out ? Million thanks |
This comment has been minimized.
This comment has been minimized.
KMacGyver
commented
Apr 15, 2018
Hi Tom, Thank you taking the time to put this code up, I was referred to this by the AWS support team. I haven't been able to figure out the syntax to insert the Access-Control-Allow-Origin values into your document. I have pasted an extract from another template that I did myself which works and I was hoping that you could tell the correct syntax and placement in your code. I would appreciate it greatly if you can help. Thanks, /equipment: |
This comment has been minimized.
This comment has been minimized.
Naresh4u
commented
Aug 24, 2018
•
@tmaslen may i know the swagger url for above CFT after executing in AWS. Thanks in advance. I'm hope that if i use the swagger url in browser it will list out all methods in browser with request type/response format etc.. just like after adding swagger configuration for RestFull web services. [example : http://localhost:8080/swagger-ui.html] |
This comment has been minimized.
This comment has been minimized.
mchapple
commented
Oct 18, 2018
Hey @tmaslen Anyway, that aside, it'd be great to understand your code above a little further. As it stands I cant get it running and indeed the URL output once the Cloud Formation has completed just results in a {"message":"Forbidden"} response. When I test the API in API Gateway I also get a 200 response. It'd be great to see if you have this up and running and if there are any additional changes required to get it working. Regards, |
This comment has been minimized.
bryanleekw commentedOct 11, 2017
Hi tmaslen, thanks for your effort, in aws, may I know how to test the POST method? in "Request Body" field, what should I input?