diff --git a/main.tf b/main.tf index d926a5f..b21781d 100644 --- a/main.tf +++ b/main.tf @@ -1,36 +1,36 @@ locals { - azs = length(var.availability_zones) - public_subnets_native = var.public_subnet_enabled ? length(var.public_subnet_cidrs) > 0 ? var.public_subnet_cidrs : [for netnum in range(0, local.azs) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] - secondary_public_subnets = var.public_subnet_enabled && var.secondry_cidr_enabled ? [ + azs = length(var.vpc_availability_zones) + public_subnets_native = var.vpc_public_subnet_enabled ? length(var.vpc_public_subnet_cidrs) > 0 ? var.vpc_public_subnet_cidrs : [for netnum in range(0, local.azs) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] + secondary_public_subnets = var.vpc_public_subnet_enabled && var.secondry_cidr_enabled ? [ for cidr_block in var.secondary_cidr_blocks : [ for netnum in range(0, local.azs) : cidrsubnet(cidr_block, 8, netnum) ] ] : [] - public_subnets = concat(local.public_subnets_native, flatten(local.secondary_public_subnets)) - intra_subnets_native = var.intra_subnet_enabled ? length(var.intra_subnet_cidrs) > 0 ? var.intra_subnet_cidrs : [for netnum in range(local.azs * 3, local.azs * 4) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] - secondary_intra_subnets = var.intra_subnet_enabled && var.secondry_cidr_enabled ? [ + vpc_public_subnets = concat(local.public_subnets_native, flatten(local.secondary_public_subnets)) + intra_subnets_native = var.vpc_intra_subnet_enabled ? length(var.vpc_intra_subnet_cidrs) > 0 ? var.vpc_intra_subnet_cidrs : [for netnum in range(local.azs * 3, local.azs * 4) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] + secondary_intra_subnets = var.vpc_intra_subnet_enabled && var.secondry_cidr_enabled ? [ for cidr_block in var.secondary_cidr_blocks : [ for netnum in range(local.azs * 3, local.azs * 4) : cidrsubnet(cidr_block, 8, netnum) ] ] : [] - intra_subnets = concat(local.intra_subnets_native, flatten(local.secondary_intra_subnets)) - private_subnets_native = var.private_subnet_enabled ? length(var.private_subnet_cidrs) > 0 ? var.private_subnet_cidrs : [for netnum in range(local.azs, local.azs * 2) : cidrsubnet(var.vpc_cidr, 4, netnum)] : [] - secondary_private_subnets = var.private_subnet_enabled && var.secondry_cidr_enabled ? [ + vpc_intra_subnets = concat(local.intra_subnets_native, flatten(local.secondary_intra_subnets)) + private_subnets_native = var.vpc_private_subnet_enabled ? length(var.vpc_private_subnet_cidrs) > 0 ? var.vpc_private_subnet_cidrs : [for netnum in range(local.azs, local.azs * 2) : cidrsubnet(var.vpc_cidr, 4, netnum)] : [] + secondary_private_subnets = var.vpc_private_subnet_enabled && var.secondry_cidr_enabled ? [ for cidr_block in var.secondary_cidr_blocks : [ for netnum in range(local.azs, local.azs * 2) : cidrsubnet(cidr_block, 4, netnum) ] ] : [] - private_subnets = concat(local.private_subnets_native, flatten(local.secondary_private_subnets)) - database_subnets_native = var.database_subnet_enabled ? length(var.database_subnet_cidrs) > 0 ? var.database_subnet_cidrs : [for netnum in range(local.azs * 2, local.azs * 3) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] - secondary_database_subnets = var.database_subnet_enabled && var.secondry_cidr_enabled ? [ + vpc_private_subnets = concat(local.private_subnets_native, flatten(local.secondary_private_subnets)) + database_subnets_native = var.vpc_database_subnet_enabled ? length(var.vpc_database_subnet_cidrs) > 0 ? var.vpc_database_subnet_cidrs : [for netnum in range(local.azs * 2, local.azs * 3) : cidrsubnet(var.vpc_cidr, 8, netnum)] : [] + secondary_database_subnets = var.vpc_database_subnet_enabled && var.secondry_cidr_enabled ? [ for cidr_block in var.secondary_cidr_blocks : [ for netnum in range(local.azs * 2, local.azs * 3) : cidrsubnet(cidr_block, 8, netnum) ] ] : [] database_subnets = concat(local.database_subnets_native, flatten(local.secondary_database_subnets)) - single_nat_gateway = var.one_nat_gateway_per_az == true ? false : true - create_database_subnet_route_table = var.database_subnet_enabled - create_flow_log_cloudwatch_log_group = var.flow_log_enabled == true || var.flow_log_cloudwatch_log_group_skip_destroy == true ? true : false + vpc_single_nat_gateway = var.vpc_one_nat_gateway_per_az == true ? false : true + create_database_subnet_route_table = var.vpc_database_subnet_enabled + create_flow_log_cloudwatch_log_group = var.vpc_flow_log_enabled == true || var.vpc_flow_log_cloudwatch_log_group_skip_destroy == true ? true : false is_supported_arch = data.aws_ec2_instance_type.arch.supported_architectures[0] == "arm64" ? false : true # for VPN Instance nacl_allow_vpc_access_rule = [{ rule_no = 97 @@ -49,10 +49,10 @@ locals { database_subnet_assign_ipv6_address_on_creation = var.database_subnet_assign_ipv6_address_on_creation == true && var.ipv6_enabled == true ? true : false intra_subnet_assign_ipv6_address_on_creation = var.intra_subnet_assign_ipv6_address_on_creation == true && var.ipv6_enabled == true ? true : false - public_subnet_ipv6_prefixes = var.public_subnet_enabled ? [for i in range(local.azs) : i] : [] - private_subnet_ipv6_prefixes = var.private_subnet_enabled ? [for i in range(local.azs) : i + length(data.aws_availability_zones.available.names)] : [] - database_subnet_ipv6_prefixes = var.database_subnet_enabled ? [for i in range(local.azs) : i + 2 * length(data.aws_availability_zones.available.names)] : [] - intra_subnet_ipv6_prefixes = var.intra_subnet_enabled ? [for i in range(local.azs) : i + 3 * length(data.aws_availability_zones.available.names)] : [] + public_subnet_ipv6_prefixes = var.vpc_public_subnet_enabled ? [for i in range(local.azs) : i] : [] + private_subnet_ipv6_prefixes = var.vpc_private_subnet_enabled ? [for i in range(local.azs) : i + length(data.aws_availability_zones.available.names)] : [] + database_subnet_ipv6_prefixes = var.vpc_database_subnet_enabled ? [for i in range(local.azs) : i + 2 * length(data.aws_availability_zones.available.names)] : [] + intra_subnet_ipv6_prefixes = var.vpc_intra_subnet_enabled ? [for i in range(local.azs) : i + 3 * length(data.aws_availability_zones.available.names)] : [] } data "aws_availability_zones" "available" {} data "aws_ec2_instance_type" "arch" { @@ -66,36 +66,36 @@ module "vpc" { cidr = var.vpc_cidr # CIDR FOR VPC azs = [for n in range(0, local.azs) : data.aws_availability_zones.available.names[n]] use_ipam_pool = var.ipam_enabled ? true : false - ipv4_ipam_pool_id = var.ipam_enabled && var.create_ipam_pool ? aws_vpc_ipam_pool.ipam_pool[0].id : null + ipv4_ipam_pool_id = var.ipam_enabled && var.ipam_pool_enabled ? aws_vpc_ipam_pool.ipam_pool[0].id : null ipv4_netmask_length = var.ipam_enabled ? var.ipv4_netmask_length : null - create_database_subnet_group = length(local.database_subnets) > 1 && var.enable_database_subnet_group ? true : false - intra_subnets = local.intra_subnets - public_subnets = local.public_subnets - private_subnets = local.private_subnets + create_database_subnet_group = length(local.generate_subnets.vpc_database_subnets) > 1 && var.database_subnet_group_enabled ? true : false + intra_subnets = local.vpc_intra_subnets + public_subnets = local.vpc_public_subnets + private_subnets = local.vpc_private_subnets database_subnets = local.database_subnets - enable_flow_log = var.flow_log_enabled - enable_nat_gateway = length(local.private_subnets) > 0 && !var.ipv6_only ? true : false - single_nat_gateway = local.single_nat_gateway - enable_vpn_gateway = false - enable_dns_hostnames = true - flow_log_traffic_type = "ALL" + enable_flow_log = var.vpc_flow_log_enabled + enable_nat_gateway = length(local.generate_subnets.vpc_private_subnets) > 0 && !var.ipv6_only ? true : false + single_nat_gateway = local.vpc_single_nat_gateway + enable_vpn_gateway = var.vpn_gateway_enabled + enable_dns_hostnames = var.dns_hostnames_enabled + flow_log_traffic_type = var.vpc_flow_log_traffic_type secondary_cidr_blocks = var.secondry_cidr_enabled ? var.secondary_cidr_blocks : [] - one_nat_gateway_per_az = var.one_nat_gateway_per_az + one_nat_gateway_per_az = var.vpc_one_nat_gateway_per_az map_public_ip_on_launch = var.auto_assign_public_ip - flow_log_destination_type = "cloud-watch-logs" - manage_default_network_acl = true + flow_log_destination_type = var.vpc_flow_log_destination_type + manage_default_network_acl = var.vpc_manage_default_network_acl default_network_acl_ingress = concat(local.nacl_allow_vpc_access_rule, var.default_network_acl_ingress) - manage_default_security_group = true - default_security_group_ingress = [] # Enforcing no rules being present in the default security group. - default_security_group_egress = [] - create_database_nat_gateway_route = false + manage_default_security_group = var.manage_vpc_default_security_group + default_security_group_ingress = var.vpc_default_security_group_ingress # Enforcing no rules being present in the default security group. + default_security_group_egress = vpc_vpc_default_security_group_egress + create_database_nat_gateway_route = var.database_nat_gateway_route_enabled create_database_subnet_route_table = local.create_database_subnet_route_table - create_flow_log_cloudwatch_iam_role = var.flow_log_enabled + create_flow_log_cloudwatch_iam_role = var.vpc_flow_log_enabled create_flow_log_cloudwatch_log_group = local.create_flow_log_cloudwatch_log_group - flow_log_max_aggregation_interval = var.flow_log_max_aggregation_interval - flow_log_cloudwatch_log_group_skip_destroy = var.flow_log_cloudwatch_log_group_skip_destroy - flow_log_cloudwatch_log_group_retention_in_days = var.flow_log_cloudwatch_log_group_retention_in_days - flow_log_cloudwatch_log_group_kms_key_id = var.flow_log_cloudwatch_log_group_kms_key_arn + flow_log_max_aggregation_interval = var.vpc_flow_log_max_aggregation_interval + flow_log_cloudwatch_log_group_skip_destroy = var.vpc_flow_log_cloudwatch_log_group_skip_destroy + flow_log_cloudwatch_log_group_retention_in_days = var.vpc_flow_log_cloudwatch_log_group_retention_in_days + flow_log_cloudwatch_log_group_kms_key_id = var.vpc_flow_log_cloudwatch_log_group_kms_key_arn enable_ipv6 = local.enable_ipv6 public_subnet_ipv6_native = local.ipv6_only private_subnet_ipv6_native = local.ipv6_only @@ -182,36 +182,32 @@ module "vpn_server" { vpc_id = module.vpc.vpc_id vpc_cidr = var.vpc_cidr environment = var.environment - vpn_key_pair = var.vpn_key_pair_name + vpn_key_pair = var.vpn_server_key_pair_name public_subnet = module.vpc.public_subnets[0] vpn_server_instance_type = var.vpn_server_instance_type } resource "aws_vpc_ipam" "ipam" { - count = var.ipam_enabled && var.create_ipam_pool ? 1 : 0 + count = var.ipam_enabled && var.ipam_pool_enabled ? 1 : 0 operating_regions { - region_name = var.region + region_name = var.aws_region } - - } # IPv4 resource "aws_vpc_ipam_pool" "ipam_pool" { - count = var.ipam_enabled && var.create_ipam_pool ? 1 : 0 + count = var.ipam_enabled && var.ipam_pool_enabled ? 1 : 0 description = "IPv4 pool" - address_family = "ipv4" + address_family = var.ipam_address_family ipam_scope_id = aws_vpc_ipam.ipam[0].private_default_scope_id - locale = var.region + locale = var.aws_region allocation_default_netmask_length = 16 - - } resource "aws_vpc_ipam_pool_cidr" "ipam_pool_cidr" { count = var.ipam_enabled ? 1 : 0 - ipam_pool_id = var.create_ipam_pool ? aws_vpc_ipam_pool.ipam_pool[0].id : var.ipam_pool_id - cidr = var.create_ipam_pool ? var.vpc_cidr : var.existing_ipam_managed_cidr + ipam_pool_id = var.ipam_pool_enabled ? aws_vpc_ipam_pool.ipam_pool[0].id : var.ipam_pool_id + cidr = var.ipam_pool_enabled ? var.vpc_cidr : var.existing_ipam_managed_cidr } # private links for S3 @@ -225,13 +221,13 @@ data "aws_route_tables" "aws_private_routes" { } } -resource "aws_vpc_endpoint" "private-s3" { +resource "aws_vpc_endpoint" "private_s3" { count = var.vpc_s3_endpoint_enabled ? 1 : 0 depends_on = [data.aws_route_tables.aws_private_routes] vpc_id = module.vpc.vpc_id - service_name = "com.amazonaws.${var.region}.s3" + service_name = "com.amazonaws.${var.aws_region}.s3" route_table_ids = data.aws_route_tables.aws_private_routes[0].ids - vpc_endpoint_type = "Gateway" + vpc_endpoint_type = var.vpc_endpoint_type_private-s3 policy = < 0 ? module.vpc.public_subnets : null -} - -output "private_subnets" { - description = "List of IDs of private subnets" - value = length(module.vpc.private_subnets) > 0 ? module.vpc.private_subnets : null -} - -output "database_subnets" { - description = "List of IDs of database subnets" - value = length(module.vpc.database_subnets) > 0 ? module.vpc.database_subnets : null -} - -output "intra_subnets" { - description = "List of IDs of Intra subnets" - value = length(module.vpc.intra_subnets) > 0 ? module.vpc.intra_subnets : null - -} - -output "vpn_host_public_ip" { - description = "IP Address of VPN Server" - value = var.vpn_server_enabled ? module.vpn_server[0].vpn_host_public_ip : null -} - -output "vpn_security_group" { - description = "Security Group ID of VPN Server" - value = var.vpn_server_enabled ? module.vpn_server[0].vpn_security_group : null -} - -output "vpc_ipv6_association_id" { - description = "The association ID for the IPv6 CIDR block" - value = module.vpc.vpc_ipv6_association_id -} - -output "ipv6_vpc_cidr_block" { - description = "The IPv6 CIDR block" - value = module.vpc.vpc_ipv6_cidr_block -} - -output "vpc_secondary_cidr_blocks" { - description = "List of secondary CIDR blocks of the VPC" - value = module.vpc.vpc_secondary_cidr_blocks -} +# output "aws_region" { +# description = "AWS Region in which VPC is created" +# value = local.aws_region +# } + +output "vpc_id" { + description = "The ID of the VPC" + value = module.vpc.vpc_id +} + +output "vpc_cidr_block" { + description = "AWS Region" + value = module.vpc.vpc_cidr_block +} + +output "vpc_public_subnets" { + description = "List of IDs of public subnets" + value = module.vpc.vpc_public_subnets +} + +output "vpc_private_subnets" { + description = "List of IDs of private subnets" + value = module.vpc.vpc_private_subnets +} + +output "database_subnets" { + description = "List of IDs of database subnets" + value = module.vpc.database_subnets +} + +output "vpc_intra_subnets" { + description = "List of IDs of Intra subnets" + value = module.vpc.vpc_intra_subnets +} + +output "vpn_host_public_ip" { + description = "IP Adress of VPN Server" + value = module.vpc.vpn_host_public_ip +} + +output "vpn_security_group" { + description = "Security Group ID of VPN Server" + value = module.vpc.vpn_security_group +} diff --git a/providers.tf b/providers.tf new file mode 100644 index 0000000..7a8138f --- /dev/null +++ b/providers.tf @@ -0,0 +1,6 @@ +provider "aws" { + region = local.aws_region + default_tags { + tags = local.additional_aws_tags + } +} diff --git a/variables.tf b/variables.tf index ca9a7a5..de0c894 100644 --- a/variables.tf +++ b/variables.tf @@ -1,3 +1,25 @@ +variable "additional_tags" { + description = "Additional tags to be applied to AWS resources" + type = map(string) + default = { + Owner = "organization_name" + Expires = "Never" + Department = "Engineering" + } +} + +variable "aws_region" { + description = "Name of the AWS region where VPC is to be created." + default = "" + type = string +} + +variable "aws_account_id" { + description = "Account ID of the AWS Account." + default = "1234567890" + type = string +} + variable "environment" { description = "Specify the environment indentifier for the VPC" type = string @@ -17,55 +39,55 @@ variable "vpc_cidr" { type = string } -variable "availability_zones" { - description = "Number of Availability Zone to be used by VPC Subnets" +variable "vpc_availability_zones" { + description = "Number of Availability Zone to be used by VPC Subnets." default = [] type = list(any) } -variable "public_subnet_enabled" { +variable "vpc_public_subnet_enabled" { description = "Set true to enable public subnets" default = false type = bool } -variable "public_subnet_cidrs" { +variable "vpc_public_subnet_cidrs" { description = "A list of public subnets CIDR to be created inside the VPC" default = [] type = list(any) } -variable "private_subnet_enabled" { +variable "vpc_private_subnet_enabled" { description = "Set true to enable private subnets" default = false type = bool } -variable "private_subnet_cidrs" { +variable "vpc_private_subnet_cidrs" { description = "A list of private subnets CIDR to be created inside the VPC" default = [] type = list(any) } -variable "database_subnet_enabled" { +variable "vpc_database_subnet_enabled" { description = "Set true to enable database subnets" default = false type = bool } -variable "database_subnet_cidrs" { +variable "vpc_database_subnet_cidrs" { description = "Database Tier subnet CIDRs to be created" default = [] type = list(any) } -variable "intra_subnet_enabled" { +variable "vpc_intra_subnet_enabled" { description = "Set true to enable intra subnets" default = false type = bool } -variable "intra_subnet_cidrs" { +variable "vpc_intra_subnet_cidrs" { description = "A list of intra subnets CIDR to be created" default = [] type = list(any) @@ -83,7 +105,7 @@ variable "vpn_server_instance_type" { type = string } -variable "vpn_key_pair_name" { +variable "vpn_server_key_pair_name" { description = "Specify the name of AWS Keypair to be used for VPN Server" default = "" type = string @@ -129,25 +151,25 @@ variable "default_network_acl_ingress" { ] } -variable "one_nat_gateway_per_az" { +variable "vpc_one_nat_gateway_per_az" { description = "Set to true if a NAT Gateway is required per availability zone for Private Subnet Tier" default = false type = bool } -variable "flow_log_enabled" { +variable "vpc_flow_log_enabled" { description = "Whether or not to enable VPC Flow Logs" type = bool default = false } -variable "flow_log_cloudwatch_log_group_retention_in_days" { +variable "vpc_flow_log_cloudwatch_log_group_retention_in_days" { description = "Specifies the number of days you want to retain log events in the specified log group for VPC flow logs." type = number default = null } -variable "flow_log_max_aggregation_interval" { +variable "vpc_flow_log_max_aggregation_interval" { description = "The maximum interval of time during which a flow of packets is captured and aggregated into a flow log record. Valid Values: `60` seconds or `600` seconds." type = number default = 60 @@ -192,7 +214,7 @@ variable "intra_subnet_assign_ipv6_address_on_creation" { default = null } -variable "flow_log_cloudwatch_log_group_kms_key_arn" { +variable "vpc_flow_log_cloudwatch_log_group_kms_key_arn" { description = "The ARN of the KMS Key to use when encrypting log data for VPC flow logs" type = string default = null @@ -216,18 +238,12 @@ variable "secondry_cidr_enabled" { type = bool } -variable "enable_database_subnet_group" { +variable "database_subnet_group_enabled" { description = "Whether create database subnet groups" default = false type = bool } -# variable "tags" { -# description = "The Tags attached with the resources" -# default = {} -# type = any -# } - variable "ipam_pool_id" { description = "The existing IPAM pool id if any" default = null @@ -240,7 +256,7 @@ variable "ipam_enabled" { type = bool } -variable "create_ipam_pool" { +variable "ipam_pool_enabled" { description = "Whether create new IPAM pool" default = true type = bool @@ -252,19 +268,13 @@ variable "ipv4_netmask_length" { type = number } -variable "region" { - description = "The AWS region name" - type = string - default = null -} - variable "existing_ipam_managed_cidr" { description = "The existing IPAM pool CIDR" default = "" type = string } -variable "flow_log_cloudwatch_log_group_skip_destroy" { +variable "vpc_flow_log_cloudwatch_log_group_skip_destroy" { description = " Set to true if you do not wish the log group (and any logs it may contain) to be deleted at destroy time, and instead just remove the log group from the Terraform state" type = bool default = false @@ -281,3 +291,93 @@ variable "vpc_ecr_endpoint_enabled" { type = bool default = false } + +variable "vpn_gateway_enabled" { + description = "Whether to enable vpn Gateway" + type = bool + default = false +} + +variable "dns_hostnames_enabled" { + description = "Whether to enable DNS hostnames" + type = bool + default = true +} + +variable "vpc_manage_default_network_acl" { + description = "Should be true to manage Default Network ACL" + type = bool + default = true +} + +variable "vpc_flow_log_traffic_type" { + description = "The type of traffic to capture. Valid values: ACCEPT, REJECT, ALL" + type = string + default = "ALL" +} + +variable "vpc_flow_log_destination_type" { + description = "Type of flow log destination. Can be s3 or cloud-watch-logs" + type = string + default = "cloud-watch-logs" +} + +variable "manage_vpc_default_security_group" { + description = "Should be true to manage Default Security group of vpc" + type = bool + default = true +} + +variable "database_nat_gateway_route_enabled" { + description = "Nat Gateway route to be created for internet access to database subnets" + type = bool + default = false +} + +variable "vpc_default_security_group_ingress" { + description = "List of ingress rules for the default security group" + type = list(object({ + from_port = number + to_port = number + protocol = string + cidr_blocks = list(string) + description = string + })) + default = [] +} + +variable "vpc_default_security_group_egress" { + description = "List of egress rules for the default security group" + type = list(object({ + from_port = number + to_port = number + protocol = string + cidr_blocks = list(string) + description = string + })) + default = [] +} + +variable "vpc_endpoint_type_ecr_api" { + description = "The type of VPC endpoint for ECR api" + type = string + default = "Interface" +} + +variable "vpc_endpoint_type_ecr_dkr" { + description = "The type of VPC endpoint for ECR Docker" + type = string + default = "Interface" +} + +variable "vpc_endpoint_type_private_s3" { + description = "The type of VPC endpoint for ECR Docker" + type = string + default = "Interface" +} + +variable "ipam_address_family" { + description = "The address family for the VPC (ipv4 or ipv6)" + type = string + default = "ipv4" +} diff --git a/versions.tf b/versions.tf index dffc488..d8e2113 100644 --- a/versions.tf +++ b/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.23" + version = ">= 5.0.0" } } }