Skip to content

Instantly share code, notes, and snippets.

@campezzi
Forked from keeth/api.tf
Created November 15, 2016 00:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save campezzi/5db298b7e31126a5d4dbf90b5144121f to your computer and use it in GitHub Desktop.
Save campezzi/5db298b7e31126a5d4dbf90b5144121f to your computer and use it in GitHub Desktop.
Apex + Terraform + AWS Lambda + API Gateway + JSON Encoded Errors + CORS
resource "aws_api_gateway_rest_api" "myApi" {
name = "myApi-${var.env}"
description = "My awesome API (${var.env} environment)"
}
resource "aws_api_gateway_deployment" "myApi" {
depends_on = [
"aws_api_gateway_integration.myApi_myEndpoint_post",
"aws_api_gateway_integration_response.myApi_myEndpoint_post",
"aws_api_gateway_integration_response.myApi_myEndpoint_post_400",
"aws_api_gateway_method_response.myApi_myEndpoint_post_200",
"aws_api_gateway_method_response.myApi_myEndpoint_post_400",
"aws_api_gateway_integration.myApi_myEndpoint_options"
]
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
stage_name = "${var.env}"
}
resource "aws_api_gateway_resource" "myApi_myEndpoint" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
parent_id = "${aws_api_gateway_rest_api.myApi.root_resource_id}"
path_part = "myEndpoint"
}
resource "aws_api_gateway_method" "myApi_myEndpoint_post" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "myApi_myEndpoint_post" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_post.http_method}"
type = "AWS"
integration_http_method = "POST" # Must be POST for invoking Lambda function
credentials = "${var.gateway_lambda_role_arn}"
# http://docs.aws.amazon.com/apigateway/api-reference/resource/integration/#uri
uri = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${var.apex_function_myEndpoint}/invocations"
}
resource "aws_api_gateway_integration_response" "myApi_myEndpoint_post" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_post.http_method}"
status_code = "${aws_api_gateway_method_response.myApi_myEndpoint_post_200.status_code}"
response_parameters_in_json = <<PARAMS
{
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
PARAMS
}
resource "aws_api_gateway_integration_response" "myApi_myEndpoint_post_400" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_post.http_method}"
status_code = "${aws_api_gateway_method_response.myApi_myEndpoint_post_400.status_code}"
selection_pattern = ".*message.*"
response_templates = {
"application/json" = <<EOT
#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))
{
"message" : "$errorMessageObj.message"
}
EOT
}
response_parameters_in_json = <<PARAMS
{
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
PARAMS
}
resource "aws_api_gateway_method_response" "myApi_myEndpoint_post_200" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_post.http_method}"
status_code = "200"
response_models = {
"application/json" = "Empty"
}
response_parameters_in_json = <<PARAMS
{
"method.response.header.Access-Control-Allow-Origin": true
}
PARAMS
}
resource "aws_api_gateway_method_response" "myApi_myEndpoint_post_400" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_post.http_method}"
status_code = "400"
response_models = {
"application/json" = "Empty"
}
response_parameters_in_json = <<PARAMS
{
"method.response.header.Access-Control-Allow-Origin": true
}
PARAMS
}
# CORS
resource "aws_api_gateway_method" "myApi_myEndpoint_options" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "OPTIONS"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "myApi_myEndpoint_options" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_options.http_method}"
type = "MOCK"
request_templates = {
"application/json" = <<EOT
{"statusCode": 200}
EOT
}
}
resource "aws_api_gateway_integration_response" "myApi_myEndpoint_options_200" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_options.http_method}"
status_code = "${aws_api_gateway_method_response.myApi_myEndpoint_options_200.status_code}"
response_parameters_in_json = <<PARAMS
{
"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'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
PARAMS
response_templates = {
"application/json" = <<EOT
{}
EOT
}
}
resource "aws_api_gateway_method_response" "myApi_myEndpoint_options_200" {
rest_api_id = "${aws_api_gateway_rest_api.myApi.id}"
resource_id = "${aws_api_gateway_resource.myApi_myEndpoint.id}"
http_method = "${aws_api_gateway_method.myApi_myEndpoint_options.http_method}"
status_code = "200"
response_models = {
"application/json" = "Empty"
}
response_parameters_in_json = <<PARAMS
{
"method.response.header.Access-Control-Allow-Headers": true,
"method.response.header.Access-Control-Allow-Methods": true,
"method.response.header.Access-Control-Allow-Origin": true
}
PARAMS
}
// Forked from https://github.com/apex/node-apex
import R from 'ramda';
function serializeError(error) {
if (!R.is(Object, error)) {
return error;
}
const copy = R.merge({}, error);
if (typeof error.message === 'string') {
copy.message = error.message;
}
return copy;
}
function wrapCb(cb) {
return function(error, result) {
if (!R.isNil(error)) {
error = JSON.stringify(serializeError(error));
}
return cb(error, result);
}
}
export default function λ(fn) {
return function(e, ctx, cb) {
cb = wrapCb(cb);
try {
var v = fn(e, ctx, cb);
if (v && typeof v.then == 'function') {
v.then(function (val) {
cb(null, val);
}).catch(cb);
return;
}
cb(null, v);
} catch (err) {
cb(err);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment