From 5003b0dba51fe230a4d6a6161c7a81dbd0e0d9df Mon Sep 17 00:00:00 2001 From: Rizal Diantoro Date: Tue, 12 Nov 2024 11:21:37 +0700 Subject: [PATCH 1/2] Allow client to create new security group --- main.tf | 61 ++++++++++++++++++++++++++++++++++++++-- outputs.tf | 16 +++++++++++ variables.tf | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index 749e67d4..01e49450 100644 --- a/main.tf +++ b/main.tf @@ -6,6 +6,12 @@ locals { is_t_instance_type = replace(var.instance_type, "/^t(2|3|3a|4g){1}\\..*$/", "1") == "1" ? true : false ami = try(coalesce(var.ami, try(nonsensitive(data.aws_ssm_parameter.this[0].value), null)), null) + + security_group_name = try(coalesce(var.security_group_name, "${var.name}-sg"), "") + sg_ingress_rules = try(lookup(var.security_group_rules, "ingress", {}), {}) + create_sg_ingress_rule = length(keys(local.sg_ingress_rules)) > 0 ? true : false + sg_egress_rules = try(lookup(var.security_group_rules, "egress", {}), {}) + create_sg_egress_rule = length(keys(local.sg_egress_rules)) > 0 ? true : false } data "aws_ssm_parameter" "this" { @@ -33,7 +39,7 @@ resource "aws_instance" "this" { availability_zone = var.availability_zone subnet_id = var.subnet_id - vpc_security_group_ids = var.vpc_security_group_ids + vpc_security_group_ids = compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) key_name = var.key_name monitoring = var.monitoring @@ -211,7 +217,7 @@ resource "aws_instance" "ignore_ami" { availability_zone = var.availability_zone subnet_id = var.subnet_id - vpc_security_group_ids = var.vpc_security_group_ids + vpc_security_group_ids = compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) key_name = var.key_name monitoring = var.monitoring @@ -395,7 +401,7 @@ resource "aws_spot_instance_request" "this" { availability_zone = var.availability_zone subnet_id = var.subnet_id - vpc_security_group_ids = var.vpc_security_group_ids + vpc_security_group_ids = compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) key_name = var.key_name monitoring = var.monitoring @@ -620,3 +626,52 @@ resource "aws_eip" "this" { tags = merge(var.tags, var.eip_tags) } + +################################################################################ +# Security Group +################################################################################ + +resource "aws_security_group" "this" { + count = local.create && var.create_security_group ? 1 : 0 + + name = var.security_group_use_name_prefix ? null : local.security_group_name + name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null + vpc_id = var.vpc_id + description = coalesce(var.security_group_description, "Control traffic to/from EC2 instance ${var.name}") + + tags = merge(var.tags, var.security_group_tags, { Name = local.security_group_name }) + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_vpc_security_group_egress_rule" "this" { + for_each = { for k, v in local.sg_egress_rules : k => v if local.create && var.create_security_group && local.create_sg_egress_rule } + + security_group_id = aws_security_group.this[0].id + cidr_ipv4 = each.value.cidr_ipv4 + cidr_ipv6 = each.value.cidr_ipv6 + description = each.value.description + from_port = each.value.from_port + to_port = each.value.to_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 + tags = merge(try(each.value.tags, {}), var.security_group_tags, { Name = local.security_group_name }) +} + +resource "aws_vpc_security_group_ingress_rule" "this" { + for_each = { for k, v in local.sg_ingress_rules : k => v if local.create && var.create_security_group && local.create_sg_ingress_rule } + + security_group_id = aws_security_group.this[0].id + cidr_ipv4 = each.value.cidr_ipv4 + cidr_ipv6 = each.value.cidr_ipv6 + description = each.value.description + from_port = each.value.from_port + to_port = each.value.to_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 + tags = merge(try(each.value.tags, {}), var.security_group_tags, { Name = local.security_group_name }) +} diff --git a/outputs.tf b/outputs.tf index 3f57b650..9957c409 100644 --- a/outputs.tf +++ b/outputs.tf @@ -230,3 +230,19 @@ output "ephemeral_block_device" { null ) } + +################################################################################ +# Security Group +################################################################################ + +output "security_group_id" { + description = "The security group ID of the cluster" + value = try(aws_security_group.this[0].id, null) +} + +output "egress_security_group_rule_ids" { + description = "The egress security group rule IDs of the cluster" + value = { + for k, v in try(aws_vpc_security_group_egress_rule.this, {}) : k => v + } +} diff --git a/variables.tf b/variables.tf index 38a1b5b2..1f80ba2e 100644 --- a/variables.tf +++ b/variables.tf @@ -430,3 +430,82 @@ variable "eip_tags" { type = map(string) default = {} } + +################################################################################ +# Security Group +################################################################################ +variable "create_security_group" { + description = "Determines whether to create security group for EC2 instance" + type = bool + default = true +} + +variable "security_group_name" { + description = "The security group name. Default value is (`var.name`)" + type = string + default = "" +} + +variable "security_group_use_name_prefix" { + description = "Determines whether the security group name (`var.name`) is used as a prefix" + type = bool + default = true +} + +variable "security_group_description" { + description = "The description of the security group." + type = string + default = null +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string + default = "" +} + +variable "security_group_rules" { + description = "Map of security group rules to add to the cluster security group created" + type = object({ + ingress = optional(map(object({ + cidr_ipv4 = optional(string) + cidr_ipv6 = optional(string) + description = optional(string) + from_port = optional(number) + ip_protocol = optional(string) + prefix_list_id = optional(string) + referenced_security_group_id = optional(string) + tags = optional(map(string)) + to_port = optional(number) + }))) + egress = optional(map(object({ + cidr_ipv4 = optional(string) + cidr_ipv6 = optional(string) + description = optional(string) + from_port = optional(number) + ip_protocol = optional(string) + prefix_list_id = optional(string) + referenced_security_group_id = optional(string) + tags = optional(map(string)) + to_port = optional(number) + }))) + }) + default = { + ingress = {} + egress = { + all_https = { + cidr_ipv4 = "0.0.0.0/0" + description = "Allow all outbound HTTPS traffic" + from_port = 443 + ip_protocol = "tcp" + to_port = 443 + } + } + } +} + +variable "security_group_tags" { + description = "Additional tags for the security group" + type = map(string) + default = {} +} From d863999994f8e3ea661318db211c1c47f8c9fe33 Mon Sep 17 00:00:00 2001 From: Rizal Diantoro Date: Tue, 12 Nov 2024 11:22:25 +0700 Subject: [PATCH 2/2] Add more ouputs --- outputs.tf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/outputs.tf b/outputs.tf index 9957c409..dc4eb312 100644 --- a/outputs.tf +++ b/outputs.tf @@ -246,3 +246,10 @@ output "egress_security_group_rule_ids" { for k, v in try(aws_vpc_security_group_egress_rule.this, {}) : k => v } } + +output "ingress_security_group_rule_ids" { + description = "The ingress security group rule IDs of the cluster" + value = { + for k, v in try(aws_vpc_security_group_rule.this, {}) : k => v + } +}