Using terraform to create lambda deploy package

I needed to build a deployment package for my lambdas but didn’t want to start keeping a wrapper script… that’s a pain :/

So here is a quick sample of how I used a null_resource to let terraform handle the lambda packaging… also shows an example of building a policy in code.

variable "target_path" {
default = "target"
}
variable "vpc_id" {
default = "abc-123"
}
variable "subnet_a" {
default = "abc-123"
}
variable "subnet_b" {
default = "123-abc"
}
variable "tag_value" {
default = "sweet"
}

resource "null_resource" "lambda_preconditions" {
triggers {
always_run = "${uuid()}"
}
provisioner "local-exec" {
command = "rm -rf ${path.root}/../../target_lambda"
}
provisioner "local-exec" {
command = "mkdir -p ${path.root}/../../target_lambda"
}
provisioner "local-exec" {
command = "pip3 install --target=${path.root}/../../target_lambda requests"
}
provisioner "local-exec" {
command = "cp -R ${path.root}/../../lambda_*.py ${path.root}/../../target_lambda/."
}
provisioner "local-exec" {
command = "cd ${path.root}/../../target_lambda && zip -r lambda.zip ."
}
}

data aws_iam_policy_document iam_assume_role_policy {
statement {
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [
"apigateway.amazonaws.com",
"ec2.amazonaws.com",
"lambda.amazonaws.com",
"rds.amazonaws.com"
]
}
}
}

resource "aws_iam_role" "api_role" {
name = "api_role"
assume_role_policy = "${data.aws_iam_policy_document.iam_assume_role_policy.json}"
}

data "aws_iam_policy_document" "lambda_iam_role_policy_document" {
statement {
sid = "1"

actions = [
"apigateway:*",
"ec2:*",
"cloudwatch:*",
"lambda:*",
"logs:*",
"rds:*",
"xray:*",
"sns:*"
]

resources = [
"*",
]
}
}

resource "aws_iam_policy" "iam_policy" {
name_prefix = "my-sweet-iam-policy-for-my-lambda"
path = "/"
policy = "${data.aws_iam_policy_document.lambda_iam_role_policy_document.json}"
}


resource "aws_iam_role_policy_attachment" "policy_attachment" {
policy_arn = "${aws_iam_policy.iam_policy.arn}"
role = "${aws_iam_role.api_role.name}"
}

data "aws_vpc" "vpc" {
id = "${var.vpc_id}"
}

resource "aws_security_group" "lambda_security_group" {
name = "security_group"
description = "Security group for lambdas"
vpc_id = "${data.aws_vpc.vpc.id}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [
"0.0.0.0/0"
]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [
"0.0.0.0/0"
]
}

tags {
some_cool_tag = "${var.tag_value}"
}
}

resource "aws_lambda_function" "some_get_lambda" {
filename = "${path.root}/../../target_lambda/lambda.zip"
function_name = "some_get"
role = "${aws_iam_role.api_role.arn}"
handler = "lambda_handler.some"
runtime = "python3.6"
source_code_hash = "${base64sha256(format("%s/../../target_lambda/lambda.zip", path.root))}"
publish = true
timeout = 30
vpc_config {
security_group_ids = [
"${aws_security_group.lambda_security_group.id}"
]
subnet_ids = [
"${var.subnet_a}",
"${var.subnet_b}"
]
}
tags {
some_cool_tag = "${var.tag_value}"
}
depends_on = [
"null_resource.lambda_preconditions"
]
environment {
variables {
ENV = "blah"
}
}
}