Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lambda_api_ses] Added basic configuration for AWS Lambda + API Gateway + Role #2

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
@@ -0,0 +1,10 @@
.terraform/
.terraform.tfstate.lock.info
terraform.tfstate
terraform.tfstate.backup

# environment variables
config/*.tfvars
config/*.tfbackend
!config/environment_variables_template.tfvars
!config/environment_variables_template.tfbackend
7 changes: 7 additions & 0 deletions config/environment_variables_template.tfbackend
@@ -0,0 +1,7 @@

# Create <name-of-environment>.tfbackend for every environment that You intend
# to deploy from this template:

"bucket" =
"key" = "terraform/Infrastructure/<name-of-environment>.tfstate"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improvement: We could use terraform workspaces instead of hardcoding this
https://www.terraform.io/docs/state/workspaces.html

"region" = "eu-west-1"
14 changes: 14 additions & 0 deletions config/environment_variables_template.tfvars
@@ -0,0 +1,14 @@
# Create <name-of-environment>.tfvars for every environment that You intend
# to deploy from this template:
"function_name" =
"lambda_description" =
"handler" =
"runtime" =
"stage" =
"path_part" =
"api_gw_description" =
"iam_role_name" =
"iam_role_policy_name" =
"rest_resource_path_part" =
"rest_api_name" =
"filename" =
36 changes: 36 additions & 0 deletions main.tf
@@ -0,0 +1,36 @@
terraform {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: This looks like tf 0.11 syntax which is OK but (as an improvement) we could use 0.12.
Though I'd also recommend using tfenv for pinning code to specific version of terraform which is not always backward compatible.
[1] https://github.com/tfutils/tfenv

backend "s3" { }
}

provider "aws" {
region = "${var.aws_region}"
profile = "default"
}

module "alinka_website" {
source = "./modules/lambda_apigateway"

# LAMBDA VARS
function_name = "alina-email-sender"
filename = "./modules/lambda_apigateway/index.js"
lambda_description = "${var.lambda_description}"
handler = "${var.handler}"
runtime = "${var.runtime}"
stage = "${var.stage}"
path_part = "${var.path_part}"


# APIGATEWAY VARS
rest_api_name = "${var.rest_api_name}"
rest_resource_path_part = "${var.rest_resource_path_part}"
api_gw_description = "${var.api_gw_description}"


# IAM VARS
iam_role_name = "${var.iam_role_name}"
iam_role_policy_name = "${var.iam_role_policy_name}"

# SES VARS
domain = "${var.domain}"
zone_id = "${var.zone_id}"
}
Empty file added modules/empty.tf
Empty file.
43 changes: 43 additions & 0 deletions modules/lambda_apigateway/api_gateway.tf
@@ -0,0 +1,43 @@

variable "rest_api_name" {}
variable "api_gw_description" {}
variable "rest_resource_path_part" {}
variable "stage" {}


resource "aws_api_gateway_rest_api" "rest_api" {
name = "${var.rest_api_name}"
description = "${var.api_gw_description}"
}

resource "aws_api_gateway_resource" "rest_api_resource" {
rest_api_id = "${aws_api_gateway_rest_api.rest_api.id}"
parent_id = "${aws_api_gateway_rest_api.rest_api.root_resource_id}"
path_part = "${var.rest_resource_path_part}"
}

resource "aws_api_gateway_method" "rest_api_method" {
rest_api_id = "${aws_api_gateway_rest_api.rest_api.id}"
resource_id = "${aws_api_gateway_resource.rest_api_resource.id}"
http_method = "ANY"
authorization = "NONE"
api_key_required = "false"
}

resource "aws_api_gateway_integration" "rest_api_integration" {
rest_api_id = "${aws_api_gateway_rest_api.rest_api.id}"
resource_id = "${aws_api_gateway_resource.rest_api_resource.id}"
http_method = "${aws_api_gateway_method.rest_api_method.http_method}"
type = "AWS_PROXY"
uri = "${aws_lambda_function.lambda_function.invoke_arn}"
integration_http_method = "POST"
}

resource "aws_api_gateway_deployment" "rest_api_deployment" {
depends_on = [
"aws_api_gateway_method.rest_api_method",
"aws_api_gateway_integration.rest_api_integration"
]
rest_api_id = "${aws_api_gateway_rest_api.rest_api.id}"
stage_name = "${var.stage}"
}
57 changes: 57 additions & 0 deletions modules/lambda_apigateway/iam.tf
@@ -0,0 +1,57 @@
variable "iam_role_name" {}
variable "iam_role_policy_name" {}


resource "aws_iam_role" "iam_role" {
name = "${var.iam_role_name}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "iam_role_policy" {
name = "${var.iam_role_policy_name}"
role = "${aws_iam_role.iam_role.id}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
}
]
}
POLICY
}
4 changes: 4 additions & 0 deletions modules/lambda_apigateway/index.js
@@ -0,0 +1,4 @@
exports.handler = async function(event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2))
return context.logStreamName
}
73 changes: 73 additions & 0 deletions modules/lambda_apigateway/lambda.tf
@@ -0,0 +1,73 @@
variable "function_name" {}
variable "filename" {}
variable "lambda_description" {}
variable "handler" {}
variable "runtime" {}
variable "path_part" {}


#### MOCK LAMBDA

resource "null_resource" "build_lambda_zip" {
provisioner "local-exec"{
command = <<COMMAND
cp -r --update ${var.filename} ./lambda
COMMAND
}

triggers {
uuid = "${uuid()}"
}
}

data "archive_file" "lambda_zip" {
depends_on = ["null_resource.build_lambda_zip"]

type = "zip"
source_dir = "lambda"
output_path = "lambda.zip"
}

resource "null_resource" "clean" {
depends_on = ["aws_lambda_function.lambda_function"]

provisioner "local-exec"{
command = <<COMMAND
rm -rf ${data.archive_file.lambda_zip.output_path}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need -r for lambda.zip? It's just one file.

COMMAND
}

triggers {
uuid = "${uuid()}"
}
}

####

resource "aws_lambda_function" "lambda_function" {
depends_on = ["data.archive_file.lambda_zip"]

function_name = "${var.function_name}"

# Basic lambda function code required during first creation
filename = "lambda.zip"

role = "${aws_iam_role.iam_role.arn}"
description = "${var.lambda_description}"
handler = "${var.handler}"
runtime = "${var.runtime}"

environment {
variables {
name = "${var.function_name}-${var.stage}"
}
}
}

resource "aws_lambda_permission" "allow_api_gateway" {
function_name = "${aws_lambda_function.lambda_function.function_name}"
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
principal = "apigateway.amazonaws.com"
source_arn = "${replace(aws_api_gateway_deployment.rest_api_deployment.execution_arn, "${var.stage}", "")}*/*"
}
Empty file.
16 changes: 16 additions & 0 deletions modules/lambda_apigateway/ses.tf
@@ -0,0 +1,16 @@
variable "domain" {}
variable "zone_id" {}



resource "aws_ses_domain_identity" "ses_domain_identity" {
domain = "${var.domain}"
}

resource "aws_route53_record" "amazonses_verification_record" {
zone_id = "${var.zone_id}"
name = "_amazonses.example.com"
type = "TXT"
ttl = "600"
records = ["${aws_ses_domain_identity.ses_domain_identity.verification_token}"]
}
20 changes: 20 additions & 0 deletions variables.tf
@@ -0,0 +1,20 @@
variable "aws_region" {
default = "eu-west-1"
}


variable "function_name" {}
variable "lambda_description" {}
variable "handler" {}
variable "runtime" {}
variable "stage" {}
variable "path_part" {}

variable "api_gw_description" {}
variable "iam_role_name" {}
variable "iam_role_policy_name" {}
variable "rest_resource_path_part" {}
variable "rest_api_name" {}
variable "domain" {}
variable "zone_id" {}
variable "filename" {}