From 76e121094196ed39fdb09931bfa665cb2d3431ee Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Fri, 12 Aug 2022 15:18:26 +0200 Subject: [PATCH 01/15] Introduce `vpc_config` variable --- variables.tf | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/variables.tf b/variables.tf index 6deb4a6..1dee506 100644 --- a/variables.tf +++ b/variables.tf @@ -97,3 +97,29 @@ variable "timeout" { description = "The amount of time (in seconds) per execution before stopping it." } + +variable "vpc_config" { + type = object({ + vpc = object({ + id = string + }) + + subnets = list( + object({ + arn = string + id = string + }) + ) + }) + + default = null + + description = < Date: Fri, 12 Aug 2022 15:21:33 +0200 Subject: [PATCH 02/15] cleanup comments, reorder resources --- main.tf | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index f6ecbf4..b169816 100644 --- a/main.tf +++ b/main.tf @@ -41,6 +41,8 @@ data "archive_file" "this" { output_path = ".terraform/tmp/lambda/${var.function_name}.zip" } +# IAM role + resource "aws_iam_role" "this" { name = "lambda-${var.function_name}" @@ -60,11 +62,7 @@ data "aws_iam_policy_document" "lambda-assume-role" { } } -resource "aws_iam_role_policy" "cloudwatch-log-group" { - role = aws_iam_role.this.name - name = "cloudwatch-log-group" - policy = data.aws_iam_policy_document.cloudwatch-log-group.json -} +# CloudWatch Logs group resource "aws_cloudwatch_log_group" "this" { name = "/aws/lambda/${var.function_name}" @@ -74,6 +72,12 @@ resource "aws_cloudwatch_log_group" "this" { tags = var.tags } +resource "aws_iam_role_policy" "cloudwatch-log-group" { + role = aws_iam_role.this.name + name = "cloudwatch-log-group" + policy = data.aws_iam_policy_document.cloudwatch-log-group.json +} + data "aws_iam_policy_document" "cloudwatch-log-group" { statement { actions = ["logs:DescribeLogStreams"] @@ -86,7 +90,6 @@ data "aws_iam_policy_document" "cloudwatch-log-group" { } } - # Secret environment variables locals { From fb8061a4b8947bbdcb5ea108401d48105f5991a0 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Fri, 12 Aug 2022 15:25:55 +0200 Subject: [PATCH 03/15] Update variables.tf --- variables.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/variables.tf b/variables.tf index 1dee506..eca2c0f 100644 --- a/variables.tf +++ b/variables.tf @@ -100,16 +100,16 @@ variable "timeout" { variable "vpc_config" { type = object({ - vpc = object({ - id = string - }) - subnets = list( object({ arn = string id = string }) ) + + vpc = object({ + id = string + }) }) default = null @@ -117,8 +117,8 @@ variable "vpc_config" { description = < Date: Sun, 14 Aug 2022 13:29:32 +0200 Subject: [PATCH 04/15] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 576c848..8a1499d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.terraform* /_test/.terraform /_test/.terraform.lock.hcl From 198ba9fcce40c224ca457efc8546593b513818b4 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 13:32:18 +0200 Subject: [PATCH 05/15] Add security group --- main.tf | 40 ++++++++++++++++++++++++++++++++++++++++ outputs.tf | 6 ++++++ 2 files changed, 46 insertions(+) diff --git a/main.tf b/main.tf index b169816..55294a5 100644 --- a/main.tf +++ b/main.tf @@ -90,6 +90,46 @@ data "aws_iam_policy_document" "cloudwatch-log-group" { } } +# VPC config + +locals { + # convert `var.vpc_config` into a `for_each`-compatible local + vpc_config_key = "lambda" + vpc_configs = var.vpc_config != null ? { (local.vpc_config_key) = var.vpc_config } : {} +} + +resource "aws_security_group" "this" { + for_each = local.vpc_configs + + name = "lambda-${var.function_name}" + description = "Lambda: ${var.function_name}" + vpc_id = each.value.vpc.id + + tags = merge({ + Name = "Lambda: ${var.function_name}" + }, var.tags) + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "egress" { + for_each = aws_security_group.this + + security_group_id = each.value.id + + type = "egress" + cidr_blocks = ["0.0.0.0/0"] + protocol = "-1" + from_port = 0 + to_port = 0 + + lifecycle { + create_before_destroy = true + } +} + # Secret environment variables locals { diff --git a/outputs.tf b/outputs.tf index 1ce9901..c5c37f7 100644 --- a/outputs.tf +++ b/outputs.tf @@ -15,3 +15,9 @@ output "iam_role" { description = "The IAM role the Lambda function will assume." } + +output "security_group" { + value = lookup(aws_security_group.this, local.vpc_config_key, null) + + description = "The VPC security group the Lambda function will use if `var.vpc_config` is specified; `null` otherwise." +} From 11913cdc5988bdd58ebe0de3c59ff8e6ab3cada3 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 13:34:59 +0200 Subject: [PATCH 06/15] reorder resources --- main.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index 55294a5..d275d7f 100644 --- a/main.tf +++ b/main.tf @@ -72,12 +72,6 @@ resource "aws_cloudwatch_log_group" "this" { tags = var.tags } -resource "aws_iam_role_policy" "cloudwatch-log-group" { - role = aws_iam_role.this.name - name = "cloudwatch-log-group" - policy = data.aws_iam_policy_document.cloudwatch-log-group.json -} - data "aws_iam_policy_document" "cloudwatch-log-group" { statement { actions = ["logs:DescribeLogStreams"] @@ -90,6 +84,12 @@ data "aws_iam_policy_document" "cloudwatch-log-group" { } } +resource "aws_iam_role_policy" "cloudwatch-log-group" { + role = aws_iam_role.this.name + name = "cloudwatch-log-group" + policy = data.aws_iam_policy_document.cloudwatch-log-group.json +} + # VPC config locals { From 0e16cacfb26f441bf7a46666fc6e785694237d02 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 14:13:23 +0200 Subject: [PATCH 07/15] specify permissions for VPC usage --- main.tf | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/main.tf b/main.tf index d275d7f..4b5fac1 100644 --- a/main.tf +++ b/main.tf @@ -130,6 +130,65 @@ resource "aws_security_group_rule" "egress" { } } +data "aws_iam_policy_document" "vpc" { + for_each = local.vpc_configs + + statement { + actions = ["ec2:CreateNetworkInterface"] + + resources = flatten([ + "arn:${data.aws_partition.current[local.vpc_config_key].partition}:ec2:${data.aws_region.current[local.vpc_config_key].name}:${data.aws_caller_identity.current[local.vpc_config_key].account_id}:network-interface/*", + each.value.subnets[*].arn, + values(aws_security_group.this)[*].arn + ]) + } + + statement { + actions = ["ec2:DescribeNetworkInterfaces"] + resources = ["*"] + + condition { + variable = "ec2:Region" + test = "StringEquals" + values = [data.aws_region.current[local.vpc_config_key].name] + } + } + + statement { + actions = ["ec2:DeleteNetworkInterface"] + + resources = [ + "arn:${data.aws_partition.current[local.vpc_config_key].partition}:ec2:${data.aws_region.current[local.vpc_config_key].name}:${data.aws_caller_identity.current[local.vpc_config_key].account_id}:network-interface/*", + ] + + condition { + variable = "ec2:Subnet" + test = "StringEquals" + values = each.value.subnets[*].arn + } + } +} + +resource "aws_iam_role_policy" "vpc" { + for_each = data.aws_iam_policy_document.vpc + + role = aws_iam_role.this.name + name = "vpc" + policy = each.value.json +} + +data "aws_partition" "current" { + for_each = local.vpc_configs +} + +data "aws_region" "current" { + for_each = local.vpc_configs +} + +data "aws_caller_identity" "current" { + for_each = local.vpc_configs +} + # Secret environment variables locals { From 6b410d2fdf2698bbab2056cfc522766ae3697b83 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 14:17:25 +0200 Subject: [PATCH 08/15] Specify `vpc_config` for `aws_lambda_function` --- main.tf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main.tf b/main.tf index 4b5fac1..698a3cf 100644 --- a/main.tf +++ b/main.tf @@ -12,6 +12,15 @@ resource "aws_lambda_function" "this" { role = aws_iam_role.this.arn + dynamic "vpc_config" { + for_each = local.vpc_configs + + content { + subnet_ids = vpc_config.value.subnets[*].id + security_group_ids = values(aws_security_group.this)[*].id + } + } + dynamic "environment" { // local.environments is built using a merge, and merges always result in a map // so we can safely assume we're dealing with a map here. From 41e7a0f4e6dcbb55665218efeddb1fa9abdc2bce Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 14:18:43 +0200 Subject: [PATCH 09/15] re-order --- main.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index 698a3cf..0c2e55f 100644 --- a/main.tf +++ b/main.tf @@ -81,6 +81,12 @@ resource "aws_cloudwatch_log_group" "this" { tags = var.tags } +resource "aws_iam_role_policy" "cloudwatch-log-group" { + role = aws_iam_role.this.name + name = "cloudwatch-log-group" + policy = data.aws_iam_policy_document.cloudwatch-log-group.json +} + data "aws_iam_policy_document" "cloudwatch-log-group" { statement { actions = ["logs:DescribeLogStreams"] @@ -93,12 +99,6 @@ data "aws_iam_policy_document" "cloudwatch-log-group" { } } -resource "aws_iam_role_policy" "cloudwatch-log-group" { - role = aws_iam_role.this.name - name = "cloudwatch-log-group" - policy = data.aws_iam_policy_document.cloudwatch-log-group.json -} - # VPC config locals { From 449a3d1b223527367e72851f502ce3ec9ee7cf0a Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Sun, 14 Aug 2022 14:20:19 +0200 Subject: [PATCH 10/15] re-order --- main.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index 0c2e55f..1ee7504 100644 --- a/main.tf +++ b/main.tf @@ -73,6 +73,12 @@ data "aws_iam_policy_document" "lambda-assume-role" { # CloudWatch Logs group +resource "aws_iam_role_policy" "cloudwatch-log-group" { + role = aws_iam_role.this.name + name = "cloudwatch-log-group" + policy = data.aws_iam_policy_document.cloudwatch-log-group.json +} + resource "aws_cloudwatch_log_group" "this" { name = "/aws/lambda/${var.function_name}" @@ -81,12 +87,6 @@ resource "aws_cloudwatch_log_group" "this" { tags = var.tags } -resource "aws_iam_role_policy" "cloudwatch-log-group" { - role = aws_iam_role.this.name - name = "cloudwatch-log-group" - policy = data.aws_iam_policy_document.cloudwatch-log-group.json -} - data "aws_iam_policy_document" "cloudwatch-log-group" { statement { actions = ["logs:DescribeLogStreams"] From f11f6fe5246177999f0e48f2fc5405c2af6149a9 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Fri, 19 Aug 2022 20:21:32 +0200 Subject: [PATCH 11/15] don't check `ec2:Subnet`, but only `ec2:Region` for `ec2:DeleteNetworkInterface` --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 1ee7504..8919631 100644 --- a/main.tf +++ b/main.tf @@ -171,9 +171,9 @@ data "aws_iam_policy_document" "vpc" { ] condition { - variable = "ec2:Subnet" + variable = "ec2:Region" test = "StringEquals" - values = each.value.subnets[*].arn + values = [data.aws_region.current[local.vpc_config_key].name] } } } From fb8af06752cfc6a4beb44f3a9cf3af72dd2f024a Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Mon, 22 Aug 2022 09:24:50 +0200 Subject: [PATCH 12/15] Update main.tf --- main.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main.tf b/main.tf index 8919631..62863e0 100644 --- a/main.tf +++ b/main.tf @@ -169,12 +169,6 @@ data "aws_iam_policy_document" "vpc" { resources = [ "arn:${data.aws_partition.current[local.vpc_config_key].partition}:ec2:${data.aws_region.current[local.vpc_config_key].name}:${data.aws_caller_identity.current[local.vpc_config_key].account_id}:network-interface/*", ] - - condition { - variable = "ec2:Region" - test = "StringEquals" - values = [data.aws_region.current[local.vpc_config_key].name] - } } } From fc125eed58e29b8c9aadea02450b5b2dc49f309a Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Mon, 22 Aug 2022 09:41:51 +0200 Subject: [PATCH 13/15] Update main.tf --- main.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.tf b/main.tf index 62863e0..161ed4c 100644 --- a/main.tf +++ b/main.tf @@ -164,11 +164,11 @@ data "aws_iam_policy_document" "vpc" { } statement { - actions = ["ec2:DeleteNetworkInterface"] - - resources = [ - "arn:${data.aws_partition.current[local.vpc_config_key].partition}:ec2:${data.aws_region.current[local.vpc_config_key].name}:${data.aws_caller_identity.current[local.vpc_config_key].account_id}:network-interface/*", - ] + # It is not possible to restrict this permissions because the Lambda runtime + # is making a DryRun call to this action without any request parameters + # before actually creating the Lambda function. + actions = ["ec2:DeleteNetworkInterface"] + resources = ["*"] } } From 8a535b3a2437d92a2d8783f8ed54264d454c81f0 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Mon, 22 Aug 2022 11:40:43 +0200 Subject: [PATCH 14/15] Update main.tf --- main.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main.tf b/main.tf index 161ed4c..ee24a6c 100644 --- a/main.tf +++ b/main.tf @@ -169,6 +169,12 @@ data "aws_iam_policy_document" "vpc" { # before actually creating the Lambda function. actions = ["ec2:DeleteNetworkInterface"] resources = ["*"] + + condition { + variable = "ec2:Region" + test = "StringEquals" + values = [data.aws_region.current[local.vpc_config_key].name] + } } } From adca1f5d322e01c6ba957b5450faf46afeb614a0 Mon Sep 17 00:00:00 2001 From: Jan Sebastian Siwy Date: Mon, 22 Aug 2022 12:15:37 +0200 Subject: [PATCH 15/15] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f99d3c5..4cdcf4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.3.0 + +- [Add VPC support](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/19) + ## v1.2.1 - [Empty environment is handled correctly](https://github.com/babbel/terraform-aws-lambda-with-inline-code/pull/15)