From 05a926c073ba1fbaeab26098b8944d7cbff301c1 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:42:33 -0600 Subject: [PATCH 01/20] added variable for name --- variable.tf | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/variable.tf b/variable.tf index 00ed7e3..4a9d923 100644 --- a/variable.tf +++ b/variable.tf @@ -18,6 +18,11 @@ variable "secret_key" { sensitive = true default = "" } +variable "name" { + description = "The name of the application." + type = string + default = "app-4" +} variable "vpc_cidr" { description = "CIDR for the VPC." default = "10.20.32.0/25" @@ -41,8 +46,8 @@ variable "instance_type" { description = "The instance type of the EC2 instances" default = "t3.medium" } -variable "replication_group_id" { - description = "The name of the ElastiCache replication group." - default = "app-4-redis-cluster" - type = string -} \ No newline at end of file +# variable "replication_group_id" { +# description = "The name of the ElastiCache replication group." +# default = "app-4-redis-cluster" +# type = string +# } \ No newline at end of file From e2e47b1494a36795a83d5de66ad35f869d6305cd Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:43:01 -0600 Subject: [PATCH 02/20] converted to variable --- ssm_parameter.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssm_parameter.tf b/ssm_parameter.tf index 9061c5c..81ef073 100644 --- a/ssm_parameter.tf +++ b/ssm_parameter.tf @@ -1,12 +1,12 @@ #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter resource "aws_ssm_parameter" "elasticache_ep" { - name = "/elasticache/app-4/${aws_elasticache_replication_group.app4.replication_group_id}/endpoint" + name = "/elasticache/${var.name}/${aws_elasticache_replication_group.app4.replication_group_id}/endpoint" type = "SecureString" key_id = aws_kms_key.encryption_rest.id value = aws_elasticache_replication_group.app4.configuration_endpoint_address } resource "aws_ssm_parameter" "elasticache_port" { - name = "/elasticache/app-4/${aws_elasticache_replication_group.app4.replication_group_id}/port" + name = "/elasticache/${var.name}/${aws_elasticache_replication_group.app4.replication_group_id}/port" type = "SecureString" key_id = aws_kms_key.encryption_rest.id value = aws_elasticache_replication_group.app4.port From edf01d6d6d5889bd5ecd917bf295427c88ae930a Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:48:49 -0600 Subject: [PATCH 03/20] updated reference --- cloudwatch.tf | 6 ++++-- data.tf | 4 ++-- ec2_role.tf | 4 ++-- elasticache.tf | 8 ++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cloudwatch.tf b/cloudwatch.tf index 1aec471..3807120 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -1,10 +1,12 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group resource "aws_cloudwatch_log_group" "slow_log" { - name = "/elasticache/${var.replication_group_id}/slow-log" + name = "/elasticache/${var.name}/slow-log" retention_in_days = 365 kms_key_id = aws_kms_key.encryption_rest.arn } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group resource "aws_cloudwatch_log_group" "engine_log" { - name = "/elasticache/${var.replication_group_id}/engine-log" + name = "/elasticache/${var.name}/engine-log" retention_in_days = 365 kms_key_id = aws_kms_key.encryption_rest.arn } \ No newline at end of file diff --git a/data.tf b/data.tf index 57db3ca..1949689 100644 --- a/data.tf +++ b/data.tf @@ -2,6 +2,6 @@ data "aws_caller_identity" "current" {} locals { principal_root_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" principal_logs_arn = "logs.${var.region}.amazonaws.com" - slow_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.replication_group_id}/slow-log" - engine_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.replication_group_id}/engine-log" + slow_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.name}/slow-log" + engine_log_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/elasticache/${var.name}/engine-log" } \ No newline at end of file diff --git a/ec2_role.tf b/ec2_role.tf index 86db034..88ccfa0 100644 --- a/ec2_role.tf +++ b/ec2_role.tf @@ -1,6 +1,6 @@ # #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role resource "aws_iam_role" "ec2_role" { - name = "app-4-ec2-role" + name = "${var.name}-ec2-role" # Terraform's "jsonencode" function converts a # Terraform expression result to valid JSON syntax. @@ -36,6 +36,6 @@ resource "aws_iam_role_policy_attachment" "secret_policy_attachement" { #Attach role to an instance profile #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile resource "aws_iam_instance_profile" "ec2_profile" { - name = "app-4-ec2-profile" + name = "${var.name}-ec2-profile" role = aws_iam_role.ec2_role.name } \ No newline at end of file diff --git a/elasticache.tf b/elasticache.tf index f3b2af5..dad1ce0 100644 --- a/elasticache.tf +++ b/elasticache.tf @@ -1,10 +1,10 @@ resource "aws_elasticache_subnet_group" "elasticache_subnet" { - name = "app-4-cache-subnet" + name = "${var.name}-cache-subnet" subnet_ids = [for subnet in aws_subnet.private : subnet.id] } resource "aws_secretsmanager_secret" "elasticache_auth" { - name = "app-4-elasticache-auth" + name = "${var.name}-elasticache-auth" recovery_window_in_days = 0 kms_key_id = aws_kms_key.encryption_secret.id #checkov:skip=CKV2_AWS_57: Disabled Secrets Manager secrets automatic rotation @@ -18,8 +18,8 @@ resource "aws_secretsmanager_secret_version" "auth" { resource "aws_elasticache_replication_group" "app4" { automatic_failover_enabled = true subnet_group_name = aws_elasticache_subnet_group.elasticache_subnet.name - replication_group_id = var.replication_group_id - description = "ElastiCache cluster for app4" + replication_group_id = var.name + description = "ElastiCache cluster for ${var.name}" node_type = "cache.t2.small" parameter_group_name = "default.redis7.cluster.on" port = 6379 From f0d04855f736efd362747f55c992571fef4cdec0 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:49:15 -0600 Subject: [PATCH 04/20] separated rules from sg --- ec2.tf | 50 +++++++++++++++++++++-------------------------- security_group.tf | 39 ++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/ec2.tf b/ec2.tf index ca2625e..a79fe33 100644 --- a/ec2.tf +++ b/ec2.tf @@ -1,34 +1,28 @@ -resource "aws_internet_gateway" "this-igw" { - vpc_id = aws_vpc.this.id - tags = { - "Name" = "app-4-gateway" - } -} -resource "aws_route" "internet-route" { - destination_cidr_block = "0.0.0.0/0" - route_table_id = aws_route_table.public.id - gateway_id = aws_internet_gateway.this-igw.id -} # create a security group resource "aws_security_group" "ec2_instance" { - name = "app-4-ec2" + name = "${var.name}-ec2" description = "Allow inbound to and outbound access from the Amazon EC2 instance." - ingress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = [var.vpc_cidr] - description = "Enable access from any resource inside the VPC." - } - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - description = "Enable access to the internet." - } vpc_id = aws_vpc.this.id } +resource "aws_security_group_rule" "ec2_instance_ingress" { + type = "ingress" + security_group_id = aws_security_group.ec2_instance.id + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [var.vpc_cidr] + description = "Enable access from any resource inside the VPC." +} + +resource "aws_security_group_rule" "ec2_instance_egress" { + type = "egress" + security_group_id = aws_security_group.ec2_instance.id + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "Enable access to the internet." +} #create an EC2 in a public subnet data "aws_ami" "amazon_ami" { @@ -61,7 +55,7 @@ resource "aws_instance" "app-server-read" { http_tokens = "required" } tags = { - Name = "app-4-server-read" + Name = "${var.name}-server-read" } user_data = templatefile("user_data/read_elasticache.tpl", { @@ -89,7 +83,7 @@ resource "aws_instance" "app-server-write" { http_tokens = "required" } tags = { - Name = "app-4-server-write" + Name = "${var.name}-server-write" } user_data = templatefile("user_data/write_elasticache.tpl", { diff --git a/security_group.tf b/security_group.tf index 375202a..258b03e 100644 --- a/security_group.tf +++ b/security_group.tf @@ -2,21 +2,26 @@ resource "aws_default_security_group" "default" { vpc_id = aws_vpc.this.id } resource "aws_security_group" "elasticache" { - name = "app-4-elasticache-sg" + name = "${var.name}-elasticache-sg" description = "Allow inbound to and outbound access from the Amazon ElastiCache cluster." - ingress { - from_port = 6379 - to_port = 6379 - protocol = "tcp" - cidr_blocks = [var.vpc_cidr] - description = "Enable communication to the Amazon ElastiCache for Redis cluster. " - } - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - description = "Enable access to the ElastiCache cluster." - } - vpc_id = aws_vpc.this.id -} \ No newline at end of file + vpc_id = aws_vpc.this.id +} +resource "aws_security_group_rule" "elasticache_ingress" { + type = "ingress" + security_group_id = aws_security_group.elasticache.id + from_port = 6379 + to_port = 6379 + protocol = "tcp" + cidr_blocks = [var.vpc_cidr] + description = "Enable communication to the Amazon ElastiCache for Redis cluster." +} + +resource "aws_security_group_rule" "elasticache_egress" { + type = "egress" + security_group_id = aws_security_group.elasticache.id + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "Enable access to the ElastiCache cluster." +} From e7e912163dfc509d36127d554c787f50b54289ee Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:49:26 -0600 Subject: [PATCH 05/20] updated reference --- iam_role.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iam_role.tf b/iam_role.tf index 5f438f6..0f498c5 100644 --- a/iam_role.tf +++ b/iam_role.tf @@ -1,7 +1,7 @@ #Create a policy to read from the specific parameter store #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy resource "aws_iam_policy" "ssm_parameter_policy" { - name = "app-4-ssm-parameter-read-policy" + name = "${var.name}-ssm-parameter-read-policy" path = "/" description = "Policy to read the ElastiCache endpoint and port number stored in the SSM Parameter Store." # Terraform's "jsonencode" function converts a @@ -29,7 +29,7 @@ resource "aws_iam_policy" "ssm_parameter_policy" { } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy resource "aws_iam_policy" "secret_manager_policy" { - name = "app-4-secret-read-policy" + name = "${var.name}-secret-read-policy" path = "/" description = "Policy to read the ElastiCache AUTH Token stored in AWS Secrets Manager secret." # Terraform's "jsonencode" function converts a From 897d9234cebf38d33f2ad765e7b7842b73d39cee Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:54:17 -0600 Subject: [PATCH 06/20] added policy to kms key --- kms.tf | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/kms.tf b/kms.tf index d8e1599..4177323 100644 --- a/kms.tf +++ b/kms.tf @@ -3,10 +3,63 @@ resource "aws_kms_key" "encryption_secret" { enable_key_rotation = true description = "Key to encrypt secret" deletion_window_in_days = 7 - #checkov:skip=CKV2_AWS_64: Not including a KMS Key policy + + # Attach the KMS key policy + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "AllowSecretsManagerUse" + Effect = "Allow" + Action = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ] + Resource = "*" + Principal = { + Service = "secretsmanager.amazonaws.com" + } + }, + { + Sid = "AllowAdminAccessToKMSKey" + Effect = "Allow" + Action = "kms:*" + Resource = "*" + Principal = { + AWS = "*" + } + }, + { + Sid = "AllowIAMRolesToUseKey" + Effect = "Allow" + Action = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ] + Resource = "*" + Principal = { + AWS = "*" + } + Condition = { + StringEquals = { + "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" + } + } + } + ] + }) + + tags = { + Name = "${var.name}-encryption-secret" + } } + resource "aws_kms_alias" "encryption_secret" { - name = "alias/elasticache-app-4-in-transit" + name = "alias/${var.name}-elasticache-in-transit" target_key_id = aws_kms_key.encryption_secret.key_id } resource "aws_kms_key" "encryption_rest" { @@ -14,15 +67,18 @@ resource "aws_kms_key" "encryption_rest" { description = "Key to encrypt cache at rest." deletion_window_in_days = 7 #checkov:skip=CKV2_AWS_64: KMS Key policy in a separate resource + tags = { + Name = "${var.name}-encryption-rest" + } } resource "aws_kms_alias" "encryption_rest" { - name = "alias/elasticache-app-4-at-rest" + name = "alias/${var.name}-elasticache-at-rest" target_key_id = aws_kms_key.encryption_rest.key_id } resource "aws_kms_key_policy" "encryption_rest_policy" { key_id = aws_kms_key.encryption_rest.id policy = jsonencode({ - Id = "encryption-rest" + Id = "${var.name}-encryption-rest" Statement = [ { Action = "kms:*" From 05e6038ed5d029c4584c0458ca9336bd25461b98 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:54:53 -0600 Subject: [PATCH 07/20] format --- ec2.tf | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ec2.tf b/ec2.tf index a79fe33..c4fac3d 100644 --- a/ec2.tf +++ b/ec2.tf @@ -2,26 +2,26 @@ resource "aws_security_group" "ec2_instance" { name = "${var.name}-ec2" description = "Allow inbound to and outbound access from the Amazon EC2 instance." - vpc_id = aws_vpc.this.id + vpc_id = aws_vpc.this.id } resource "aws_security_group_rule" "ec2_instance_ingress" { - type = "ingress" - security_group_id = aws_security_group.ec2_instance.id - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = [var.vpc_cidr] - description = "Enable access from any resource inside the VPC." + type = "ingress" + security_group_id = aws_security_group.ec2_instance.id + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = [var.vpc_cidr] + description = "Enable access from any resource inside the VPC." } resource "aws_security_group_rule" "ec2_instance_egress" { - type = "egress" - security_group_id = aws_security_group.ec2_instance.id - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - description = "Enable access to the internet." + type = "egress" + security_group_id = aws_security_group.ec2_instance.id + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "Enable access to the internet." } #create an EC2 in a public subnet From 043a3067705239349d39c7c824bd1b7e654b4493 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Fri, 15 Nov 2024 22:55:07 -0600 Subject: [PATCH 08/20] update reference to module --- network.tf | 122 +++++++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/network.tf b/network.tf index 4d6f623..37bf92f 100644 --- a/network.tf +++ b/network.tf @@ -1,56 +1,68 @@ -# https://docs.aws.amazon.com/glue/latest/dg/set-up-vpc-dns.html -resource "aws_vpc" "this" { - cidr_block = var.vpc_cidr - # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support - enable_dns_support = true - # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_hostnames - enable_dns_hostnames = true - #checkov:skip=CKV2_AWS_11: Not creating a flow log for this VPC - tags = { - "Name" = "app-4" - } -} -data "aws_availability_zones" "available" { - state = "available" -} -resource "aws_subnet" "private" { - count = length(var.subnet_cidr_private) - vpc_id = aws_vpc.this.id - cidr_block = var.subnet_cidr_private[count.index] - availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] - tags = { - "Name" = "app-4-private-${count.index + 1}" - } -} -resource "aws_subnet" "public" { - count = length(var.subnet_cidr_public) - vpc_id = aws_vpc.this.id - cidr_block = var.subnet_cidr_public[count.index] - availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] - tags = { - "Name" = "app-4-public-${count.index + 1}" - } -} -resource "aws_route_table" "private" { - count = length(var.subnet_cidr_private) - vpc_id = aws_vpc.this.id - tags = { - "Name" = "app-4-private-route-table-${count.index + 1}" - } -} -resource "aws_route_table" "public" { - vpc_id = aws_vpc.this.id - tags = { - "Name" = "app-4-public" - } -} -resource "aws_route_table_association" "private" { - count = length(var.subnet_cidr_private) - subnet_id = element(aws_subnet.private.*.id, count.index) - route_table_id = aws_route_table.private[count.index].id -} -resource "aws_route_table_association" "public" { - count = length(var.subnet_cidr_public) - subnet_id = element(aws_subnet.public.*.id, count.index) - route_table_id = aws_route_table.public.id +# # https://docs.aws.amazon.com/glue/latest/dg/set-up-vpc-dns.html +# resource "aws_vpc" "this" { +# cidr_block = var.vpc_cidr +# # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support +# enable_dns_support = true +# # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_hostnames +# enable_dns_hostnames = true +# #checkov:skip=CKV2_AWS_11: Not creating a flow log for this VPC +# tags = { +# "Name" = "app-4" +# } +# } +# data "aws_availability_zones" "available" { +# state = "available" +# } +# resource "aws_subnet" "private" { +# count = length(var.subnet_cidr_private) +# vpc_id = aws_vpc.this.id +# cidr_block = var.subnet_cidr_private[count.index] +# availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] +# tags = { +# "Name" = "app-4-private-${count.index + 1}" +# } +# } +# resource "aws_subnet" "public" { +# count = length(var.subnet_cidr_public) +# vpc_id = aws_vpc.this.id +# cidr_block = var.subnet_cidr_public[count.index] +# availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] +# tags = { +# "Name" = "app-4-public-${count.index + 1}" +# } +# } +# resource "aws_route_table" "private" { +# count = length(var.subnet_cidr_private) +# vpc_id = aws_vpc.this.id +# tags = { +# "Name" = "app-4-private-route-table-${count.index + 1}" +# } +# } +# resource "aws_route_table" "public" { +# vpc_id = aws_vpc.this.id +# tags = { +# "Name" = "app-4-public" +# } +# } +# resource "aws_route_table_association" "private" { +# count = length(var.subnet_cidr_private) +# subnet_id = element(aws_subnet.private.*.id, count.index) +# route_table_id = aws_route_table.private[count.index].id +# } +# resource "aws_route_table_association" "public" { +# count = length(var.subnet_cidr_public) +# subnet_id = element(aws_subnet.public.*.id, count.index) +# route_table_id = aws_route_table.public.id +# } + +module "vpc" { + source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.0" + vpc_cidr = var.vpc_cidr + enable_dns_support = "true" + enable_dns_hostnames = "true" + vpc_name = "app-4" + subnet_cidr_private = var.subnet_cidr_private + subnet_cidr_public = var.subnet_cidr_public + enable_internet_gateway = "true" + enable_flow_log = "true" } \ No newline at end of file From cec79d9c4355fc5382171064ec02e366f093ad74 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 08:51:14 -0600 Subject: [PATCH 09/20] upgrade provider version --- provider.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider.tf b/provider.tf index bee5e8d..98a3b46 100644 --- a/provider.tf +++ b/provider.tf @@ -6,7 +6,7 @@ terraform { } random = { source = "hashicorp/random" - version = "3.5.1" + version = "3.6.3" } } } From ffe35c6cbcbe863770125f0fd2fcaba42bb5e534 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 21:04:06 -0600 Subject: [PATCH 10/20] updated terraform documentation links --- ec2_role.tf | 4 ++-- security_group.tf | 11 +++++------ ssm_parameter.tf | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ec2_role.tf b/ec2_role.tf index 88ccfa0..f03017f 100644 --- a/ec2_role.tf +++ b/ec2_role.tf @@ -1,7 +1,6 @@ # #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role resource "aws_iam_role" "ec2_role" { name = "${var.name}-ec2-role" - # Terraform's "jsonencode" function converts a # Terraform expression result to valid JSON syntax. assume_role_policy = jsonencode({ @@ -24,11 +23,12 @@ resource "aws_iam_role_policy_attachment" "custom" { role = aws_iam_role.ec2_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" } - +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment resource "aws_iam_role_policy_attachment" "ssm_policy_attachement" { role = aws_iam_role.ec2_role.name policy_arn = aws_iam_policy.ssm_parameter_policy.arn } +##https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment resource "aws_iam_role_policy_attachment" "secret_policy_attachement" { role = aws_iam_role.ec2_role.name policy_arn = aws_iam_policy.secret_manager_policy.arn diff --git a/security_group.tf b/security_group.tf index 258b03e..31d2142 100644 --- a/security_group.tf +++ b/security_group.tf @@ -1,11 +1,10 @@ -resource "aws_default_security_group" "default" { - vpc_id = aws_vpc.this.id -} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group resource "aws_security_group" "elasticache" { name = "${var.name}-elasticache-sg" description = "Allow inbound to and outbound access from the Amazon ElastiCache cluster." - vpc_id = aws_vpc.this.id + vpc_id = module.vpc.vpc.id } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule resource "aws_security_group_rule" "elasticache_ingress" { type = "ingress" security_group_id = aws_security_group.elasticache.id @@ -15,7 +14,7 @@ resource "aws_security_group_rule" "elasticache_ingress" { cidr_blocks = [var.vpc_cidr] description = "Enable communication to the Amazon ElastiCache for Redis cluster." } - +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule resource "aws_security_group_rule" "elasticache_egress" { type = "egress" security_group_id = aws_security_group.elasticache.id @@ -24,4 +23,4 @@ resource "aws_security_group_rule" "elasticache_egress" { protocol = "-1" cidr_blocks = ["0.0.0.0/0"] description = "Enable access to the ElastiCache cluster." -} +} \ No newline at end of file diff --git a/ssm_parameter.tf b/ssm_parameter.tf index 81ef073..d42af08 100644 --- a/ssm_parameter.tf +++ b/ssm_parameter.tf @@ -5,6 +5,7 @@ resource "aws_ssm_parameter" "elasticache_ep" { key_id = aws_kms_key.encryption_rest.id value = aws_elasticache_replication_group.app4.configuration_endpoint_address } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter resource "aws_ssm_parameter" "elasticache_port" { name = "/elasticache/${var.name}/${aws_elasticache_replication_group.app4.replication_group_id}/port" type = "SecureString" From e52acddae99de3934320eda9edb46fdb1984c77d Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 21:05:31 -0600 Subject: [PATCH 11/20] converted to use vpc module to address #41 --- ec2.tf | 15 ++++++++----- elasticache.tf | 12 ++++++----- network.tf | 58 +------------------------------------------------- 3 files changed, 18 insertions(+), 67 deletions(-) diff --git a/ec2.tf b/ec2.tf index c4fac3d..380feda 100644 --- a/ec2.tf +++ b/ec2.tf @@ -1,9 +1,11 @@ # create a security group +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group resource "aws_security_group" "ec2_instance" { name = "${var.name}-ec2" description = "Allow inbound to and outbound access from the Amazon EC2 instance." - vpc_id = aws_vpc.this.id + vpc_id = module.vpc.vpc.id } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule resource "aws_security_group_rule" "ec2_instance_ingress" { type = "ingress" security_group_id = aws_security_group.ec2_instance.id @@ -13,7 +15,7 @@ resource "aws_security_group_rule" "ec2_instance_ingress" { cidr_blocks = [var.vpc_cidr] description = "Enable access from any resource inside the VPC." } - +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule resource "aws_security_group_rule" "ec2_instance_egress" { type = "egress" security_group_id = aws_security_group.ec2_instance.id @@ -24,7 +26,7 @@ resource "aws_security_group_rule" "ec2_instance_egress" { description = "Enable access to the internet." } -#create an EC2 in a public subnet +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami data "aws_ami" "amazon_ami" { filter { name = "name" @@ -37,6 +39,8 @@ data "aws_ami" "amazon_ami" { most_recent = true owners = ["amazon"] } +#create an EC2 in a public subnet +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance resource "aws_instance" "app-server-read" { instance_type = var.instance_type ami = data.aws_ami.amazon_ami.id @@ -44,7 +48,7 @@ resource "aws_instance" "app-server-read" { iam_instance_profile = aws_iam_instance_profile.ec2_profile.name associate_public_ip_address = true #checkov:skip=CKV_AWS_88: Required for Session Manager access - subnet_id = aws_subnet.public[0].id + subnet_id = module.vpc.private_subnets[0].id ebs_optimized = true monitoring = true root_block_device { @@ -65,6 +69,7 @@ resource "aws_instance" "app-server-read" { elasticache_auth_token = aws_secretsmanager_secret.elasticache_auth.name }) } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance resource "aws_instance" "app-server-write" { instance_type = var.instance_type ami = data.aws_ami.amazon_ami.id @@ -72,7 +77,7 @@ resource "aws_instance" "app-server-write" { iam_instance_profile = aws_iam_instance_profile.ec2_profile.name associate_public_ip_address = true #checkov:skip=CKV_AWS_88: Required for Session Manager access - subnet_id = aws_subnet.public[0].id + subnet_id = module.vpc.private_subnets[0].id ebs_optimized = true monitoring = true root_block_device { diff --git a/elasticache.tf b/elasticache.tf index dad1ce0..d0cceba 100644 --- a/elasticache.tf +++ b/elasticache.tf @@ -1,14 +1,16 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group resource "aws_elasticache_subnet_group" "elasticache_subnet" { name = "${var.name}-cache-subnet" - subnet_ids = [for subnet in aws_subnet.private : subnet.id] + subnet_ids = [for subnet in module.vpc.private_subnets : subnet.id] } - +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret resource "aws_secretsmanager_secret" "elasticache_auth" { name = "${var.name}-elasticache-auth" recovery_window_in_days = 0 kms_key_id = aws_kms_key.encryption_secret.id #checkov:skip=CKV2_AWS_57: Disabled Secrets Manager secrets automatic rotation } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version resource "aws_secretsmanager_secret_version" "auth" { secret_id = aws_secretsmanager_secret.elasticache_auth.id secret_string = random_password.auth.result @@ -43,8 +45,8 @@ resource "aws_elasticache_replication_group" "app4" { log_format = "json" log_type = "engine-log" } - lifecycle { - ignore_changes = [kms_key_id] - } + # lifecycle { + # ignore_changes = [kms_key_id] + # } apply_immediately = true } \ No newline at end of file diff --git a/network.tf b/network.tf index 37bf92f..bc244a2 100644 --- a/network.tf +++ b/network.tf @@ -1,62 +1,6 @@ -# # https://docs.aws.amazon.com/glue/latest/dg/set-up-vpc-dns.html -# resource "aws_vpc" "this" { -# cidr_block = var.vpc_cidr -# # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support -# enable_dns_support = true -# # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_hostnames -# enable_dns_hostnames = true -# #checkov:skip=CKV2_AWS_11: Not creating a flow log for this VPC -# tags = { -# "Name" = "app-4" -# } -# } -# data "aws_availability_zones" "available" { -# state = "available" -# } -# resource "aws_subnet" "private" { -# count = length(var.subnet_cidr_private) -# vpc_id = aws_vpc.this.id -# cidr_block = var.subnet_cidr_private[count.index] -# availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] -# tags = { -# "Name" = "app-4-private-${count.index + 1}" -# } -# } -# resource "aws_subnet" "public" { -# count = length(var.subnet_cidr_public) -# vpc_id = aws_vpc.this.id -# cidr_block = var.subnet_cidr_public[count.index] -# availability_zone = data.aws_availability_zones.available.names[(count.index) % length(data.aws_availability_zones.available.names)] -# tags = { -# "Name" = "app-4-public-${count.index + 1}" -# } -# } -# resource "aws_route_table" "private" { -# count = length(var.subnet_cidr_private) -# vpc_id = aws_vpc.this.id -# tags = { -# "Name" = "app-4-private-route-table-${count.index + 1}" -# } -# } -# resource "aws_route_table" "public" { -# vpc_id = aws_vpc.this.id -# tags = { -# "Name" = "app-4-public" -# } -# } -# resource "aws_route_table_association" "private" { -# count = length(var.subnet_cidr_private) -# subnet_id = element(aws_subnet.private.*.id, count.index) -# route_table_id = aws_route_table.private[count.index].id -# } -# resource "aws_route_table_association" "public" { -# count = length(var.subnet_cidr_public) -# subnet_id = element(aws_subnet.public.*.id, count.index) -# route_table_id = aws_route_table.public.id -# } - module "vpc" { source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.0" + region = var.region vpc_cidr = var.vpc_cidr enable_dns_support = "true" enable_dns_hostnames = "true" From 35127bb82c0a631ba2033b9257429109ef8be917 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 21:06:21 -0600 Subject: [PATCH 12/20] tighened up kms key policy --- kms.tf | 109 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/kms.tf b/kms.tf index 4177323..e5bd8a7 100644 --- a/kms.tf +++ b/kms.tf @@ -1,38 +1,52 @@ - +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key resource "aws_kms_key" "encryption_secret" { enable_key_rotation = true description = "Key to encrypt secret" deletion_window_in_days = 7 - - # Attach the KMS key policy + tags = { + Name = "${var.name}-encryption-secret" + } +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias +resource "aws_kms_alias" "encryption_secret" { + name = "alias/${var.name}-elasticache-in-transit" + target_key_id = aws_kms_key.encryption_secret.key_id +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy +resource "aws_kms_key_policy" "encryption_secret_policy" { + key_id = aws_kms_key.encryption_secret.id policy = jsonencode({ - Version = "2012-10-17" + Id = "${var.name}-encryption-secret" Statement = [ { - Sid = "AllowSecretsManagerUse" - Effect = "Allow" Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion" ] - Resource = "*" + Effect = "Allow" Principal = { - Service = "secretsmanager.amazonaws.com" + AWS = "${local.principal_root_arn}" } - }, - { - Sid = "AllowAdminAccessToKMSKey" - Effect = "Allow" - Action = "kms:*" Resource = "*" - Principal = { - AWS = "*" + Sid = "Enable IAM User Permissions" + Condition = { + StringEquals = { + "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" + } } }, { - Sid = "AllowIAMRolesToUseKey" + Sid = "AllowSecretsManagerUse" Effect = "Allow" Action = [ "kms:Encrypt", @@ -42,26 +56,13 @@ resource "aws_kms_key" "encryption_secret" { ] Resource = "*" Principal = { - AWS = "*" - } - Condition = { - StringEquals = { - "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" - } + Service = "secretsmanager.amazonaws.com" } } ] }) - - tags = { - Name = "${var.name}-encryption-secret" - } -} - -resource "aws_kms_alias" "encryption_secret" { - name = "alias/${var.name}-elasticache-in-transit" - target_key_id = aws_kms_key.encryption_secret.key_id } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key resource "aws_kms_key" "encryption_rest" { enable_key_rotation = true description = "Key to encrypt cache at rest." @@ -71,23 +72,59 @@ resource "aws_kms_key" "encryption_rest" { Name = "${var.name}-encryption-rest" } } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias resource "aws_kms_alias" "encryption_rest" { name = "alias/${var.name}-elasticache-at-rest" target_key_id = aws_kms_key.encryption_rest.key_id } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy resource "aws_kms_key_policy" "encryption_rest_policy" { key_id = aws_kms_key.encryption_rest.id policy = jsonencode({ Id = "${var.name}-encryption-rest" Statement = [ { - Action = "kms:*" + Action = [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion" + ] Effect = "Allow" Principal = { AWS = "${local.principal_root_arn}" } Resource = "*" Sid = "Enable IAM User Permissions" + Condition = { + StringEquals = { + "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" + } + } + }, + { + Sid = "Allow ElastiCache to use the key" + Effect = "Allow" + Principal = { + Service = "elasticache.amazonaws.com" + } + Action = [ + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey", + "kms:ReEncrypt*", + "kms:CreateGrant", + "kms:DescribeKey" + ] + Resource = "*" }, { Effect : "Allow", From 5484fa779eab6525134b15ce0d5d5491982844f1 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 21:15:51 -0600 Subject: [PATCH 13/20] checkov scan fixes --- kms.tf | 1 - network.tf | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kms.tf b/kms.tf index e5bd8a7..617f704 100644 --- a/kms.tf +++ b/kms.tf @@ -67,7 +67,6 @@ resource "aws_kms_key" "encryption_rest" { enable_key_rotation = true description = "Key to encrypt cache at rest." deletion_window_in_days = 7 - #checkov:skip=CKV2_AWS_64: KMS Key policy in a separate resource tags = { Name = "${var.name}-encryption-rest" } diff --git a/network.tf b/network.tf index bc244a2..826f2ba 100644 --- a/network.tf +++ b/network.tf @@ -1,4 +1,6 @@ module "vpc" { + #CKV_TF_1: Ensure Terraform module sources use a commit hash + #checkov:skip=CKV_TF_1: This is a self hosted module where the version number is tagged rather than the commit hash. source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.0" region = var.region vpc_cidr = var.vpc_cidr From 4a240dcb33452ec64f31d6d9b9cd5715d1ec153d Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Sat, 16 Nov 2024 21:17:41 -0600 Subject: [PATCH 14/20] readability --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05e8985..b08d8e7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/)[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/pulls?q=is%3Apr+is%3Aclosed)[![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/pull/) -[![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/issues?q=is%3Aissue+is%3Aclosed)[![GitHub issues](https://img.shields.io/github/issues/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/issues/) -[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml)[![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml) +[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/) [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/pulls?q=is%3Apr+is%3Aclosed) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/pull/) +[![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/issues/) +[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml) [![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml) ![Image](https://skdevops.files.wordpress.com/2023/12/87-image-0-1.png) From a97b23e79b7780c0b32908afbcf79f419b799e9d Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Mon, 18 Nov 2024 18:42:11 -0600 Subject: [PATCH 15/20] added ignore changes to elasticache --- elasticache.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elasticache.tf b/elasticache.tf index d0cceba..b21cbae 100644 --- a/elasticache.tf +++ b/elasticache.tf @@ -45,8 +45,8 @@ resource "aws_elasticache_replication_group" "app4" { log_format = "json" log_type = "engine-log" } - # lifecycle { - # ignore_changes = [kms_key_id] - # } + lifecycle { + ignore_changes = [kms_key_id] + } apply_immediately = true } \ No newline at end of file From 5e4bffee7eac766a805e3d8d8c6b35d384cc1d40 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Mon, 18 Nov 2024 18:42:45 -0600 Subject: [PATCH 16/20] updated kms key and policy for #42 --- kms.tf | 66 ++++++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/kms.tf b/kms.tf index 617f704..af3c5c2 100644 --- a/kms.tf +++ b/kms.tf @@ -9,59 +9,51 @@ resource "aws_kms_key" "encryption_secret" { } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias resource "aws_kms_alias" "encryption_secret" { - name = "alias/${var.name}-elasticache-in-transit" + name = "alias/${var.name}-encryption-secret" target_key_id = aws_kms_key.encryption_secret.key_id } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy resource "aws_kms_key_policy" "encryption_secret_policy" { key_id = aws_kms_key.encryption_secret.id policy = jsonencode({ - Id = "${var.name}-encryption-secret" + Id = "${var.name}-encryption-secret" + Version = "2012-10-17" Statement = [ { - Action = [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ] + Sid = "Enable IAM User Permissions" Effect = "Allow" Principal = { - AWS = "${local.principal_root_arn}" + AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" } + Action = "kms:*" Resource = "*" - Sid = "Enable IAM User Permissions" - Condition = { - StringEquals = { - "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" - } - } }, { - Sid = "AllowSecretsManagerUse" + Sid = "Allow access through AWS Secrets Manager for all principals in the account that are authorized to use AWS Secrets Manager" Effect = "Allow" + Principal = { + AWS = ["*"] + } Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", + "kms:CreateGrant", + "kms:DescribeKey", "kms:GenerateDataKey*" ] Resource = "*" - Principal = { - Service = "secretsmanager.amazonaws.com" + Condition = { + StringEquals = { + "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" + "kms:ViaService" = "secretsmanager.${var.region}.amazonaws.com" + } } } ] }) } + #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key resource "aws_kms_key" "encryption_rest" { enable_key_rotation = true @@ -73,7 +65,7 @@ resource "aws_kms_key" "encryption_rest" { } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias resource "aws_kms_alias" "encryption_rest" { - name = "alias/${var.name}-elasticache-at-rest" + name = "alias/${var.name}-encryption-rest" target_key_id = aws_kms_key.encryption_rest.key_id } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy @@ -83,31 +75,13 @@ resource "aws_kms_key_policy" "encryption_rest_policy" { Id = "${var.name}-encryption-rest" Statement = [ { - Action = [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ] + Action = ["kms:*"] Effect = "Allow" Principal = { AWS = "${local.principal_root_arn}" } Resource = "*" Sid = "Enable IAM User Permissions" - Condition = { - StringEquals = { - "kms:CallerAccount" = "${data.aws_caller_identity.current.account_id}" - } - } }, { Sid = "Allow ElastiCache to use the key" From 92f81274a70b5490ac44c64c7232389a0a2d1ca7 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Mon, 18 Nov 2024 18:43:06 -0600 Subject: [PATCH 17/20] using module to address vpc flow log #41 --- network.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network.tf b/network.tf index 826f2ba..69d8cc9 100644 --- a/network.tf +++ b/network.tf @@ -1,7 +1,7 @@ module "vpc" { #CKV_TF_1: Ensure Terraform module sources use a commit hash #checkov:skip=CKV_TF_1: This is a self hosted module where the version number is tagged rather than the commit hash. - source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.0" + source = "github.com/kunduso/terraform-aws-vpc?ref=v1.0.1" region = var.region vpc_cidr = var.vpc_cidr enable_dns_support = "true" From c19994c40859837cf293b497dccfc50223b79881 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Mon, 18 Nov 2024 18:52:32 -0600 Subject: [PATCH 18/20] updated for terraform docs #43 --- .github/workflows/documentation.yml | 25 +++++++++++++++++++++++++ README.md | 6 +++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/documentation.yml diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..9067d15 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,25 @@ +#https://github.com/terraform-docs/gh-actions +name: generate-terraform-docs +on: + - pull_request +jobs: + docs: + runs-on: ubuntu-latest + permissions: + #checkov:skip=CKV2_GHA_1: This is required to add Terraform module details to the ReadMe.md + # Ensure top-level permissions are not set to write-all + contents: write + id-token: write + pull-requests: write + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: Render terraform docs inside the README.md and push changes back to PR branch + uses: terraform-docs/gh-actions@v1.3.0 + with: + working-dir: . + output-file: README.md + output-method: inject + git-push: "true" \ No newline at end of file diff --git a/README.md b/README.md index b08d8e7..514290c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/) [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/pulls?q=is%3Apr+is%3Aclosed) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/pull/) [![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/amazon-elasticache-redis-tf)](https://github.com/kunduso/amazon-elasticache-redis-tf/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues/kunduso/amazon-elasticache-redis-tf)](https://GitHub.com/kunduso/amazon-elasticache-redis-tf/issues/) -[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml) [![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml) +[![terraform-infra-provisioning](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/terraform.yml) [![checkov-static-analysis-scan](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml/badge.svg?branch=main)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/code-scan.yml) [![Generate terraform docs](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/documentation.yml/badge.svg)](https://github.com/kunduso/amazon-elasticache-redis-tf/actions/workflows/documentation.yml) ![Image](https://skdevops.files.wordpress.com/2023/12/87-image-0-1.png) @@ -28,10 +28,14 @@ For this code to function without errors, I created an **OpenID connect** identi
I stored the ARN of the IAM Role as a GitHub secret which is referred in the [`terraform.yml`](https://github.com/kunduso/amazon-elasticache-redis-tf/blob/eb148db2b9ff37cff9f1fb469d0c14b6479bd57a/.github/workflows/terraform.yml#L42) file.
Since I used Infracost in this repository, I stored the `INFRACOST_API_KEY` as a repository secret. It is referenced in the [`terraform.yml`](https://github.com/kunduso/amazon-elasticache-redis-tf/blob/eb148db2b9ff37cff9f1fb469d0c14b6479bd57a/.github/workflows/terraform.yml#L52) GitHub actions workflow file.
As part of the Infracost integration, I also created a `INFRACOST_API_KEY` and stored that as a GitHub Actions secret. I also managed the cost estimate process using a GitHub Actions variable `INFRACOST_SCAN_TYPE` where the value is either `hcl_code` or `tf_plan`, depending on the type of scan desired. + + ## Usage Ensure that the policy attached to the IAM role whose credentials are being used in this configuration has permission to create and manage all the resources that are included in this repository.
Review the code including the [`terraform.yml`](./.github/workflows/terraform.yml) to understand the steps in the GitHub Actions pipeline. Also review the terraform code to understand all the concepts associated with creating an AWS VPC, subnets, internet gateway, route table, and route table association.
If you want to check the pipeline logs, click on the **Build Badge** (terrform-infra-provisioning) above the image in this ReadMe. +## Contributing +If you find any issues or have suggestions for improvement, feel free to open an issue or submit a pull request. Contributions are always welcome! ## License This code is released under the Unlincse License. See [LICENSE](LICENSE). \ No newline at end of file From 444fe6d5fea9c433ec1f641109a2232168c2baf0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 19 Nov 2024 01:39:50 +0000 Subject: [PATCH 19/20] terraform-docs: automated action --- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/README.md b/README.md index 514290c..39b5d21 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,80 @@ For this code to function without errors, I created an **OpenID connect** identi
Since I used Infracost in this repository, I stored the `INFRACOST_API_KEY` as a repository secret. It is referenced in the [`terraform.yml`](https://github.com/kunduso/amazon-elasticache-redis-tf/blob/eb148db2b9ff37cff9f1fb469d0c14b6479bd57a/.github/workflows/terraform.yml#L52) GitHub actions workflow file.
As part of the Infracost integration, I also created a `INFRACOST_API_KEY` and stored that as a GitHub Actions secret. I also managed the cost estimate process using a GitHub Actions variable `INFRACOST_SCAN_TYPE` where the value is either `hcl_code` or `tf_plan`, depending on the type of scan desired. +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | 5.20.1 | +| [random](#requirement\_random) | 3.6.3 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.20.1 | +| [random](#provider\_random) | 3.6.3 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [vpc](#module\_vpc) | github.com/kunduso/terraform-aws-vpc | v1.0.1 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.engine_log](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/cloudwatch_log_group) | resource | +| [aws_cloudwatch_log_group.slow_log](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/cloudwatch_log_group) | resource | +| [aws_elasticache_replication_group.app4](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/elasticache_replication_group) | resource | +| [aws_elasticache_subnet_group.elasticache_subnet](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/elasticache_subnet_group) | resource | +| [aws_iam_instance_profile.ec2_profile](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_instance_profile) | resource | +| [aws_iam_policy.secret_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_policy) | resource | +| [aws_iam_policy.ssm_parameter_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_policy) | resource | +| [aws_iam_role.ec2_role](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.secret_policy_attachement](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.ssm_policy_attachement](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/iam_role_policy_attachment) | resource | +| [aws_instance.app-server-read](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/instance) | resource | +| [aws_instance.app-server-write](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/instance) | resource | +| [aws_kms_alias.encryption_rest](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_alias) | resource | +| [aws_kms_alias.encryption_secret](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_alias) | resource | +| [aws_kms_key.encryption_rest](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key) | resource | +| [aws_kms_key.encryption_secret](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key) | resource | +| [aws_kms_key_policy.encryption_rest_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key_policy) | resource | +| [aws_kms_key_policy.encryption_secret_policy](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/kms_key_policy) | resource | +| [aws_secretsmanager_secret.elasticache_auth](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/secretsmanager_secret) | resource | +| [aws_secretsmanager_secret_version.auth](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/secretsmanager_secret_version) | resource | +| [aws_security_group.ec2_instance](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group) | resource | +| [aws_security_group.elasticache](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group) | resource | +| [aws_security_group_rule.ec2_instance_egress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ec2_instance_ingress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.elasticache_egress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.elasticache_ingress](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/security_group_rule) | resource | +| [aws_ssm_parameter.elasticache_ep](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/ssm_parameter) | resource | +| [aws_ssm_parameter.elasticache_port](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/resources/ssm_parameter) | resource | +| [random_password.auth](https://registry.terraform.io/providers/hashicorp/random/3.6.3/docs/resources/password) | resource | +| [aws_ami.amazon_ami](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/data-sources/ami) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/5.20.1/docs/data-sources/caller_identity) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [access\_key](#input\_access\_key) | The access\_key that belongs to the IAM user. | `string` | `""` | no | +| [ami\_name](#input\_ami\_name) | The ami name of the image from where the instances will be created | `list(string)` |
[
"amzn2-ami-amd-hvm-2.0.20230727.0-x86_64-gp2"
]
| no | +| [instance\_type](#input\_instance\_type) | The instance type of the EC2 instances | `string` | `"t3.medium"` | no | +| [name](#input\_name) | The name of the application. | `string` | `"app-4"` | no | +| [region](#input\_region) | AWS Cloud infrastructure region. | `string` | `"us-east-2"` | no | +| [secret\_key](#input\_secret\_key) | The secret\_key that belongs to the IAM user. | `string` | `""` | no | +| [subnet\_cidr\_private](#input\_subnet\_cidr\_private) | CIDR blocks for the private subnets. | `list(any)` |
[
"10.20.32.0/27",
"10.20.32.32/27",
"10.20.32.64/27"
]
| no | +| [subnet\_cidr\_public](#input\_subnet\_cidr\_public) | CIDR blocks for the public subnets. | `list(any)` |
[
"10.20.32.96/27"
]
| no | +| [vpc\_cidr](#input\_vpc\_cidr) | CIDR for the VPC. | `string` | `"10.20.32.0/25"` | no | + +## Outputs + +No outputs. ## Usage Ensure that the policy attached to the IAM role whose credentials are being used in this configuration has permission to create and manage all the resources that are included in this repository. From 82dedf3ca530465dd8a462d73ea7f5f25027e60e Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Mon, 18 Nov 2024 19:41:21 -0600 Subject: [PATCH 20/20] suppressing checkov scan --- .github/workflows/code-scan.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/code-scan.yml b/.github/workflows/code-scan.yml index 5a97381..2e0ae35 100644 --- a/.github/workflows/code-scan.yml +++ b/.github/workflows/code-scan.yml @@ -34,6 +34,8 @@ jobs: # This will add both a CLI output to the console and create a results.sarif file output_format: cli,sarif output_file_path: console,results.sarif + #https://github.com/bridgecrewio/checkov/issues/6216 + skip_check: CKV2_GHA_1 - name: Upload SARIF file uses: github/codeql-action/upload-sarif@v2