Skip to content

Instantly share code, notes, and snippets.

@EricLondon
Last active October 23, 2018 16:21
Show Gist options
  • Save EricLondon/a93c9cfc302f754ba4a939b51b2bf629 to your computer and use it in GitHub Desktop.
Save EricLondon/a93c9cfc302f754ba4a939b51b2bf629 to your computer and use it in GitHub Desktop.
Lamba, NodeJS, API Gateway, Terraform
resource "aws_api_gateway_rest_api" "lambda_api_gateway" {
name = "Lambda API Gateway (Eric)"
}
resource "aws_api_gateway_resource" "proxy" {
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
parent_id = "${aws_api_gateway_rest_api.lambda_api_gateway.root_resource_id}"
path_part = "{proxy+}"
}
resource "aws_api_gateway_method" "proxy" {
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
resource_id = "${aws_api_gateway_resource.proxy.id}"
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda" {
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
resource_id = "${aws_api_gateway_method.proxy.resource_id}"
http_method = "${aws_api_gateway_method.proxy.http_method}"
integration_http_method = "POST"
type = "AWS_PROXY"
uri = "${aws_lambda_function.api_gateway.invoke_arn}"
}
resource "aws_api_gateway_method" "proxy_root" {
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
resource_id = "${aws_api_gateway_rest_api.lambda_api_gateway.root_resource_id}"
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda_root" {
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
resource_id = "${aws_api_gateway_method.proxy_root.resource_id}"
http_method = "${aws_api_gateway_method.proxy_root.http_method}"
integration_http_method = "POST"
type = "AWS_PROXY"
uri = "${aws_lambda_function.api_gateway.invoke_arn}"
}
resource "aws_api_gateway_deployment" "lambda_api_gateway" {
depends_on = [
"aws_api_gateway_integration.lambda",
"aws_api_gateway_integration.lambda_root",
]
rest_api_id = "${aws_api_gateway_rest_api.lambda_api_gateway.id}"
stage_name = "test"
}
output "base_url" {
value = "${aws_api_gateway_deployment.lambda_api_gateway.invoke_url}"
}
data "archive_file" "lambda_api_gateway" {
type = "zip"
source_file = "${path.module}/lambda_api_gateway.js"
output_path = "${path.module}/lambda_api_gateway.zip"
}
resource "aws_lambda_function" "api_gateway" {
function_name = "lambda_api_gateway"
filename = "${path.module}/lambda_api_gateway.zip"
handler = "lambda_api_gateway.handler"
runtime = "nodejs8.10"
source_code_hash = "${data.archive_file.lambda_api_gateway.output_base64sha256}"
role = "${aws_iam_role.lambda_api_gateway.arn}"
environment {
variables = {
AWS_ACCOUNT_ID = "${data.aws_caller_identity.current.account_id}"
}
}
tags {
infrastructure = "${var.infrastructure}"
instance_name = "${var.instance_name}"
}
}
resource "aws_iam_role" "lambda_api_gateway" {
name = "lambda_api_gateway"
assume_role_policy = "${data.aws_iam_policy_document.lambda_api_gateway.json}"
}
data "aws_iam_policy_document" "lambda_api_gateway" {
statement {
sid = ""
effect = "Allow"
actions = [
"sts:AssumeRole"
]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "lambda_api_gateway_attach_policy" {
role = "${aws_iam_role.lambda_api_gateway.name}"
policy_arn = "${aws_iam_policy.lambda_api_gateway_policy.arn}"
}
resource "aws_iam_policy" "lambda_api_gateway_policy" {
name = "lambda_api_gateway_policy"
policy = "${data.aws_iam_policy_document.lambda_api_gateway_policy_document.json}"
}
data "aws_iam_policy_document" "lambda_api_gateway_policy_document" {
statement {
sid = ""
effect = "Allow"
actions = [
"logs:CreateLogGroup"
]
resources = [
"arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"
]
}
statement {
sid = ""
effect = "Allow"
actions = [
"logs:CreateLogStream",
"logs:PutLogEvents"
]
resources = [
"arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/lambda/${aws_lambda_function.api_gateway.function_name}:*"
]
}
}
resource "aws_lambda_permission" "api_gateway" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.api_gateway.arn}"
principal = "apigateway.amazonaws.com"
# The /*/* portion grants access from any method on any resource
# within the API Gateway "REST API".
source_arn = "${aws_api_gateway_deployment.lambda_api_gateway.execution_arn}/*/*"
}
'use strict';
const AWS_REGION_STRING = process.env.AWS_REGION || 'us-east-1';
exports.handler = function (event, context, callback) {
return main(event).then(function (result) {
callback(null, result);
}).catch(function (error) {
callback(error);
});
};
const main = async (event) => {
let response = {
statusCode: 200,
headers: {
'Content-Type': 'text/html; charset=utf-8',
},
body: "<p>Hello world!</p>",
};
return response;
}
data "aws_caller_identity" "current" {}
terraform {
required_version = "0.11.8"
backend "s3" {
bucket = ""
key = ""
profile = ""
region = ""
}
}
provider "aws" {
profile = "${var.aws_profile}"
region = "${var.aws_region}"
shared_credentials_file = "${var.aws_credentials_file}"
version = "1.37.0"
}
#!/usr/bin/env bash
set -x
: "${AWS_PROFILE:=some-aws-profile}"
: "${AWS_REGION:=us-east-1}"
: "${STATE_BUCKET:=some-s3-bucket}"
: "${STATE_KEY:=eric-test-api-gateway/terraform/base.tfstate}"
action="$1"
TFENV=$(which tfenv)
if [ $? -eq 0 ]; then
$TFENV install $(cat .terraform-version)
cat .terraform-version | xargs $TFENV use
fi
rm -f *.tfstate
rm -rf ./.terraform
terraform init \
-force-copy \
-backend=true \
-backend-config "bucket=${STATE_BUCKET}" \
-backend-config "key=${STATE_KEY}" \
-backend-config "profile=${AWS_PROFILE}" \
-backend-config "region=${AWS_REGION}"
terraform plan
if [ "$action" == "apply" ]; then
terraform apply -auto-approve
fi
if [ "$action" == "destroy" ]; then
terraform destroy
fi
variable "aws_region" {
type = "string"
default = "us-east-1"
}
variable "aws_profile" {
type = "string"
default = "some-aws-profile"
}
variable "aws_credentials_file" {
type = "string"
default = "~/.aws/credentials"
}
variable "instance_name" {
type = "string"
default = ""
}
variable "infrastructure" {
type = "string"
default = ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment