From e597f2029311ac36a7424e5c31ec6a9e3400c68e Mon Sep 17 00:00:00 2001 From: theprashantyadav Date: Mon, 19 Jun 2023 20:52:43 +0530 Subject: [PATCH] feat: added security-group-rule and kms main.tf --- _example/basic_example/example.tf | 82 +++------ _example/ebs_mount/example.tf | 82 +++------ _example/ebs_mount/versions.tf | 11 -- main.tf | 127 ++++++++++++- variables.tf | 170 +++++++++++++++++- .../basic_example/versions.tf => versions.tf | 4 +- 6 files changed, 327 insertions(+), 149 deletions(-) delete mode 100644 _example/ebs_mount/versions.tf rename _example/basic_example/versions.tf => versions.tf (64%) diff --git a/_example/basic_example/example.tf b/_example/basic_example/example.tf index 1e59f00..cc79922 100644 --- a/_example/basic_example/example.tf +++ b/_example/basic_example/example.tf @@ -1,7 +1,13 @@ +####---------------------------------------------------------------------------------- +## Provider block added, Use the Amazon Web Services (AWS) provider to interact with the many resources supported by AWS. +####---------------------------------------------------------------------------------- provider "aws" { region = "eu-west-1" } +####---------------------------------------------------------------------------------- +## A VPC is a virtual network that closely resembles a traditional network that you'd operate in your own data center. +####---------------------------------------------------------------------------------- module "vpc" { source = "clouddrove/vpc/aws" version = "1.3.1" @@ -13,6 +19,9 @@ module "vpc" { cidr_block = "172.16.0.0/16" } +####---------------------------------------------------------------------------------- +## A subnet is a range of IP addresses in your VPC. +####---------------------------------------------------------------------------------- module "public_subnets" { source = "clouddrove/subnet/aws" version = "1.3.0" @@ -29,23 +38,11 @@ module "public_subnets" { ipv6_cidr_block = module.vpc.ipv6_cidr_block } -module "http-https" { - source = "clouddrove/security-group/aws" - version = "1.3.0" - name = "http-https" - environment = "test" - label_order = ["name", "environment"] - - vpc_id = module.vpc.vpc_id - allowed_ip = ["0.0.0.0/0"] - allowed_ports = [80, 443] -} - module "keypair" { source = "clouddrove/keypair/aws" version = "1.3.0" - public_key = "ssh-rsa AAAAB3NzaC1yxxxxxxxxxxxxxxQDDIqppj2U2K8norJh5/gxz7sbSSseLd+ldHEOM3+lajUSGqWk3Bw/NgygEf1Kgw7gyK3jsTVVcokhK3TDuR3pi4u2QDR2tW9559zKaR7RJJfjO1u1Onc2tgA3y0btdju2bcYBtFkRVOLwpog8CvslYEDV1Vf9HNeh9A3yOS6Pkjq6gDMrsUVF89ps3zuLmdVBIlCOnJDkwHK71lKihGKdkeXEtAj0aOQzAJsIpDFXz7vob9OiA/fb2T3t4R1EwEsPEnYVczKMsqUyqa+EE36bItcZHQyCPVN7+bRJyJpPcrfrsAa4yMtiHUUiecPdL/6HYwGHxA5rUX3uD2UBm6sbGBH00ZCj6yUxl2UQR5NE4NR35NI86Q+q1kNOc5VctxxQOTHBwKHaGvKLk4c5gHXaEl8yyYL0wVkL00KYx3GCh1LvRdQL8fvzImBCN" + public_key = "HEOM3+lajUSGqWk3Bw/NgygEf1Kgw7gyK3jsTVVcokhK3TDuR3pi4u2QDR2tvLXddPKd37a2S7rjeqecw+XRW9559zKaR7RJJfjO1u1Onc2tgA3y0btdju2bcYBtFkRVOLwpog8CvslYEDLmdVBIlCOnJDkwHK71lKihGKdkeXEtAj0aOQzAJsIpDFXz7vob9OiA/fb2T3t4R1EwEsPEnYVczKMsqUyqa+EE36bItcZHQyCPVN7+bRJyJpPcrfrsAa4yMtiHUUiecPdL/6HYwGHxA5rUX3uD2UBm6sbGBH00ZCj6yUxl2UQR5NE4NR35NI86Q+q1kNOc5VctxxQOTHBwKHaGvKLk4c5gHXaEl8yyYL0wVkL00KYx3GCh1" key_name = "devops" environment = "test" label_order = ["name", "environment"] @@ -53,18 +50,6 @@ module "keypair" { } -module "ssh" { - source = "clouddrove/security-group/aws" - version = "1.3.0" - name = "ssh" - environment = "test" - label_order = ["name", "environment"] - - vpc_id = module.vpc.vpc_id - allowed_ip = [module.vpc.vpc_cidr_block, "0.0.0.0/0"] - allowed_ports = [22] -} - module "iam-role" { source = "clouddrove/iam-role/aws" version = "1.3.0" @@ -78,36 +63,6 @@ module "iam-role" { policy = data.aws_iam_policy_document.iam-policy.json } -module "kms_key" { - source = "clouddrove/kms/aws" - version = "1.3.0" - name = "kms" - environment = "test" - label_order = ["environment", "name"] - enabled = true - description = "KMS key for ec2" - deletion_window_in_days = 7 - enable_key_rotation = true - alias = "alias/ec3" - policy = data.aws_iam_policy_document.kms.json -} - - -data "aws_iam_policy_document" "kms" { - version = "2012-10-17" - statement { - sid = "Enable IAM User Permissions" - effect = "Allow" - principals { - type = "AWS" - identifiers = ["*"] - } - actions = ["kms:*"] - resources = ["*"] - } - -} - data "aws_iam_policy_document" "default" { statement { effect = "Allow" @@ -138,6 +93,13 @@ module "ec2" { environment = "test" label_order = ["name", "environment"] + ####---------------------------------------------------------------------------------- + ## Below A security group controls the traffic that is allowed to reach and leave the resources that it is associated with. + ####---------------------------------------------------------------------------------- + vpc_id = module.vpc.vpc_id + ssh_allowed_ip = ["0.0.0.0/0"] + ssh_allowed_ports = [22] + #instance instance_enabled = true instance_count = 1 @@ -148,7 +110,6 @@ module "ec2" { hibernation = false #Networking - vpc_security_group_ids_list = [module.ssh.security_group_ids, module.http-https.security_group_ids] subnet_ids = tolist(module.public_subnets.public_subnet_id) assign_eip_address = true associate_public_ip_address = true @@ -166,16 +127,15 @@ module "ec2" { volume_type = "gp2" volume_size = 15 delete_on_termination = true - kms_key_id = module.kms_key.key_arn } ] #EBS Volume multi_attach_enabled = false - ebs_optimized = false - ebs_volume_enabled = false - ebs_volume_type = "gp2" - ebs_volume_size = 30 + ebs_optimized = false + ebs_volume_enabled = false + ebs_volume_type = "gp2" + ebs_volume_size = 30 #DNS dns_enabled = false diff --git a/_example/ebs_mount/example.tf b/_example/ebs_mount/example.tf index 4b42a0a..21a53d6 100644 --- a/_example/ebs_mount/example.tf +++ b/_example/ebs_mount/example.tf @@ -1,7 +1,13 @@ +####---------------------------------------------------------------------------------- +## Provider block added, Use the Amazon Web Services (AWS) provider to interact with the many resources supported by AWS. +####---------------------------------------------------------------------------------- provider "aws" { region = "eu-west-1" } +####---------------------------------------------------------------------------------- +## A VPC is a virtual network that closely resembles a traditional network that you'd operate in your own data center. +####---------------------------------------------------------------------------------- module "vpc" { source = "clouddrove/vpc/aws" version = "1.3.1" @@ -13,6 +19,9 @@ module "vpc" { cidr_block = "172.16.0.0/16" } +####---------------------------------------------------------------------------------- +## A subnet is a range of IP addresses in your VPC. +####---------------------------------------------------------------------------------- module "public_subnets" { source = "clouddrove/subnet/aws" version = "1.3.0" @@ -29,35 +38,11 @@ module "public_subnets" { ipv6_cidr_block = module.vpc.ipv6_cidr_block } -module "http-https" { - source = "clouddrove/security-group/aws" - version = "1.3.0" - name = "http-https" - environment = "test" - label_order = ["name", "environment"] - - vpc_id = module.vpc.vpc_id - allowed_ip = ["0.0.0.0/0"] - allowed_ports = [80, 443] -} - -module "ssh" { - source = "clouddrove/security-group/aws" - version = "1.3.0" - name = "ssh" - environment = "test" - label_order = ["name", "environment"] - - vpc_id = module.vpc.vpc_id - allowed_ip = [module.vpc.vpc_cidr_block, "0.0.0.0/0"] - allowed_ports = [22] -} - module "keypair" { source = "clouddrove/keypair/aws" version = "1.3.0" - public_key = "ssh-rsa AAAAB3NLd+ldHEOM3+lajUSGqWk3Bw/NgygEf1Kgw7gyK3jsTVVcokhK3TDuR3pi4u2QDR2tvLXddPKd37a2S7rjeqecw+XRW9559zKaR7RJJfjO1u1Onc2tgA3y0btdju2bcYBtFkRVOLwpog8CvslYEDV1Vf9HNeh9A3yOS6Pkjq6gDMrsUVF89ps3zuLmdVBIlCOnJDkwHK71lKihGKdkeXEtAj0aOQzAJsIpDFXz7vob9OiA/fb2T3t4R1EwEsPEnYVczKMsqUyqa+EE36bItcZHQyCPVN7+bRJyJpPcrfrsAa4yMBm6sbGBH00ZCj6yUxl2UQR5NE4NR35NI86Q" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDIqppj2U2K8norJh5/gxz7sbSSseLd+ldHEOM3+lajUSGqWk3Bw/NgygEf1Kgw7gyK3jsTVVcokhK3TDuR3pi4u2QDR2tvLXddPKd37a2S7rjeqecw+XRW9559zKaR7RJJfjO1u1Onc2tgA3y0btdju2bcYBtFkRVOLwpog8CvslYEDV1Vf9HNeh9A3yOS6Pkjq6gDMrsUVF89ps3zuLmdVBIlCOnJDkwHK71lKihGKdkeXEtAj0aOQzAJsIpDFXz7vob9OiA/fb2T3t4R1EwEsPEnYVczKMsqUyqa+EE36bItcZHQyCPVN7+bRJyJpPcrfrsAa4yMtiHUUiecPdL/6HYwGHxA5rUX3uD2UBm6sbGBH00ZCj6yUxl2UQR5NE4NR35NI86Q+q1kNOc5VctxxQOTHBwKHaGvKLk4c5gHXaEl8yyYL0wVkL00KYx3GCh1LvRdQL8fvzImBCNgZdSpKT2xjq/wc5c9L9NSc43TGoldnDYUjm79qAYMlwQHr0= prashant@prashant" key_name = "devops" environment = "test" label_order = ["name", "environment"] @@ -77,36 +62,6 @@ module "iam-role" { policy = data.aws_iam_policy_document.iam-policy.json } -module "kms_key" { - source = "clouddrove/kms/aws" - version = "1.3.0" - name = "kms" - environment = "test" - label_order = ["environment", "name"] - enabled = true - description = "KMS key for ec2" - deletion_window_in_days = 7 - enable_key_rotation = true - alias = "alias/ec2" - policy = data.aws_iam_policy_document.kms.json -} - - -data "aws_iam_policy_document" "kms" { - version = "2012-10-17" - statement { - sid = "Enable IAM User Permissions" - effect = "Allow" - principals { - type = "AWS" - identifiers = ["*"] - } - actions = ["kms:*"] - resources = ["*"] - } - -} - data "aws_iam_policy_document" "default" { statement { effect = "Allow" @@ -138,6 +93,13 @@ module "ec2" { environment = "test" label_order = ["name", "environment"] + ####---------------------------------------------------------------------------------- + ## Below A security group controls the traffic that is allowed to reach and leave the resources that it is associated with. + ####---------------------------------------------------------------------------------- + vpc_id = module.vpc.vpc_id + ssh_allowed_ip = ["0.0.0.0/0"] + ssh_allowed_ports = [22] + #Instance instance_enabled = true instance_count = 2 @@ -150,7 +112,6 @@ module "ec2" { key_name = module.keypair.name #Networking - vpc_security_group_ids_list = [module.ssh.security_group_ids, module.http-https.security_group_ids] subnet_ids = tolist(module.public_subnets.public_subnet_id) assign_eip_address = true associate_public_ip_address = true @@ -165,16 +126,15 @@ module "ec2" { volume_type = "gp2" volume_size = 15 delete_on_termination = true - kms_key_id = module.kms_key.key_arn } ] #EBS Volume multi_attach_enabled = false - ebs_optimized = false - ebs_volume_enabled = true - ebs_volume_type = "gp2" - ebs_volume_size = 30 + ebs_optimized = false + ebs_volume_enabled = true + ebs_volume_type = "gp2" + ebs_volume_size = 30 #DNS dns_enabled = false diff --git a/_example/ebs_mount/versions.tf b/_example/ebs_mount/versions.tf deleted file mode 100644 index cbc6f9c..0000000 --- a/_example/ebs_mount/versions.tf +++ /dev/null @@ -1,11 +0,0 @@ -# Terraform version -terraform { - required_version = ">= 1.3.6" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.48.0" - } - } -} \ No newline at end of file diff --git a/main.tf b/main.tf index 5979f39..271d87e 100644 --- a/main.tf +++ b/main.tf @@ -38,6 +38,119 @@ data "template_file" "userdata" { template = "userdata.sh" } +##---------------------------------------------------------------------------------- +## Below resources will create SECURITY-GROUP and its components. +##---------------------------------------------------------------------------------- +resource "aws_security_group" "default" { + count = var.enable_security_group && length(var.sg_ids) < 1 ? 1 : 0 + + name = format("%s-sg", module.labels.id) + vpc_id = var.vpc_id + description = var.sg_description + tags = module.labels.tags + lifecycle { + create_before_destroy = true + } +} + +data "aws_security_group" "existing" { + count = var.is_external ? 1 : 0 + id = var.existing_sg_id + vpc_id = var.vpc_id +} + +##---------------------------------------------------------------------------------- +## Below resources will create SECURITY-GROUP-RULE and its components. +##---------------------------------------------------------------------------------- +#tfsec:ignore:aws-ec2-no-public-egress-sgr +resource "aws_security_group_rule" "egress" { + count = (var.enable_security_group == true && length(var.sg_ids) < 1 && var.is_external == false && var.egress_rule == true) ? 1 : 0 + + description = var.sg_egress_description + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_group_id = join("", aws_security_group.default.*.id) +} +#tfsec:ignore:aws-ec2-no-public-egress-sgr +resource "aws_security_group_rule" "egress_ipv6" { + count = (var.enable_security_group == true && length(var.sg_ids) < 1 && var.is_external == false) && var.egress_rule == true ? 1 : 0 + + description = var.sg_egress_ipv6_description + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + ipv6_cidr_blocks = ["::/0"] + security_group_id = join("", aws_security_group.default.*.id) +} +resource "aws_security_group_rule" "ssh_ingress" { + count = length(var.ssh_allowed_ip) > 0 == true && length(var.sg_ids) < 1 ? length(compact(var.ssh_allowed_ports)) : 0 + + description = var.ssh_sg_ingress_description + type = "ingress" + from_port = element(var.ssh_allowed_ports, count.index) + to_port = element(var.ssh_allowed_ports, count.index) + protocol = var.ssh_protocol + cidr_blocks = var.ssh_allowed_ip + security_group_id = join("", aws_security_group.default.*.id) +} + +resource "aws_security_group_rule" "ingress" { + count = length(var.allowed_ip) > 0 == true && length(var.sg_ids) < 1 ? length(compact(var.allowed_ports)) : 0 + + description = var.sg_ingress_description + type = "ingress" + from_port = element(var.allowed_ports, count.index) + to_port = element(var.allowed_ports, count.index) + protocol = var.protocol + cidr_blocks = var.allowed_ip + security_group_id = join("", aws_security_group.default.*.id) +} + + +##---------------------------------------------------------------------------------- +## Below resources will create KMS-KEY and its components. +##---------------------------------------------------------------------------------- +resource "aws_kms_key" "default" { + count = var.kms_key_enabled && var.kms_key_id == "" ? 1 : 0 + + description = var.kms_description + key_usage = var.key_usage + deletion_window_in_days = var.deletion_window_in_days + is_enabled = var.is_enabled + enable_key_rotation = var.enable_key_rotation + customer_master_key_spec = var.customer_master_key_spec + policy = data.aws_iam_policy_document.kms.json + multi_region = var.kms_multi_region + tags = module.labels.tags +} + +resource "aws_kms_alias" "default" { + count = var.kms_key_enabled && var.kms_key_id == "" ? 1 : 0 + + name = coalesce(var.alias, format("alias/%v", module.labels.id)) + target_key_id = var.kms_key_id == "" ? join("", aws_kms_key.default.*.id) : var.kms_key_id +} + +data "aws_iam_policy_document" "kms" { + version = "2012-10-17" + statement { + sid = "Enable IAM User Permissions" + effect = "Allow" + principals { + type = "AWS" + identifiers = ["*"] + } + actions = ["kms:*"] + resources = ["*"] + } + +} + + #Module : EC2 #Description : Terraform module to create an EC2 resource on AWS with Elastic IP Addresses @@ -51,7 +164,7 @@ resource "aws_instance" "default" { instance_type = var.instance_type key_name = var.key_name monitoring = var.monitoring - vpc_security_group_ids = var.vpc_security_group_ids_list + vpc_security_group_ids = length(var.sg_ids) < 1 ? aws_security_group.default.*.id : var.sg_ids subnet_id = element(distinct(compact(concat(var.subnet_ids))), count.index) associate_public_ip_address = var.associate_public_ip_address disable_api_termination = var.disable_api_termination @@ -153,13 +266,13 @@ resource "aws_eip" "default" { resource "aws_ebs_volume" "default" { count = var.instance_enabled == true && var.ebs_volume_enabled == true ? var.instance_count : 0 - availability_zone = element(aws_instance.default.*.availability_zone, count.index) - size = var.ebs_volume_size - iops = local.ebs_iops - type = var.ebs_volume_type + availability_zone = element(aws_instance.default.*.availability_zone, count.index) + size = var.ebs_volume_size + iops = local.ebs_iops + type = var.ebs_volume_type multi_attach_enabled = var.multi_attach_enabled - encrypted = true - kms_key_id = var.kms_key_id + encrypted = true + kms_key_id = var.kms_key_id == "" ? join("", aws_kms_key.default.*.arn) : var.kms_key_id tags = merge(module.labels.tags, { "Name" = format("%s-ebs-volume%s%s", module.labels.id, var.delimiter, (count.index)) }, diff --git a/variables.tf b/variables.tf index ad42720..abb48d7 100644 --- a/variables.tf +++ b/variables.tf @@ -309,13 +309,6 @@ variable "ttl" { description = "The TTL of the record to add to the DNS zone to complete certificate validation." } -variable "kms_key_id" { - type = string - default = "" - description = "The ARN for the KMS encryption key. When specifying kms_key_id, encrypted needs to be set to true." - sensitive = true -} - variable "metadata_http_tokens_required" { type = string default = "optional" @@ -344,4 +337,167 @@ variable "multi_attach_enabled" { type = bool default = true description = "Specifies whether to enable Amazon EBS Multi-Attach. Multi-Attach is supported on io1 and io2 volumes." +} + +variable "kms_key_enabled" { + type = bool + default = true + description = "Specifies whether the kms is enabled or disabled." +} + +variable "kms_key_id" { + type = string + default = "" + description = "The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. Can be specified only if at_rest_encryption_enabled = true." +} + +variable "alias" { + type = string + default = "alias/redissss" + description = "The display name of the alias. The name must start with the word `alias` followed by a forward slash." +} + +variable "kms_description" { + type = string + default = "Parameter Store KMS master key" + description = "The description of the key as viewed in AWS console." +} + +variable "key_usage" { + type = string + default = "ENCRYPT_DECRYPT" + sensitive = true + description = "Specifies the intended use of the key. Defaults to ENCRYPT_DECRYPT, and only symmetric encryption and decryption are supported." +} + +variable "deletion_window_in_days" { + type = number + default = 7 + description = "Duration in days after which the key is deleted after destruction of the resource." +} + +variable "is_enabled" { + type = bool + default = true + description = "Specifies whether the key is enabled." +} + +variable "enable_key_rotation" { + type = string + default = true + description = "Specifies whether key rotation is enabled." +} + +variable "customer_master_key_spec" { + type = string + default = "SYMMETRIC_DEFAULT" + description = "Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: SYMMETRIC_DEFAULT, RSA_2048, RSA_3072, RSA_4096, ECC_NIST_P256, ECC_NIST_P384, ECC_NIST_P521, or ECC_SECG_P256K1. Defaults to SYMMETRIC_DEFAULT." + sensitive = true +} + +variable "kms_multi_region" { + type = bool + default = false + description = "Indicates whether the KMS key is a multi-Region (true) or regional (false) key." +} +variable "vpc_id" { + type = string + default = "" + description = "The ID of the VPC that the instance security group belongs to." + sensitive = true +} + +variable "allowed_ip" { + type = list(any) + default = ["0.0.0.0/0"] + description = "List of allowed ip." +} + +variable "allowed_ports" { + type = list(any) + default = [80, 443] + description = "List of allowed ingress ports" +} + +variable "protocol" { + type = string + default = "tcp" + description = "The protocol. If not icmp, tcp, udp, or all use the." +} + +variable "enable_security_group" { + type = bool + default = true + description = "Enable default Security Group with only Egress traffic allowed." +} + +variable "existing_sg_id" { + type = string + default = null + description = "Provide existing security group id for updating existing rule" +} + +variable "egress_rule" { + type = bool + default = true + description = "Enable to create egress rule" +} + +variable "is_external" { + type = bool + default = false + description = "enable to udated existing security Group" +} + +variable "sg_ids" { + type = list(any) + default = [] + description = "of the security group id." +} + +variable "sg_description" { + type = string + default = "Instance default security group (only egress access is allowed)." + description = "The security group description." +} +variable "sg_egress_description" { + type = string + default = "Description of the rule." + description = "Description of the egress and ingress rule" +} + +variable "sg_egress_ipv6_description" { + type = string + default = "Description of the rule." + description = "Description of the egress_ipv6 rule" +} + +variable "sg_ingress_description" { + type = string + default = "Description of the ingress rule use elasticache." + description = "Description of the ingress rule" +} + +variable "ssh_allowed_ip" { + type = list(any) + default = [] + description = "List of allowed ip." +} + +variable "ssh_allowed_ports" { + type = list(any) + default = [] + description = "List of allowed ingress ports" +} + +variable "ssh_protocol" { + type = string + default = "tcp" + description = "The protocol. If not icmp, tcp, udp, or all use the." +} + +variable "ssh_sg_ingress_description" { + type = string + default = "Description of the ingress rule use elasticache." + description = "Description of the ingress rule" } \ No newline at end of file diff --git a/_example/basic_example/versions.tf b/versions.tf similarity index 64% rename from _example/basic_example/versions.tf rename to versions.tf index cbc6f9c..9317499 100644 --- a/_example/basic_example/versions.tf +++ b/versions.tf @@ -1,11 +1,11 @@ # Terraform version terraform { - required_version = ">= 1.3.6" + required_version = ">= 1.4.6" required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.48.0" + version = ">= 5.1.0" } } } \ No newline at end of file