From 366b8b55e22b60b6382dfa57596c19e599f69dc7 Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 15 Dec 2023 10:35:49 +0100 Subject: [PATCH 1/6] Add security group as input --- main.tf | 18 ++---------------- outputs.tf | 2 +- variables.tf | 22 ++++------------------ 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/main.tf b/main.tf index 45a76ea..0b04c54 100644 --- a/main.tf +++ b/main.tf @@ -72,7 +72,7 @@ data "aws_subnet" "selected" { resource "aws_security_group" "default" { #checkov:skip=CKV2_AWS_5: False positive finding, the security group is attached. - count = var.subnet_ids != null ? 1 : 0 + count = var.subnet_ids != null && var.security_group_id == null ? 1 : 0 name = var.security_group_name_prefix == null ? var.name : null name_prefix = var.security_group_name_prefix != null ? var.security_group_name_prefix : null @@ -85,20 +85,6 @@ resource "aws_security_group" "default" { } } -resource "aws_vpc_security_group_egress_rule" "default" { - for_each = var.subnet_ids != null && length(var.security_group_egress_rules) != 0 ? { for v in var.security_group_egress_rules : v.description => v } : {} - - cidr_ipv4 = each.value.cidr_ipv4 - cidr_ipv6 = each.value.cidr_ipv6 - description = each.value.description - from_port = each.value.from_port - ip_protocol = each.value.ip_protocol - prefix_list_id = each.value.prefix_list_id - referenced_security_group_id = each.value.referenced_security_group_id - security_group_id = aws_security_group.default[0].id - to_port = each.value.to_port -} - data "archive_file" "dummy" { type = "zip" output_path = "${path.module}/dummy_payload.zip" @@ -204,7 +190,7 @@ resource "aws_lambda_function" "default" { content { subnet_ids = var.subnet_ids - security_group_ids = [aws_security_group.default[0].id] + security_group_ids = [var.security_group_id != null ? var.security_group_id : aws_security_group.default[0].id] } } diff --git a/outputs.tf b/outputs.tf index e7064e0..4015207 100644 --- a/outputs.tf +++ b/outputs.tf @@ -24,7 +24,7 @@ output "role_arn" { } output "security_group_id" { - value = var.subnet_ids != null ? aws_security_group.default[0].id : "" + value = var.subnet_ids != null ? var.security_group_id != null ? var.security_group_id : aws_security_group.default[0].id : "" description = "If the Lambda is deployed into a VPC this will output the security group id" } diff --git a/variables.tf b/variables.tf index c5ec2c0..dd38dca 100644 --- a/variables.tf +++ b/variables.tf @@ -176,24 +176,10 @@ variable "s3_object_version" { description = "The object version containing the function's deployment package" } -variable "security_group_egress_rules" { - type = list(object({ - cidr_ipv4 = optional(string) - cidr_ipv6 = optional(string) - description = string - from_port = optional(number, 0) - ip_protocol = optional(string, "-1") - prefix_list_id = optional(string) - referenced_security_group_id = optional(string) - to_port = optional(number, 0) - })) - default = [] - description = "Security Group egress rules" - - validation { - condition = alltrue([for o in var.security_group_egress_rules : (o.cidr_ipv4 != null || o.cidr_ipv6 != null || o.prefix_list_id != null || o.referenced_security_group_id != null)]) - error_message = "Although \"cidr_ipv4\", \"cidr_ipv6\", \"prefix_list_id\", and \"referenced_security_group_id\" are all marked as optional, you must provide one of them in order to configure the destination of the traffic." - } +variable "security_group_id" { + type = string + default = null + description = "The security group for running the Lambda within the VPC. If not specified a minimal default SG will be created" } variable "security_group_name_prefix" { From 60ecab4aec4d445e133af1822a5955aca5308922 Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Fri, 15 Dec 2023 16:19:23 +0100 Subject: [PATCH 2/6] Restore SG Egress --- main.tf | 14 ++++++++++++++ variables.tf | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/main.tf b/main.tf index 0b04c54..af789df 100644 --- a/main.tf +++ b/main.tf @@ -85,6 +85,20 @@ resource "aws_security_group" "default" { } } +resource "aws_vpc_security_group_egress_rule" "default" { + for_each = var.subnet_ids != null && length(var.security_group_egress_rules) != 0 ? { for v in var.security_group_egress_rules : v.description => v } : {} + + cidr_ipv4 = each.value.cidr_ipv4 + cidr_ipv6 = each.value.cidr_ipv6 + description = each.value.description + from_port = each.value.from_port + ip_protocol = each.value.ip_protocol + prefix_list_id = each.value.prefix_list_id + referenced_security_group_id = each.value.referenced_security_group_id + security_group_id = aws_security_group.default[0].id + to_port = each.value.to_port +} + data "archive_file" "dummy" { type = "zip" output_path = "${path.module}/dummy_payload.zip" diff --git a/variables.tf b/variables.tf index dd38dca..4d0a7ff 100644 --- a/variables.tf +++ b/variables.tf @@ -182,6 +182,26 @@ variable "security_group_id" { description = "The security group for running the Lambda within the VPC. If not specified a minimal default SG will be created" } +variable "security_group_egress_rules" { + type = list(object({ + cidr_ipv4 = optional(string) + cidr_ipv6 = optional(string) + description = string + from_port = optional(number, 0) + ip_protocol = optional(string, "-1") + prefix_list_id = optional(string) + referenced_security_group_id = optional(string) + to_port = optional(number, 0) + })) + default = [] + description = "Security Group egress rules" + + validation { + condition = alltrue([for o in var.security_group_egress_rules : (o.cidr_ipv4 != null || o.cidr_ipv6 != null || o.prefix_list_id != null || o.referenced_security_group_id != null)]) + error_message = "Although \"cidr_ipv4\", \"cidr_ipv6\", \"prefix_list_id\", and \"referenced_security_group_id\" are all marked as optional, you must provide one of them in order to configure the destination of the traffic." + } +} + variable "security_group_name_prefix" { type = string default = null From 7c6dde67ea215cd0c02b28eb035d6212258c726a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 15 Dec 2023 15:19:53 +0000 Subject: [PATCH 3/6] docs(readme): update module usage --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 95d66a0..d242f4d 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ No modules. | [s3\_key](#input\_s3\_key) | The S3 key of an object containing the function's deployment package | `string` | `null` | no | | [s3\_object\_version](#input\_s3\_object\_version) | The object version containing the function's deployment package | `string` | `null` | no | | [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Security Group egress rules |
list(object({
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = string
from_port = optional(number, 0)
ip_protocol = optional(string, "-1")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
to_port = optional(number, 0)
}))
| `[]` | no | +| [security\_group\_id](#input\_security\_group\_id) | The security group for running the Lambda within the VPC. If not specified a minimal default SG will be created | `string` | `null` | no | | [security\_group\_name\_prefix](#input\_security\_group\_name\_prefix) | An optional prefix to create a unique name of the security group. If not provided `var.name` will be used | `string` | `null` | no | | [source\_code\_hash](#input\_source\_code\_hash) | Optional source code hash | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | The subnet ids where this lambda needs to run | `list(string)` | `null` | no | From 0f58d3afecadf24b2ef1e690e4dc2550867ec24e Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Thu, 7 Mar 2024 14:15:12 +0100 Subject: [PATCH 4/6] Change to an array --- .gitignore | 3 +++ main.tf | 5 +++-- outputs.tf | 4 ++-- variables.tf | 8 ++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 1a015fa..d05ed19 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,8 @@ # .tfvars files *.tfvars +# Terraform Lock file +.terraform.lock.hcl + # CheckOv pre-commit external modules path **/.external_modules/* diff --git a/main.tf b/main.tf index af789df..6d82411 100644 --- a/main.tf +++ b/main.tf @@ -9,6 +9,7 @@ locals { source_code_hash = var.source_code_hash != null ? var.source_code_hash : var.filename != null ? filebase64sha256(var.filename) : null tracing_config = var.tracing_config_mode != null ? { create : true } : {} vpc_config = var.subnet_ids != null ? { create : true } : {} + security_group_ids = length(var.security_group_ids) > 0 ? [var.security_group_ids] : [aws_security_group.default[0].id] } data "aws_iam_policy_document" "default" { @@ -72,7 +73,7 @@ data "aws_subnet" "selected" { resource "aws_security_group" "default" { #checkov:skip=CKV2_AWS_5: False positive finding, the security group is attached. - count = var.subnet_ids != null && var.security_group_id == null ? 1 : 0 + count = var.subnet_ids != null && length(var.security_group_ids) == 0 ? 1 : 0 name = var.security_group_name_prefix == null ? var.name : null name_prefix = var.security_group_name_prefix != null ? var.security_group_name_prefix : null @@ -204,7 +205,7 @@ resource "aws_lambda_function" "default" { content { subnet_ids = var.subnet_ids - security_group_ids = [var.security_group_id != null ? var.security_group_id : aws_security_group.default[0].id] + security_group_ids = local.security_group_ids } } diff --git a/outputs.tf b/outputs.tf index 4015207..38330e6 100644 --- a/outputs.tf +++ b/outputs.tf @@ -24,8 +24,8 @@ output "role_arn" { } output "security_group_id" { - value = var.subnet_ids != null ? var.security_group_id != null ? var.security_group_id : aws_security_group.default[0].id : "" - description = "If the Lambda is deployed into a VPC this will output the security group id" + value = try(aws_security_group.default[0].id, "") + description = "If the Lambda is deployed into a VPC this will output the genetered security group id (if no security groups are specified)" } output "version" { diff --git a/variables.tf b/variables.tf index 4d0a7ff..25356b2 100644 --- a/variables.tf +++ b/variables.tf @@ -176,10 +176,10 @@ variable "s3_object_version" { description = "The object version containing the function's deployment package" } -variable "security_group_id" { - type = string - default = null - description = "The security group for running the Lambda within the VPC. If not specified a minimal default SG will be created" +variable "security_group_ids" { + type = list(string) + default = [] + description = "The security group(s) for running the Lambda within the VPC. If not specified a minimal default SG will be created" } variable "security_group_egress_rules" { From 50719e086fd36f35c151a7c4abbbe13c7ea34a9b Mon Sep 17 00:00:00 2001 From: Frank van Boven Date: Thu, 7 Mar 2024 14:20:20 +0100 Subject: [PATCH 5/6] Add new output --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 6d82411..578df63 100644 --- a/main.tf +++ b/main.tf @@ -9,7 +9,7 @@ locals { source_code_hash = var.source_code_hash != null ? var.source_code_hash : var.filename != null ? filebase64sha256(var.filename) : null tracing_config = var.tracing_config_mode != null ? { create : true } : {} vpc_config = var.subnet_ids != null ? { create : true } : {} - security_group_ids = length(var.security_group_ids) > 0 ? [var.security_group_ids] : [aws_security_group.default[0].id] + security_group_ids = length(var.security_group_ids) > 0 ? var.security_group_ids : [aws_security_group.default[0].id] } data "aws_iam_policy_document" "default" { @@ -87,7 +87,7 @@ resource "aws_security_group" "default" { } resource "aws_vpc_security_group_egress_rule" "default" { - for_each = var.subnet_ids != null && length(var.security_group_egress_rules) != 0 ? { for v in var.security_group_egress_rules : v.description => v } : {} + for_each = var.subnet_ids != null && length(var.security_group_ids) == 0 && length(var.security_group_egress_rules) != 0 ? { for v in var.security_group_egress_rules : v.description => v } : {} cidr_ipv4 = each.value.cidr_ipv4 cidr_ipv6 = each.value.cidr_ipv6 From 9e4a08348c7d168b057c533c36f989b002c3acd9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 7 Mar 2024 18:27:57 +0000 Subject: [PATCH 6/6] docs(readme): update module usage --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d242f4d..f563e07 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ No modules. | [s3\_key](#input\_s3\_key) | The S3 key of an object containing the function's deployment package | `string` | `null` | no | | [s3\_object\_version](#input\_s3\_object\_version) | The object version containing the function's deployment package | `string` | `null` | no | | [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Security Group egress rules |
list(object({
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = string
from_port = optional(number, 0)
ip_protocol = optional(string, "-1")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
to_port = optional(number, 0)
}))
| `[]` | no | -| [security\_group\_id](#input\_security\_group\_id) | The security group for running the Lambda within the VPC. If not specified a minimal default SG will be created | `string` | `null` | no | +| [security\_group\_ids](#input\_security\_group\_ids) | The security group(s) for running the Lambda within the VPC. If not specified a minimal default SG will be created | `list(string)` | `[]` | no | | [security\_group\_name\_prefix](#input\_security\_group\_name\_prefix) | An optional prefix to create a unique name of the security group. If not provided `var.name` will be used | `string` | `null` | no | | [source\_code\_hash](#input\_source\_code\_hash) | Optional source code hash | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | The subnet ids where this lambda needs to run | `list(string)` | `null` | no | @@ -93,7 +93,7 @@ No modules. | [name](#output\_name) | Function name of the Lambda | | [qualified\_arn](#output\_qualified\_arn) | Qualified ARN of the Lambda | | [role\_arn](#output\_role\_arn) | ARN of the lambda execution role | -| [security\_group\_id](#output\_security\_group\_id) | If the Lambda is deployed into a VPC this will output the security group id | +| [security\_group\_id](#output\_security\_group\_id) | If the Lambda is deployed into a VPC this will output the genetered security group id (if no security groups are specified) | | [version](#output\_version) | Latest published version of the Lambda function |