From adc108740af04e6844845f5a3eb07cba82aeab71 Mon Sep 17 00:00:00 2001 From: ravimahey Date: Mon, 24 Jun 2024 00:48:29 +0530 Subject: [PATCH 1/4] Updated the terraform module for fargate --- .gitignore | 4 + main.tf | 128 ++++++++----- modules/eks/iam_policy.json | 242 ++++++++++++++++++++++++ modules/eks/main.tf | 141 ++++++++++++++ modules/eks/nodes/main.tf | 124 ++++++++++++ modules/eks/nodes/outputs.tf | 0 modules/eks/nodes/variables.tf | 67 +++++++ modules/eks/output.tf | 16 ++ modules/eks/variables.tf | 63 ++++++ modules/rds/main.tf | 75 ++++++++ modules/rds/outputs.tf | 24 +++ modules/rds/variables.tf | 85 +++++++++ modules/vpc/gateway/main.tf | 46 +++++ modules/vpc/gateway/outputs.tf | 24 +++ modules/vpc/gateway/variables.tf | 43 +++++ modules/vpc/main.tf | 104 ++++++++++ modules/vpc/output.tf | 38 ++++ modules/vpc/route_table/main.tf | 43 +++++ modules/vpc/route_table/outputs.tf | 10 + modules/vpc/route_table/variables.tf | 47 +++++ modules/vpc/security_group/main.tf | 0 modules/vpc/security_group/outputs.tf | 0 modules/vpc/security_group/variables.tf | 0 modules/vpc/subnet/main.tf | 33 ++++ modules/vpc/subnet/outputs.tf | 10 + modules/vpc/subnet/variables.tf | 45 +++++ modules/vpc/variables.tf | 24 +++ output.tf | 40 +++- terraform.tfvars | 62 ++++++ variables.tf | 81 ++++++-- 30 files changed, 1541 insertions(+), 78 deletions(-) create mode 100644 modules/eks/iam_policy.json create mode 100644 modules/eks/main.tf create mode 100644 modules/eks/nodes/main.tf create mode 100644 modules/eks/nodes/outputs.tf create mode 100644 modules/eks/nodes/variables.tf create mode 100644 modules/eks/output.tf create mode 100644 modules/eks/variables.tf create mode 100644 modules/rds/main.tf create mode 100644 modules/rds/outputs.tf create mode 100644 modules/rds/variables.tf create mode 100644 modules/vpc/gateway/main.tf create mode 100644 modules/vpc/gateway/outputs.tf create mode 100644 modules/vpc/gateway/variables.tf create mode 100644 modules/vpc/main.tf create mode 100644 modules/vpc/output.tf create mode 100644 modules/vpc/route_table/main.tf create mode 100644 modules/vpc/route_table/outputs.tf create mode 100644 modules/vpc/route_table/variables.tf create mode 100644 modules/vpc/security_group/main.tf create mode 100644 modules/vpc/security_group/outputs.tf create mode 100644 modules/vpc/security_group/variables.tf create mode 100644 modules/vpc/subnet/main.tf create mode 100644 modules/vpc/subnet/outputs.tf create mode 100644 modules/vpc/subnet/variables.tf create mode 100644 modules/vpc/variables.tf create mode 100644 terraform.tfvars diff --git a/.gitignore b/.gitignore index 072e772..cdff0cb 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ override.tf.json # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan # example: *tfplan* + +kubeconfig/* +provider.tf +backend.tf \ No newline at end of file diff --git a/main.tf b/main.tf index a2ede96..5ffa9a4 100644 --- a/main.tf +++ b/main.tf @@ -1,64 +1,88 @@ -provider "aws" { - region = "ap-south-1" -} -terraform { - required_version = ">= 0.12.0" -} +####################################################### +# Terraform Configuration +####################################################### -resource "aws_eks_cluster" "eks_cluster" { - name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}" - role_arn = aws_iam_role.eks_cluster_role.arn - version = var.kubernetes_version - - vpc_config { - subnet_ids = var.subnet_ids +# Specify the required providers and backend for Terraform state +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } } - kubernetes_network_config { - service_ipv4_cidr = var.eks_cluster_service_ipv4_cidr + backend "s3" { + # Backend configuration for S3 will be added here } +} - timeouts { - create = var.eks_cluster_create_timeout - delete = var.eks_cluster_delete_timeout - update = var.eks_cluster_update_timeout - } +# AWS provider configuration +provider "aws" { + region = var.region +} - depends_on = [ - aws_iam_role_policy_attachment.eks_cluster_policy, - aws_iam_role_policy_attachment.eks_vpc_resource_controller_policy, - aws_cloudwatch_log_group.eks_cluster_cloudwatch_log_group - ] +####################################################### +# VPC Module +####################################################### - tags = { - Name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}" - Environment = var.eks_cluster_environment - } +# Create the VPC and subnets using a module +module "vpc" { + source = "./modules/vpc" + cluster_prefix = var.cluster_prefix + cidr = var.cidr + subnet_bits = var.subnet_bits } -# data "tls_certificate" "eks_cluster_tls_certificate" { -# url = aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer -# } +####################################################### +# EKS Cluster Module +####################################################### -# resource "aws_iam_openid_connect_provider" "eks_cluster_openid_connect_provider" { -# client_id_list = ["sts.amazonaws.com"] -# thumbprint_list = [data.tls_certificate.eks_cluster_tls_certificate.certificates[0].sha1_fingerprint] -# url = aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer -# } +# Create the EKS cluster using a module +module "eks" { + source = "./modules/eks" + cluster_prefix = var.cluster_prefix + kubernetes_version = var.kubernetes_version + private_subnet_ids = module.vpc.private_subnet_ids + eks_cluster_enabled_log_types = var.eks_cluster_enabled_log_types +} -# data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { -# statement { -# actions = ["sts:AssumeRoleWithWebIdentity"] -# effect = "Allow" +####################################################### +# EKS Node Groups Module +####################################################### -# condition { -# test = "StringEquals" -# variable = "${replace(aws_iam_openid_connect_provider.eks_cluster_openid_connect_provider.url, "https://", "")}:sub" -# values = ["system:serviceaccount:kube-system:aws-node"] -# } +# Create EKS node groups using a module +module "nodes" { + depends_on = [module.eks] + for_each = var.nodes + source = "./modules/eks/nodes" + cluster_prefix = var.cluster_prefix + node_environment = each.key + subnet_ids = module.vpc.private_subnet_ids + cluster_name = module.eks.cluster_name + node_type = each.value.node_type + instance_type = try(each.value.instance_type, null) + desired_size = try(each.value.desired_size, null) + max_size = try(each.value.max_size, null) + min_size = try(each.value.min_size, null) + selector = each.value.node_type == "fargate" ? each.value.selector : null +} + +####################################################### +# RDS Database Module +####################################################### -# principals { -# identifiers = [aws_iam_openid_connect_provider.eks_cluster_openid_connect_provider.arn] -# type = "Federated" -# } -# } -# } \ No newline at end of file +# Create RDS instances using a module +module "database" { + for_each = var.databases + source = "./modules/rds" + cluster_prefix = var.cluster_prefix + db_environment = each.key + db_engine = each.value.db_engine + db_instance_class = each.value.db_instance_class + db_version = each.value.db_version + db_storage = each.value.db_storage + db_name = each.value.db_name + db_username = each.value.db_username + db_password = each.value.db_password + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.storage_subnet_ids +} diff --git a/modules/eks/iam_policy.json b/modules/eks/iam_policy.json new file mode 100644 index 0000000..76d96e4 --- /dev/null +++ b/modules/eks/iam_policy.json @@ -0,0 +1,242 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:CreateServiceLinkedRole" + ], + "Resource": "*", + "Condition": { + "StringEquals": { + "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInternetGateways", + "ec2:DescribeVpcs", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeTags", + "ec2:GetCoipPoolUsage", + "ec2:DescribeCoipPools", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTrustStores" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "cognito-idp:DescribeUserPoolClient", + "acm:ListCertificates", + "acm:DescribeCertificate", + "iam:ListServerCertificates", + "iam:GetServerCertificate", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "shield:GetSubscriptionState", + "shield:DescribeProtection", + "shield:CreateProtection", + "shield:DeleteProtection" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateSecurityGroup" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "StringEquals": { + "ec2:CreateAction": "CreateSecurityGroup" + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags", + "ec2:DeleteTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:DeleteSecurityGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*" + ], + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/*/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/*/*/*/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:DeleteTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*" + ], + "Condition": { + "StringEquals": { + "elasticloadbalancing:CreateAction": [ + "CreateTargetGroup", + "CreateLoadBalancer" + ] + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets" + ], + "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:SetWebAcl", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:ModifyRule" + ], + "Resource": "*" + } + ] +} diff --git a/modules/eks/main.tf b/modules/eks/main.tf new file mode 100644 index 0000000..6286dd6 --- /dev/null +++ b/modules/eks/main.tf @@ -0,0 +1,141 @@ +###################################################################################### +# EKS Cluster +###################################################################################### + +// AWS EKS Cluster resource definition +resource "aws_eks_cluster" "eks_cluster" { + name = "${var.cluster_prefix}-cluster" // Name of the EKS cluster + role_arn = aws_iam_role.eks_cluster_role.arn // IAM role ARN for the EKS cluster + version = var.kubernetes_version // Kubernetes version for the cluster + + // VPC configuration for the cluster + vpc_config { + subnet_ids = var.private_subnet_ids // Subnet IDs where EKS resources will be deployed + } + + // Kubernetes network configuration + kubernetes_network_config { + service_ipv4_cidr = var.eks_cluster_service_ipv4_cidr // CIDR block for Kubernetes service IPs + } + + // Timeouts configuration for create, delete, and update operations + timeouts { + create = var.eks_cluster_create_timeout + delete = var.eks_cluster_delete_timeout + update = var.eks_cluster_update_timeout + } + + // Dependencies on IAM resources and policies + depends_on = [ + aws_iam_role_policy_attachment.eks_cluster_policy, + aws_iam_role_policy_attachment.eks_vpc_resource_controller_policy, + aws_iam_role_policy_attachment.eks_cluster_elb_service_link_policy_attachment, + + aws_iam_role.eks_cluster_role, + aws_iam_policy.alb_policy, + aws_cloudwatch_log_group.eks_cluster_cloudwatch_log_group, + ] + + // Tags for the EKS cluster resource + tags = { + Name = "${var.cluster_prefix}-cluster" + Environment = "all-environment" + } +} + +################################################################################# +# Creating Role and Policies for the cluster +################################################################################# + +// IAM policy document for EKS cluster assume role policy +data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["eks.amazonaws.com"] + } + actions = [ + "sts:AssumeRole", + ] + } +} + +// IAM policy document for EKS cluster ELB service link role policy +data "aws_iam_policy_document" "eks_cluster_elb_service_link_role_policy" { + statement { + effect = "Allow" + actions = [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeInternetGateways", + "ec2:DescribeAddresses", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:*" + ] + resources = ["*"] + } +} + +// IAM role for EKS cluster +resource "aws_iam_role" "eks_cluster_role" { + name = "${var.cluster_prefix}-eks-cluster-role" + assume_role_policy = data.aws_iam_policy_document.eks_cluster_assume_role_policy.json +} + +// IAM policy for EKS cluster ELB service link +resource "aws_iam_policy" "eks_cluster_elb_service_link_policy" { + name = "${var.cluster_prefix}-eks-cluster-elb-service-link-policy" + policy = data.aws_iam_policy_document.eks_cluster_elb_service_link_role_policy.json +} + +// IAM policy for AWS Load Balancer Controller +resource "aws_iam_policy" "alb_policy" { + name = "AWSLoadBalancerControllerIAMPolicy" + policy = file("${path.module}/iam_policy.json") +} + +// Attachment of AWS Load Balancer Controller IAM policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "alb_policy" { + policy_arn = aws_iam_policy.alb_policy.arn + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of AmazonEKS policies to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_cluster_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" + role = aws_iam_role.eks_cluster_role.name +} + +resource "aws_iam_role_policy_attachment" "eks_service_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of AmazonEKSVPCResourceController policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of EKS cluster ELB service link policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_cluster_elb_service_link_policy_attachment" { + policy_arn = aws_iam_policy.eks_cluster_elb_service_link_policy.arn + role = aws_iam_role.eks_cluster_role.name +} + +################################################################################# +# Cloudwatch for the cluster +################################################################################# + +// CloudWatch log group for EKS cluster +resource "aws_cloudwatch_log_group" "eks_cluster_cloudwatch_log_group" { + count = length(var.eks_cluster_enabled_log_types) > 0 ? 1 : 0 + name = "/aws/eks/${var.cluster_prefix}-cluster" + retention_in_days = var.eks_cluster_log_retention_in_days + + // Tags for the CloudWatch log group + tags = { + Name = "${var.cluster_prefix}-cloudwatch" + Environment = "all-environments" + } +} diff --git a/modules/eks/nodes/main.tf b/modules/eks/nodes/main.tf new file mode 100644 index 0000000..f86bc27 --- /dev/null +++ b/modules/eks/nodes/main.tf @@ -0,0 +1,124 @@ +################################################################################# +# VM Node Group +################################################################################# + +// AWS EKS Node Group resource +resource "aws_eks_node_group" "node_group" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + cluster_name = var.cluster_name // Name of the EKS cluster + node_group_name = "${var.cluster_prefix}-${var.node_environment}-node-group" // Name of the node group + node_role_arn = aws_iam_role.vm_node_group[0].arn // IAM role ARN for the node group + subnet_ids = var.subnet_ids // Subnet IDs for the node group instances + instance_types = var.instance_type // Instance types for the node group + disk_size = var.disk_size // Disk size for the node group instances + + // Scaling configuration for the node group + scaling_config { + desired_size = var.desired_size // Desired number of instances + max_size = var.max_size // Maximum number of instances + min_size = var.min_size // Minimum number of instances + } + + // Lifecycle configuration to ignore changes in desired_size + lifecycle { + ignore_changes = [scaling_config[0].desired_size] + } + + // Update configuration for the node group + update_config { + max_unavailable = 1 // Maximum number of unavailable instances during updates + } + + // Dependencies on IAM role policies before creating the node group + depends_on = [ + aws_iam_role.vm_node_group, + aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy[0], + aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy[0], + aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly[0], + ] +} + +// IAM role for VM Node Group +resource "aws_iam_role" "vm_node_group" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + name = "${var.cluster_prefix}-${var.node_environment}-vm-role" // Name of the IAM role + + // Assume role policy allowing EC2 instances to assume this role + assume_role_policy = jsonencode({ + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "ec2.amazonaws.com" + } + }] + Version = "2012-10-17" + }) +} + +// IAM role policy attachment for AmazonEKSWorkerNodePolicy +resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +// IAM role policy attachment for AmazonEKS_CNI_Policy +resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +// IAM role policy attachment for AmazonEC2ContainerRegistryReadOnly +resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +################################################################################# +# Fargate Profile +################################################################################# + +// AWS EKS Fargate Profile resource +resource "aws_eks_fargate_profile" "fargate" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + cluster_name = var.cluster_name // Name of the EKS cluster + fargate_profile_name = "${var.cluster_prefix}-${var.node_environment}-fargate-profile" // Name of the Fargate profile + pod_execution_role_arn = aws_iam_role.fargate_iam[0].arn // IAM role ARN for Fargate pods + subnet_ids = var.subnet_ids // Subnet IDs for Fargate + + // Dynamic selector for Fargate profile + dynamic "selector" { + for_each = var.selector != null && length(var.selector) > 0 ? toset(var.selector) : [] // Selectors for namespaces + content { + namespace = selector.value // Namespace selector + } + } +} + +// IAM role for Fargate pods +resource "aws_iam_role" "fargate_iam" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + name = "${var.cluster_prefix}-${var.node_environment}-fargate-role" // Name of the IAM role + + // Assume role policy allowing EKS Fargate pods to assume this role + assume_role_policy = jsonencode({ + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "eks-fargate-pods.amazonaws.com" + } + }] + Version = "2012-10-17" + }) +} + +// IAM role policy attachment for AmazonEKSFargatePodExecutionRolePolicy +resource "aws_iam_role_policy_attachment" "AmazonEKSFargatePodExecutionRolePolicy" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" // ARN of the policy + role = aws_iam_role.fargate_iam[0].name // Name of the IAM role to attach the policy to +} diff --git a/modules/eks/nodes/outputs.tf b/modules/eks/nodes/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/eks/nodes/variables.tf b/modules/eks/nodes/variables.tf new file mode 100644 index 0000000..01b6422 --- /dev/null +++ b/modules/eks/nodes/variables.tf @@ -0,0 +1,67 @@ +################################################################################# +# Variables +################################################################################# + + +// Prefix used in naming resources within the EKS cluster +variable "cluster_prefix" { + type = string +} + +// Name of the EKS cluster +variable "cluster_name" { + type = string +} + +// List of subnet IDs where EKS resources (nodes or Fargate profiles) will be deployed +variable "subnet_ids" { + type = list(string) +} + +// Desired number of instances in the node group (default: 1) +variable "desired_size" { + type = number + default = 1 +} + +// Maximum number of instances in the node group (default: 1) +variable "max_size" { + type = number + default = 1 +} + +// Minimum number of instances in the node group (default: 1) +variable "min_size" { + type = number + default = 1 +} + +// List of instance types for nodes in the node group (default: ["t3.medium"]) +variable "instance_type" { + type = list(string) + default = ["t3.medium"] +} + +// Environment identifier used in naming resources within the cluster +variable "node_environment" { + type = string +} + +// Size of the disk attached to each instance in the node group (default: "30" GB) +variable "disk_size" { + type = string + default = "30" +} + +// Type of the node group to create. Possible values are 'fargate' or 'vm'. +variable "node_type" { + description = "Type of the node group to create. Possible values are 'fargate' or 'vm'." + type = string + default = "vm" +} + +// List of namespaces for Fargate profile selectors (optional) +variable "selector" { + description = "List of namespaces for Fargate profile selectors." + type = list(string) +} diff --git a/modules/eks/output.tf b/modules/eks/output.tf new file mode 100644 index 0000000..4f6847a --- /dev/null +++ b/modules/eks/output.tf @@ -0,0 +1,16 @@ +###################################################################################### +# Outputs for the KS Modules +###################################################################################### + + +// Output: Cluster Endpoint +output "cluster_endpoint" { + description = "Endpoint for EKS control plane" + value = aws_eks_cluster.eks_cluster.endpoint +} + +// Output: Cluster Name +output "cluster_name" { + description = "Kubernetes Cluster Name" + value = aws_eks_cluster.eks_cluster.name +} diff --git a/modules/eks/variables.tf b/modules/eks/variables.tf new file mode 100644 index 0000000..473123b --- /dev/null +++ b/modules/eks/variables.tf @@ -0,0 +1,63 @@ +###################################################################################### +# Variable for the Eks Modules +###################################################################################### + +// Prefix used to apply generic naming to the EKS Cluster +variable "cluster_prefix" { + description = "To apply generic naming to EKS Cluster" + type = string +} + +// Kubernetes version for the EKS Cluster +variable "kubernetes_version" { + description = "Kubernetes version for EKS Cluster" + type = string + default = "1.29" +} + +// List of Control Plane Logging options to enable +variable "eks_cluster_enabled_log_types" { + description = "List of Control Plane Logging options to enable" + type = list(any) + default = ["api", "audit"] +} + +// CloudWatch log events retention period in days for EKS Cluster +variable "eks_cluster_log_retention_in_days" { + description = "Cloudwatch log events retention period in days for EKS Cluster" + type = number + default = 7 +} + +// EKS Cluster - Kubernetes Service IP address range +variable "eks_cluster_service_ipv4_cidr" { + description = "EKS Cluster - Kubernetes Service IP address range" + type = string + default = "10.43.0.0/16" +} + +// Average wait time in minutes for the EKS Cluster to be created +variable "eks_cluster_create_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be created" + type = string + default = "30m" +} + +// Average wait time in minutes for the EKS Cluster to be deleted +variable "eks_cluster_delete_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be deleted" + type = string + default = "15m" +} + +// Average wait time in minutes for the EKS Cluster to be updated +variable "eks_cluster_update_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be updated" + type = string + default = "60m" +} + +// List of private subnet IDs where EKS resources will be deployed +variable "private_subnet_ids" { + type = list(string) +} diff --git a/modules/rds/main.tf b/modules/rds/main.tf new file mode 100644 index 0000000..e7d341e --- /dev/null +++ b/modules/rds/main.tf @@ -0,0 +1,75 @@ +# KMS Key for RDS +resource "aws_kms_key" "kms" { + description = "KMS key for RDS" +} + +data "aws_rds_engine_version" "current" { + engine = var.db_engine + version = var.db_version +} + + +# Security group for RDS instance +resource "aws_security_group" "rds_sg" { + name_prefix = "${var.cluster_prefix}-${var.db_environment}-rds-sg" + description = "Security group for RDS instance" + vpc_id = var.vpc_id + + ingress { + from_port = var.db_port + to_port = var.db_port + protocol = "tcp" + cidr_blocks = var.allowed_ip # Consider restricting this to your IP range or VPC + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-rds-sg" + } +} + +# Subnet group for RDS instance +resource "aws_db_subnet_group" "subnet_group" { + name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" + subnet_ids = var.subnet_ids + description = "Subnet group for RDS instance" + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" + } + depends_on = [ + aws_security_group.rds_sg + ] +} + +# RDS instance +resource "aws_db_instance" "db_instance" { + allocated_storage = var.db_storage + # identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" + identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" + db_name = var.db_name + engine = var.db_engine + engine_version = var.db_version + instance_class = var.db_instance_class + + vpc_security_group_ids = [aws_security_group.rds_sg.id] + db_subnet_group_name = aws_db_subnet_group.subnet_group.name + + # manage_master_user_password = true + # master_user_secret_kms_key_id = aws_kms_key.kms.key_id + username = var.db_username + password = var.db_password + skip_final_snapshot = true + delete_automated_backups = true + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-db" + } + depends_on = [ aws_db_subnet_group.subnet_group, aws_security_group.rds_sg ] +} diff --git a/modules/rds/outputs.tf b/modules/rds/outputs.tf new file mode 100644 index 0000000..995d296 --- /dev/null +++ b/modules/rds/outputs.tf @@ -0,0 +1,24 @@ +############################################################################## +# Outputs +############################################################################# + +# Output: Database Instance Endpoint +# The endpoint address of the RDS instance +output "db_instance_endpoint" { + description = "The endpoint address of the RDS instance" + value = aws_db_instance.db_instance.endpoint +} + +# Output: Database Instance ID +# The unique identifier of the RDS instance +output "db_instance_id" { + description = "The unique identifier of the RDS instance" + value = aws_db_instance.db_instance.id +} + +# Output: RDS Security Group ID +# The ID of the security group associated with the RDS instance +output "rds_security_group_id" { + description = "The ID of the security group associated with the RDS instance" + value = aws_security_group.rds_sg.id +} diff --git a/modules/rds/variables.tf b/modules/rds/variables.tf new file mode 100644 index 0000000..faab1dd --- /dev/null +++ b/modules/rds/variables.tf @@ -0,0 +1,85 @@ +############################################################################## +# Outputs +############################################################################# + +# Variable Definitions + +# Prefix for naming resources +variable "cluster_prefix" { + description = "Prefix for naming resources" + type = string +} + +# Storage size for the database +variable "db_storage" { + description = "Allocated storage size for the RDS instance in GB" + type = number +} + +# Environment for the database (e.g., dev, prod) +variable "db_environment" { + description = "Environment for the database (e.g., dev, prod)" + type = string +} + +# Database engine type (e.g., postgres, mysql) +variable "db_engine" { + description = "Type of the database engine (e.g., postgres, mysql)" + type = string +} + +# Instance class for the database +variable "db_instance_class" { + description = "Instance class for the RDS database instance" + type = string +} + +# Port for the database +variable "db_port" { + description = "Port number on which the database accepts connections. Defaults to 5432 for PostgreSQL" + type = string + default = "5432" +} + +# Allowed IP addresses for database access +variable "allowed_ip" { + description = "List of allowed IP addresses for database access" + type = list(string) + default = ["0.0.0.0/0"] +} + +# Version of the database engine +variable "db_version" { + description = "Version of the database engine" + type = string +} + +# Name of the database +variable "db_name" { + description = "Name of the database" + type = string +} + +# Username for the database +variable "db_username" { + description = "Username for the database" + type = string +} + +# Password for the database +variable "db_password" { + description = "Password for the database" + type = string +} + +# List of subnet IDs for the database +variable "subnet_ids" { + description = "List of subnet IDs for the RDS instance" + type = list(string) +} + +# ID of the VPC +variable "vpc_id" { + description = "ID of the VPC" + type = string +} diff --git a/modules/vpc/gateway/main.tf b/modules/vpc/gateway/main.tf new file mode 100644 index 0000000..9e2914d --- /dev/null +++ b/modules/vpc/gateway/main.tf @@ -0,0 +1,46 @@ +####################################################### +# Internet Gateway +####################################################### + +# Resource: aws_internet_gateway.this +# Description: Creates an Internet Gateway if gateway_type is "internet" to provide internet access to public subnets. +resource "aws_internet_gateway" "this" { + count = var.gateway_type == "internet" ? 1 : 0 + + vpc_id = var.vpc_id + + tags = { + Name = "${var.cluster_prefix}-${var.gateway_type}-gateway" + } +} + +####################################################### +# Elastic IP (EIP) +####################################################### + +# Resource: aws_eip.nat +# Description: Creates an Elastic IP (EIP) if gateway_type is "nat" to associate with a NAT Gateway. +resource "aws_eip" "nat" { + count = var.gateway_type == "nat" ? 1 : 0 + + tags = { + Name = "${var.cluster_prefix}-eip" + } +} + +####################################################### +# NAT Gateway +####################################################### + +# Resource: aws_nat_gateway.this +# Description: Creates a NAT Gateway if gateway_type is "nat" to allow private subnet instances to access the internet. +resource "aws_nat_gateway" "this" { + count = var.gateway_type == "nat" ? 1 : 0 + + allocation_id = aws_eip.nat[0].id + subnet_id = var.subnet_id + + tags = { + Name = "${var.cluster_prefix}-nat-gateway" + } +} diff --git a/modules/vpc/gateway/outputs.tf b/modules/vpc/gateway/outputs.tf new file mode 100644 index 0000000..ea0e464 --- /dev/null +++ b/modules/vpc/gateway/outputs.tf @@ -0,0 +1,24 @@ +####################################################### +# Outputs +####################################################### + +# Output: internet_gateway_id +# Description: The ID of the Internet Gateway if gateway_type is "internet", otherwise null. +output "internet_gateway_id" { + description = "The ID of the Internet Gateway" + value = var.gateway_type == "internet" ? aws_internet_gateway.this[0].id : null +} + +# Output: nat_gateway_id +# Description: The ID of the NAT Gateway if gateway_type is "nat", otherwise null. +output "nat_gateway_id" { + description = "The ID of the NAT Gateway" + value = var.gateway_type == "nat" ? aws_nat_gateway.this[0].id : null +} + +# Output: nat_gateway_eip +# Description: The Elastic IP of the NAT Gateway if gateway_type is "nat", otherwise null. +output "nat_gateway_eip" { + description = "The Elastic IP of the NAT Gateway" + value = var.gateway_type == "nat" ? aws_eip.nat[0].public_ip : null +} diff --git a/modules/vpc/gateway/variables.tf b/modules/vpc/gateway/variables.tf new file mode 100644 index 0000000..cfc14c4 --- /dev/null +++ b/modules/vpc/gateway/variables.tf @@ -0,0 +1,43 @@ +####################################################### +# Variables +####################################################### + +# Variable: cluster_prefix +# Description: Prefix to apply generic naming to resources like VPC and subnets +variable "cluster_prefix" { + type = string +} + +# Variable: vpc_id +# Description: The ID of the VPC where the gateway will be attached +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# Variable: gateway_type +# Description: Type of gateway to create: 'nat' for NAT Gateway or 'internet' for Internet Gateway +variable "gateway_type" { + description = "Type of gateway: nat or internet" + type = string + validation { + condition = contains(["nat", "internet"], var.gateway_type) + error_message = "gateway_type must be either 'nat' or 'internet'." + } +} + +# Variable: subnet_id +# Description: The ID of the subnet in which to place the NAT Gateway (required if gateway_type is 'nat') +variable "subnet_id" { + description = "The ID of the subnet in which to place the NAT Gateway (required if NAT Gateway)" + type = string + default = null +} + +# Variable: tags +# Description: Tags to assign to the gateway +variable "tags" { + description = "Tags to assign to the gateway" + type = map(string) + default = {} +} diff --git a/modules/vpc/main.tf b/modules/vpc/main.tf new file mode 100644 index 0000000..343266a --- /dev/null +++ b/modules/vpc/main.tf @@ -0,0 +1,104 @@ +####################################################### +# VPC and Subnets +####################################################### + +# Create a VPC with DNS support and hostnames enabled +resource "aws_vpc" "vpc" { + cidr_block = var.cidr + enable_dns_support = true + enable_dns_hostnames = true + + tags = { + Name = "${var.cluster_prefix}-vpc" + } +} + +# Create public subnets +module "public_subnets" { + + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "public" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 0 +} + +# Create private subnets +module "private_subnets" { + + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "private" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 1 +} + +# Create storage subnets +module "storage_subnets" { + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "storage" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 2 +} + +####################################################### +# Gateways +####################################################### + +# Create an Internet Gateway for the public subnets +module "internet_gateway" { + source = "./gateway" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + gateway_type = "internet" +} + +# Create a NAT Gateway for the private and storage subnets +module "nat_gateway" { + source = "./gateway" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + gateway_type = "nat" + subnet_id = module.public_subnets.subnet_ids[0] +} + +####################################################### +# Route Tables +####################################################### + +# Create a public route table and associate it with public subnets +module "public_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.public_subnets.subnet_ids + route_table_type = "public" + internet_gateway_id = module.internet_gateway.internet_gateway_id +} + +# Create a private route table and associate it with private subnets +module "private_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.private_subnets.subnet_ids + route_table_type = "private" + nat_gateway_id = module.nat_gateway.nat_gateway_id +} + +# Create a storage route table and associate it with storage subnets +module "storage_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.storage_subnets.subnet_ids + route_table_type = "private" + nat_gateway_id = module.nat_gateway.nat_gateway_id +} diff --git a/modules/vpc/output.tf b/modules/vpc/output.tf new file mode 100644 index 0000000..177624b --- /dev/null +++ b/modules/vpc/output.tf @@ -0,0 +1,38 @@ +####################################################### +# Outputs +####################################################### + +# Output: VPC ID +# The ID of the created VPC +output "vpc_id" { + description = "The ID of the created VPC" + value = aws_vpc.vpc.id +} + +# Output: Public Subnet IDs +# List of IDs of the created public subnets +output "public_subnets_ids" { + description = "List of IDs of the created public subnets" + value = module.public_subnets.subnet_ids +} + +# Output: Private Subnet IDs +# List of IDs of the created private subnets +output "private_subnet_ids" { + description = "List of IDs of the created private subnets" + value = module.private_subnets.subnet_ids +} + +# Output: Storage Subnet IDs +# List of IDs of the created storage subnets +output "storage_subnet_ids" { + description = "List of IDs of the created storage subnets" + value = module.storage_subnets.subnet_ids +} + +# Output: Internet Gateway ID +# The ID of the created Internet Gateway +output "internet_gateway_id" { + description = "The ID of the created Internet Gateway" + value = module.internet_gateway.internet_gateway_id +} diff --git a/modules/vpc/route_table/main.tf b/modules/vpc/route_table/main.tf new file mode 100644 index 0000000..eda25e3 --- /dev/null +++ b/modules/vpc/route_table/main.tf @@ -0,0 +1,43 @@ +####################################################### +# Route Tables +####################################################### + +# Resource: aws_route_table +# Description: Manages a route table for a VPC. +resource "aws_route_table" "this" { + vpc_id = var.vpc_id + + # Dynamic Block: route (Public Route) + # Description: Defines a route for the public subnet(s) to route traffic via an Internet Gateway. + dynamic "route" { + for_each = var.route_table_type == "public" ? [1] : [] + content { + cidr_block = "0.0.0.0/0" + gateway_id = var.internet_gateway_id + } + } + + # Dynamic Block: route (Private Route) + # Description: Defines a route for the private subnet(s) to route traffic via a NAT Gateway. + dynamic "route" { + for_each = var.route_table_type == "private" ? [1] : [] + content { + cidr_block = "0.0.0.0/0" + nat_gateway_id = var.nat_gateway_id + } + } + + # Tags: Name + # Description: Tags the route table with a name based on the cluster prefix and route table type. + tags = { + Name = "${var.cluster_prefix}-${var.route_table_type}-rt" + } +} + +# Resource: aws_route_table_association +# Description: Associates subnet(s) with the specified route table. +resource "aws_route_table_association" "this" { + count = length(var.subnet_ids) + subnet_id = element(var.subnet_ids, count.index) + route_table_id = aws_route_table.this.id +} diff --git a/modules/vpc/route_table/outputs.tf b/modules/vpc/route_table/outputs.tf new file mode 100644 index 0000000..ec429fd --- /dev/null +++ b/modules/vpc/route_table/outputs.tf @@ -0,0 +1,10 @@ +####################################################### +# Outputs +####################################################### + +# Output: route_table_id +# Description: Provides the ID of the created route table. +output "route_table_id" { + description = "The ID of the route table" + value = aws_route_table.this.id +} diff --git a/modules/vpc/route_table/variables.tf b/modules/vpc/route_table/variables.tf new file mode 100644 index 0000000..272e84a --- /dev/null +++ b/modules/vpc/route_table/variables.tf @@ -0,0 +1,47 @@ +####################################################### +# Variablesw +####################################################### + +# Variable Definitions + +# The ID of the VPC +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# The ID of the Internet Gateway (required if route table type is public) +variable "internet_gateway_id" { + description = "The ID of the Internet Gateway (required if public)" + type = string + default = null +} + +# The ID of the NAT Gateway (required if route table type is private) +variable "nat_gateway_id" { + description = "The ID of the NAT Gateway (required if private)" + type = string + default = null +} + +# Prefix for naming resources +variable "cluster_prefix" { + description = "Prefix for naming resources" + type = string +} + +# Type of route table: public or private +variable "route_table_type" { + description = "Type of route table: public or private" + type = string + validation { + condition = contains(["public", "private"], var.route_table_type) + error_message = "route_table_type must be either 'public' or 'private'." + } +} + +# List of subnet IDs to associate with the route table +variable "subnet_ids" { + description = "List of subnet IDs to associate with the route table" + type = list(string) +} diff --git a/modules/vpc/security_group/main.tf b/modules/vpc/security_group/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/vpc/security_group/outputs.tf b/modules/vpc/security_group/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/vpc/security_group/variables.tf b/modules/vpc/security_group/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/vpc/subnet/main.tf b/modules/vpc/subnet/main.tf new file mode 100644 index 0000000..65f5b3c --- /dev/null +++ b/modules/vpc/subnet/main.tf @@ -0,0 +1,33 @@ +####################################################### +# Subnets +####################################################### + +#Data Source: AWS Availability Zones +# Fetches a list of all available availability zones in the current region +data "aws_availability_zones" "available_zones" {} + +# Local Variables +locals { + # Offset calculation based on the number of available availability zones + offset = length(data.aws_availability_zones.available_zones.names) +} + +# Resource: AWS Subnet +# Creates subnets across all available availability zones +resource "aws_subnet" "subnet" { + count = length(data.aws_availability_zones.available_zones.names) + + # CIDR block calculation for the subnet + cidr_block = cidrsubnet(var.cidr, var.subnet_bits, local.offset * var.offset + count.index) + + # VPC ID in which the subnet will be created + vpc_id = var.vpc_id + + # Assigns the subnet to a specific availability zone + availability_zone = data.aws_availability_zones.available_zones.names[count.index] + + # Tags assigned to the subnet for identification + tags = { + Name = "${var.cluster_prefix}-${lower(var.subnet_type)}-subnet-${count.index + 1}" + } +} diff --git a/modules/vpc/subnet/outputs.tf b/modules/vpc/subnet/outputs.tf new file mode 100644 index 0000000..55990f9 --- /dev/null +++ b/modules/vpc/subnet/outputs.tf @@ -0,0 +1,10 @@ +####################################################### +# Subnets +####################################################### + +# Output: Subnet IDs +# Provides the IDs of the subnets created +output "subnet_ids" { + description = "The IDs of the created subnets" + value = aws_subnet.subnet[*].id +} diff --git a/modules/vpc/subnet/variables.tf b/modules/vpc/subnet/variables.tf new file mode 100644 index 0000000..87aefea --- /dev/null +++ b/modules/vpc/subnet/variables.tf @@ -0,0 +1,45 @@ +####################################################### +# Variables +####################################################### + +# Variable: cidr +# Description: The CIDR block of the VPC. +variable "cidr" { + description = "The CIDR block of the VPC" + type = string +} + +# Variable: subnet_bits +# Description: The number of bits for the subnet. +variable "subnet_bits" { + description = "The number of bits for subnet" + type = number +} + +# Variable: vpc_id +# Description: The ID of the VPC. +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# Variable: cluster_prefix +# Description: Prefix for the cluster, used for naming resources. +variable "cluster_prefix" { + description = "Prefix for the cluster" + type = string +} + +# Variable: subnet_type +# Description: Type of subnet (e.g., public, private, storage). +variable "subnet_type" { + description = "Type of subnet" + type = string +} + +# Variable: offset +# Description: Offset value used for calculating subnet CIDR blocks. +variable "offset" { + description = "Offset value for subnet calculation" + type = number +} diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf new file mode 100644 index 0000000..8786388 --- /dev/null +++ b/modules/vpc/variables.tf @@ -0,0 +1,24 @@ +####################################################### +# Variables +####################################################### + +# Variable: cluster_prefix +# Description: Prefix to apply generic naming to resources like VPC and subnets +variable "cluster_prefix" { + type = string + description = "Prefix to apply generic naming to resources like VPC and subnets" +} + +# Variable: cidr +# Description: CIDR block for the VPC +variable "cidr" { + type = string + description = "CIDR block for the VPC" +} + +# Variable: subnet_bits +# Description: Number of bits to use for subnet calculations +variable "subnet_bits" { + type = string + description = "Number of bits to use for subnet calculations" +} diff --git a/output.tf b/output.tf index b3469c9..6277567 100644 --- a/output.tf +++ b/output.tf @@ -1,15 +1,39 @@ -output "endpoint" { - value = aws_eks_cluster.eks_cluster.endpoint +####################################################### +# Outputs +####################################################### + +# EKS cluster endpoint +output "cluster_endpoint" { + description = "Endpoint for EKS control plane" + value = module.eks.cluster_endpoint +} + +# AWS region +output "region" { + description = "AWS region" + value = var.region +} + +# EKS cluster name +output "cluster_name" { + description = "Kubernetes Cluster Name" + value = module.eks.cluster_name } -output "kubeconfig_certificate_authority_data" { - value = aws_eks_cluster.eks_cluster.certificate_authority[0].data +# RDS endpoints +output "rds_endpoints" { + description = "RDS Endpoints" + value = { for key, db in module.database : key => db.db_instance_endpoint } } -output "eks_cluster_policy" { - value = aws_iam_role_policy_attachment.eks_cluster_policy +# Public subnets IDs +output "public_subnets" { + description = "IDs of public subnets" + value = module.vpc.public_subnets_ids } -output "eks_vpc_resource_controller_policy" { - value = aws_iam_role_policy_attachment.eks_vpc_resource_controller_policy +# VPC ID +output "vpc_id" { + description = "ID of the VPC" + value = module.vpc.vpc_id } diff --git a/terraform.tfvars b/terraform.tfvars new file mode 100644 index 0000000..d509abb --- /dev/null +++ b/terraform.tfvars @@ -0,0 +1,62 @@ +# Terraform variables for configuring the infrastructure + +# To apply generic naming to EKS Cluster +cluster_prefix = "source4learn" + +# AWS Region for the infrastructure +region = "ap-southeast-2" + +# CIDR block for the VPC +cidr = "10.0.0.0/16" + +# Number of subnet bits +subnet_bits = 4 + +# Kubernetes version for EKS Cluster +kubernetes_version = "1.28" + +# List of Control Plane Logging options to enable +eks_cluster_enabled_log_types = ["api", "audit"] + +# Cloudwatch log events retention period in days for EKS Cluster +eks_cluster_log_retention_in_days = 7 + +# EKS Cluster - Kubernetes Service IP address range +eks_cluster_service_ipv4_cidr = "10.43.0.0/16" + +# Average wait time in minutes for the EKS Cluster to be created +eks_cluster_create_timeout = "30m" + +# Average wait time in minutes for the EKS Cluster to be deleted +eks_cluster_delete_timeout = "15m" + +# Average wait time in minutes for the EKS Cluster to be updated +eks_cluster_update_timeout = "60m" + +# Map of node groups to create with their respective configurations +nodes= { + dev = { + instance_type = ["t3.medium"] + node_type = "vm" + desired_size = 1 + max_size = 3 + min_size = 1 + } + prod = { + node_type = "fargate" + selector = ["production"] + } +} + +# Map of databases to create with their respective configurations +databases = { + dev = { + db_engine = "postgres" + db_instance_class = "db.t3.micro" + db_version = "13.13" + db_storage = 20 + db_name = "devapi2" + db_username = "devapi2admin" + db_password = "gNjx3jKUcoRk8JJ" + } +} diff --git a/variables.tf b/variables.tf index ca9781b..4d79e77 100644 --- a/variables.tf +++ b/variables.tf @@ -1,60 +1,105 @@ +####################################################### # Terraform Variables -variable "eks_cluster_prefix" { - description = "To apply generic naming to EKS Cluster" +####################################################### +# Terraform Variables + +# To apply generic naming to EKS Cluster +variable "cluster_prefix" { + description = "Prefix to apply to EKS Cluster" type = string default = "source4learn" } -variable "eks_cluster_environment" { - description = "To apply generic environment to EKS Cluster" +# AWS Region for the infrastructure +variable "region" { + description = "AWS Region where the infrastructure will be deployed" type = string - default = "devops" } -variable "kubernetes_version" { - description = "Kubernetes version for EKS Cluster" +# CIDR block for the VPC +variable "cidr" { + description = "CIDR block for the VPC" type = string - default = "1.19" } -variable "subnet_ids" { - description = "List of VPC Subnets to be set in EKS Cluster" - type = list(any) - default = ["subnet-d12321b9", "subnet-4a245706", "subnet-38299343"] +# Number of subnet bits for subnet calculation +variable "subnet_bits" { + description = "Number of bits to use for subnetting" + type = number +} + +# Kubernetes version for EKS Cluster +variable "kubernetes_version" { + description = "Version of Kubernetes for the EKS Cluster" + type = string + default = "1.19" } +# List of Control Plane Logging options to enable variable "eks_cluster_enabled_log_types" { description = "List of Control Plane Logging options to enable" type = list(any) default = ["api", "audit"] } +# Cloudwatch log events retention period in days for EKS Cluster variable "eks_cluster_log_retention_in_days" { - description = "Cloudwatch log events retention period in days for EKS Cluster" + description = "Retention period in days for CloudWatch log events" type = number default = 7 } +# EKS Cluster - Kubernetes Service IP address range variable "eks_cluster_service_ipv4_cidr" { - description = "EKS Cluster - Kubernetes Service IP address range" + description = "IP address range for Kubernetes services in the EKS Cluster" type = string default = "10.43.0.0/16" } +# Average wait time in minutes for the EKS Cluster to be created variable "eks_cluster_create_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be created" + description = "Average wait time in minutes for EKS Cluster creation" type = string default = "30m" } +# Average wait time in minutes for the EKS Cluster to be deleted variable "eks_cluster_delete_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be deleted" + description = "Average wait time in minutes for EKS Cluster deletion" type = string default = "15m" } +# Average wait time in minutes for the EKS Cluster to be updated variable "eks_cluster_update_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be updated" + description = "Average wait time in minutes for EKS Cluster update" type = string default = "60m" -} \ No newline at end of file +} + +# Map of node groups to create with their respective configurations +variable "nodes" { + description = "Map of node groups to create with their respective configurations" + type = map(object({ + instance_type = optional(list(string)) + node_type = string + desired_size = optional(number) + max_size = optional(number) + min_size = optional(number) + selector = optional(list(string)) + })) +} + +# Map of databases to create with their respective configurations +variable "databases" { + description = "Map of databases to create with their respective configurations" + type = map(object({ + db_engine = string + db_instance_class = string + db_version = string + db_storage = number + db_name = string + db_username = string + db_password = string + })) +} From 1711eda6c36f45c45f8164b7d06deb43bb09369e Mon Sep 17 00:00:00 2001 From: "ravi752696@gmail.com" Date: Sun, 7 Jul 2024 16:26:26 +0530 Subject: [PATCH 2/4] Update policy --- .gitignore | 78 ++--- cloudwatch.tf | 18 +- iam.tf | 94 +++--- main.tf | 176 +++++----- modules/eks/iam_policy.json | 484 +++++++++++++-------------- modules/eks/main.tf | 282 ++++++++-------- modules/eks/nodes/main.tf | 248 +++++++------- modules/eks/nodes/variables.tf | 134 ++++---- modules/eks/output.tf | 32 +- modules/eks/variables.tf | 126 +++---- modules/rds/main.tf | 150 ++++----- modules/rds/outputs.tf | 48 +-- modules/rds/variables.tf | 170 +++++----- modules/vpc/gateway/main.tf | 92 ++--- modules/vpc/gateway/outputs.tf | 48 +-- modules/vpc/gateway/variables.tf | 86 ++--- modules/vpc/main.tf | 208 ++++++------ modules/vpc/output.tf | 76 ++--- modules/vpc/route_table/main.tf | 86 ++--- modules/vpc/route_table/outputs.tf | 20 +- modules/vpc/route_table/variables.tf | 94 +++--- modules/vpc/subnet/main.tf | 66 ++-- modules/vpc/subnet/outputs.tf | 20 +- modules/vpc/subnet/variables.tf | 90 ++--- modules/vpc/variables.tf | 48 +-- output.tf | 78 ++--- terraform.tfvars | 124 +++---- variables.tf | 210 ++++++------ 28 files changed, 1693 insertions(+), 1693 deletions(-) diff --git a/.gitignore b/.gitignore index cdff0cb..ba8cdac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,40 +1,40 @@ -# Local .terraform directories -*.terraform -**/.terraform/* - -# .tfstate files -*.tfstate -*.tfstate.* - -# Local .hcl configurations -*.hcl - -# Crash log files -crash.log - -# Crash log files -crash.log - -# Ignore any .tfvars files that are generated automatically for each Terraform run. Most -# .tfvars files are managed as part of configuration and so should be included in -# version control. -# -# example.tfvars - -# Ignore override files as they are usually used to override resources locally and so -# are not checked in -override.tf -override.tf.json -*_override.tf -*_override.tf.json - -# Include override files you do wish to add to version control using negated pattern -# -# !example_override.tf - -# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan -# example: *tfplan* - -kubeconfig/* -provider.tf +# Local .terraform directories +*.terraform +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Local .hcl configurations +*.hcl + +# Crash log files +crash.log + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +kubeconfig/* +provider.tf backend.tf \ No newline at end of file diff --git a/cloudwatch.tf b/cloudwatch.tf index 075166f..0136e81 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -1,10 +1,10 @@ -resource "aws_cloudwatch_log_group" "eks_cluster_cloudwatch_log_group" { - count = length(var.eks_cluster_enabled_log_types) > 0 ? 1 : 0 - name = "/aws/eks/${var.eks_cluster_prefix}-${var.eks_cluster_environment}/cluster" - retention_in_days = var.eks_cluster_log_retention_in_days +# resource "aws_cloudwatch_log_group" "eks_cluster_cloudwatch_log_group" { +# count = length(var.eks_cluster_enabled_log_types) > 0 ? 1 : 0 +# name = "/aws/eks/${var.eks_cluster_prefix}-${var.eks_cluster_environment}/cluster" +# retention_in_days = var.eks_cluster_log_retention_in_days - tags = { - Name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}" - Environment = var.eks_cluster_environment - } -} \ No newline at end of file +# tags = { +# Name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}" +# Environment = var.eks_cluster_environment +# } +# } \ No newline at end of file diff --git a/iam.tf b/iam.tf index 982e7fb..9bb1678 100644 --- a/iam.tf +++ b/iam.tf @@ -1,54 +1,54 @@ -data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { - statement { - effect = "Allow" - principals { - type = "Service" - identifiers = ["eks.amazonaws.com"] - } - actions = [ - "sts:AssumeRole", - ] - } -} +# data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { +# statement { +# effect = "Allow" +# principals { +# type = "Service" +# identifiers = ["eks.amazonaws.com"] +# } +# actions = [ +# "sts:AssumeRole", +# ] +# } +# } -data "aws_iam_policy_document" "eks_cluster_elb_service_link_role_policy" { - statement { - effect = "Allow" - actions = [ - "ec2:DescribeAccountAttributes", - "ec2:DescribeInternetGateways", - "ec2:DescribeAddresses" - ] - resources = ["*"] - } -} +# data "aws_iam_policy_document" "eks_cluster_elb_service_link_role_policy" { +# statement { +# effect = "Allow" +# actions = [ +# "ec2:DescribeAccountAttributes", +# "ec2:DescribeInternetGateways", +# "ec2:DescribeAddresses" +# ] +# resources = ["*"] +# } +# } -resource "aws_iam_role" "eks_cluster_role" { - name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}-eks-cluster-role" - assume_role_policy = data.aws_iam_policy_document.eks_cluster_assume_role_policy.json -} +# resource "aws_iam_role" "eks_cluster_role" { +# name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}-eks-cluster-role" +# assume_role_policy = data.aws_iam_policy_document.eks_cluster_assume_role_policy.json +# } -resource "aws_iam_policy" "eks_cluster_elb_service_link_policy" { - name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}-eks-cluster-elb-service-link-policy" - policy = data.aws_iam_policy_document.eks_cluster_elb_service_link_role_policy.json -} +# resource "aws_iam_policy" "eks_cluster_elb_service_link_policy" { +# name = "${var.eks_cluster_prefix}-${var.eks_cluster_environment}-eks-cluster-elb-service-link-policy" +# policy = data.aws_iam_policy_document.eks_cluster_elb_service_link_role_policy.json +# } -resource "aws_iam_role_policy_attachment" "eks_cluster_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" - role = aws_iam_role.eks_cluster_role.name -} +# resource "aws_iam_role_policy_attachment" "eks_cluster_policy" { +# policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" +# role = aws_iam_role.eks_cluster_role.name +# } -resource "aws_iam_role_policy_attachment" "eks_service_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" - role = aws_iam_role.eks_cluster_role.name -} +# resource "aws_iam_role_policy_attachment" "eks_service_policy" { +# policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" +# role = aws_iam_role.eks_cluster_role.name +# } -resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" - role = aws_iam_role.eks_cluster_role.name -} +# resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller_policy" { +# policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" +# role = aws_iam_role.eks_cluster_role.name +# } -resource "aws_iam_role_policy_attachment" "eks_cluster_elb_service_link_policy_attachment" { - policy_arn = aws_iam_policy.eks_cluster_elb_service_link_policy.arn - role = aws_iam_role.eks_cluster_role.name -} \ No newline at end of file +# resource "aws_iam_role_policy_attachment" "eks_cluster_elb_service_link_policy_attachment" { +# policy_arn = aws_iam_policy.eks_cluster_elb_service_link_policy.arn +# role = aws_iam_role.eks_cluster_role.name +# } \ No newline at end of file diff --git a/main.tf b/main.tf index 5ffa9a4..48a2854 100644 --- a/main.tf +++ b/main.tf @@ -1,88 +1,88 @@ -####################################################### -# Terraform Configuration -####################################################### - -# Specify the required providers and backend for Terraform state -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.0" - } - } - backend "s3" { - # Backend configuration for S3 will be added here - } -} - -# AWS provider configuration -provider "aws" { - region = var.region -} - -####################################################### -# VPC Module -####################################################### - -# Create the VPC and subnets using a module -module "vpc" { - source = "./modules/vpc" - cluster_prefix = var.cluster_prefix - cidr = var.cidr - subnet_bits = var.subnet_bits -} - -####################################################### -# EKS Cluster Module -####################################################### - -# Create the EKS cluster using a module -module "eks" { - source = "./modules/eks" - cluster_prefix = var.cluster_prefix - kubernetes_version = var.kubernetes_version - private_subnet_ids = module.vpc.private_subnet_ids - eks_cluster_enabled_log_types = var.eks_cluster_enabled_log_types -} - -####################################################### -# EKS Node Groups Module -####################################################### - -# Create EKS node groups using a module -module "nodes" { - depends_on = [module.eks] - for_each = var.nodes - source = "./modules/eks/nodes" - cluster_prefix = var.cluster_prefix - node_environment = each.key - subnet_ids = module.vpc.private_subnet_ids - cluster_name = module.eks.cluster_name - node_type = each.value.node_type - instance_type = try(each.value.instance_type, null) - desired_size = try(each.value.desired_size, null) - max_size = try(each.value.max_size, null) - min_size = try(each.value.min_size, null) - selector = each.value.node_type == "fargate" ? each.value.selector : null -} - -####################################################### -# RDS Database Module -####################################################### - -# Create RDS instances using a module -module "database" { - for_each = var.databases - source = "./modules/rds" - cluster_prefix = var.cluster_prefix - db_environment = each.key - db_engine = each.value.db_engine - db_instance_class = each.value.db_instance_class - db_version = each.value.db_version - db_storage = each.value.db_storage - db_name = each.value.db_name - db_username = each.value.db_username - db_password = each.value.db_password - vpc_id = module.vpc.vpc_id - subnet_ids = module.vpc.storage_subnet_ids -} +####################################################### +# Terraform Configuration +####################################################### + +# Specify the required providers and backend for Terraform state +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } + backend "s3" { + # Backend configuration for S3 will be added here + } +} + +# AWS provider configuration +provider "aws" { + region = var.region +} + +####################################################### +# VPC Module +####################################################### + +# Create the VPC and subnets using a module +module "vpc" { + source = "./modules/vpc" + cluster_prefix = var.cluster_prefix + cidr = var.cidr + subnet_bits = var.subnet_bits +} + +####################################################### +# EKS Cluster Module +####################################################### + +# Create the EKS cluster using a module +module "eks" { + source = "./modules/eks" + cluster_prefix = var.cluster_prefix + kubernetes_version = var.kubernetes_version + private_subnet_ids = module.vpc.private_subnet_ids + eks_cluster_enabled_log_types = var.eks_cluster_enabled_log_types +} + +####################################################### +# EKS Node Groups Module +####################################################### + +# Create EKS node groups using a module +module "nodes" { + depends_on = [module.eks] + for_each = var.nodes + source = "./modules/eks/nodes" + cluster_prefix = var.cluster_prefix + node_environment = each.key + subnet_ids = module.vpc.private_subnet_ids + cluster_name = module.eks.cluster_name + node_type = each.value.node_type + instance_type = try(each.value.instance_type, null) + desired_size = try(each.value.desired_size, null) + max_size = try(each.value.max_size, null) + min_size = try(each.value.min_size, null) + selector = each.value.node_type == "fargate" ? each.value.selector : null +} + +####################################################### +# RDS Database Module +####################################################### + +# Create RDS instances using a module +module "database" { + for_each = var.databases + source = "./modules/rds" + cluster_prefix = var.cluster_prefix + db_environment = each.key + db_engine = each.value.db_engine + db_instance_class = each.value.db_instance_class + db_version = each.value.db_version + db_storage = each.value.db_storage + db_name = each.value.db_name + db_username = each.value.db_username + db_password = each.value.db_password + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.storage_subnet_ids +} diff --git a/modules/eks/iam_policy.json b/modules/eks/iam_policy.json index 76d96e4..ebfef10 100644 --- a/modules/eks/iam_policy.json +++ b/modules/eks/iam_policy.json @@ -1,242 +1,242 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "iam:CreateServiceLinkedRole" - ], - "Resource": "*", - "Condition": { - "StringEquals": { - "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeAccountAttributes", - "ec2:DescribeAddresses", - "ec2:DescribeAvailabilityZones", - "ec2:DescribeInternetGateways", - "ec2:DescribeVpcs", - "ec2:DescribeVpcPeeringConnections", - "ec2:DescribeSubnets", - "ec2:DescribeSecurityGroups", - "ec2:DescribeInstances", - "ec2:DescribeNetworkInterfaces", - "ec2:DescribeTags", - "ec2:GetCoipPoolUsage", - "ec2:DescribeCoipPools", - "elasticloadbalancing:DescribeLoadBalancers", - "elasticloadbalancing:DescribeLoadBalancerAttributes", - "elasticloadbalancing:DescribeListeners", - "elasticloadbalancing:DescribeListenerCertificates", - "elasticloadbalancing:DescribeSSLPolicies", - "elasticloadbalancing:DescribeRules", - "elasticloadbalancing:DescribeTargetGroups", - "elasticloadbalancing:DescribeTargetGroupAttributes", - "elasticloadbalancing:DescribeTargetHealth", - "elasticloadbalancing:DescribeTags", - "elasticloadbalancing:DescribeTrustStores" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "cognito-idp:DescribeUserPoolClient", - "acm:ListCertificates", - "acm:DescribeCertificate", - "iam:ListServerCertificates", - "iam:GetServerCertificate", - "waf-regional:GetWebACL", - "waf-regional:GetWebACLForResource", - "waf-regional:AssociateWebACL", - "waf-regional:DisassociateWebACL", - "wafv2:GetWebACL", - "wafv2:GetWebACLForResource", - "wafv2:AssociateWebACL", - "wafv2:DisassociateWebACL", - "shield:GetSubscriptionState", - "shield:DescribeProtection", - "shield:CreateProtection", - "shield:DeleteProtection" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:RevokeSecurityGroupIngress" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:CreateSecurityGroup" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:CreateTags" - ], - "Resource": "arn:aws:ec2:*:*:security-group/*", - "Condition": { - "StringEquals": { - "ec2:CreateAction": "CreateSecurityGroup" - }, - "Null": { - "aws:RequestTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "ec2:CreateTags", - "ec2:DeleteTags" - ], - "Resource": "arn:aws:ec2:*:*:security-group/*", - "Condition": { - "Null": { - "aws:RequestTag/elbv2.k8s.aws/cluster": "true", - "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:RevokeSecurityGroupIngress", - "ec2:DeleteSecurityGroup" - ], - "Resource": "*", - "Condition": { - "Null": { - "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:CreateLoadBalancer", - "elasticloadbalancing:CreateTargetGroup" - ], - "Resource": "*", - "Condition": { - "Null": { - "aws:RequestTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:CreateListener", - "elasticloadbalancing:DeleteListener", - "elasticloadbalancing:CreateRule", - "elasticloadbalancing:DeleteRule" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:AddTags", - "elasticloadbalancing:RemoveTags" - ], - "Resource": [ - "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", - "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*", - "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*" - ], - "Condition": { - "Null": { - "aws:RequestTag/elbv2.k8s.aws/cluster": "true", - "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:AddTags", - "elasticloadbalancing:RemoveTags" - ], - "Resource": [ - "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", - "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", - "arn:aws:elasticloadbalancing:*:*:listener-rule/*/*/*/*", - "arn:aws:elasticloadbalancing:*:*:listener-rule/*/*/*/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:ModifyLoadBalancerAttributes", - "elasticloadbalancing:SetIpAddressType", - "elasticloadbalancing:SetSecurityGroups", - "elasticloadbalancing:SetSubnets", - "elasticloadbalancing:DeleteLoadBalancer", - "elasticloadbalancing:ModifyTargetGroup", - "elasticloadbalancing:ModifyTargetGroupAttributes", - "elasticloadbalancing:DeleteTargetGroup" - ], - "Resource": "*", - "Condition": { - "Null": { - "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:AddTags" - ], - "Resource": [ - "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", - "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*", - "arn:aws:elasticloadbalancing:*:*:loadbalancer/*/*/*" - ], - "Condition": { - "StringEquals": { - "elasticloadbalancing:CreateAction": [ - "CreateTargetGroup", - "CreateLoadBalancer" - ] - }, - "Null": { - "aws:RequestTag/elbv2.k8s.aws/cluster": "false" - } - } - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:RegisterTargets", - "elasticloadbalancing:DeregisterTargets" - ], - "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:SetWebAcl", - "elasticloadbalancing:ModifyListener", - "elasticloadbalancing:AddListenerCertificates", - "elasticloadbalancing:RemoveListenerCertificates", - "elasticloadbalancing:ModifyRule" - ], - "Resource": "*" - } - ] -} +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:CreateServiceLinkedRole" + ], + "Resource": "*", + "Condition": { + "StringEquals": { + "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInternetGateways", + "ec2:DescribeVpcs", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeTags", + "ec2:GetCoipPoolUsage", + "ec2:DescribeCoipPools", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTrustStores" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "cognito-idp:DescribeUserPoolClient", + "acm:ListCertificates", + "acm:DescribeCertificate", + "iam:ListServerCertificates", + "iam:GetServerCertificate", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "shield:GetSubscriptionState", + "shield:DescribeProtection", + "shield:CreateProtection", + "shield:DeleteProtection" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateSecurityGroup" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "StringEquals": { + "ec2:CreateAction": "CreateSecurityGroup" + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags", + "ec2:DeleteTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:DeleteSecurityGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + ], + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:DeleteTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + ], + "Condition": { + "StringEquals": { + "elasticloadbalancing:CreateAction": [ + "CreateTargetGroup", + "CreateLoadBalancer" + ] + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets" + ], + "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:SetWebAcl", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:ModifyRule" + ], + "Resource": "*" + } + ] +} \ No newline at end of file diff --git a/modules/eks/main.tf b/modules/eks/main.tf index 6286dd6..776987e 100644 --- a/modules/eks/main.tf +++ b/modules/eks/main.tf @@ -1,141 +1,141 @@ -###################################################################################### -# EKS Cluster -###################################################################################### - -// AWS EKS Cluster resource definition -resource "aws_eks_cluster" "eks_cluster" { - name = "${var.cluster_prefix}-cluster" // Name of the EKS cluster - role_arn = aws_iam_role.eks_cluster_role.arn // IAM role ARN for the EKS cluster - version = var.kubernetes_version // Kubernetes version for the cluster - - // VPC configuration for the cluster - vpc_config { - subnet_ids = var.private_subnet_ids // Subnet IDs where EKS resources will be deployed - } - - // Kubernetes network configuration - kubernetes_network_config { - service_ipv4_cidr = var.eks_cluster_service_ipv4_cidr // CIDR block for Kubernetes service IPs - } - - // Timeouts configuration for create, delete, and update operations - timeouts { - create = var.eks_cluster_create_timeout - delete = var.eks_cluster_delete_timeout - update = var.eks_cluster_update_timeout - } - - // Dependencies on IAM resources and policies - depends_on = [ - aws_iam_role_policy_attachment.eks_cluster_policy, - aws_iam_role_policy_attachment.eks_vpc_resource_controller_policy, - aws_iam_role_policy_attachment.eks_cluster_elb_service_link_policy_attachment, - - aws_iam_role.eks_cluster_role, - aws_iam_policy.alb_policy, - aws_cloudwatch_log_group.eks_cluster_cloudwatch_log_group, - ] - - // Tags for the EKS cluster resource - tags = { - Name = "${var.cluster_prefix}-cluster" - Environment = "all-environment" - } -} - -################################################################################# -# Creating Role and Policies for the cluster -################################################################################# - -// IAM policy document for EKS cluster assume role policy -data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { - statement { - effect = "Allow" - principals { - type = "Service" - identifiers = ["eks.amazonaws.com"] - } - actions = [ - "sts:AssumeRole", - ] - } -} - -// IAM policy document for EKS cluster ELB service link role policy -data "aws_iam_policy_document" "eks_cluster_elb_service_link_role_policy" { - statement { - effect = "Allow" - actions = [ - "ec2:DescribeAccountAttributes", - "ec2:DescribeInternetGateways", - "ec2:DescribeAddresses", - "elasticloadbalancing:DescribeLoadBalancers", - "elasticloadbalancing:*" - ] - resources = ["*"] - } -} - -// IAM role for EKS cluster -resource "aws_iam_role" "eks_cluster_role" { - name = "${var.cluster_prefix}-eks-cluster-role" - assume_role_policy = data.aws_iam_policy_document.eks_cluster_assume_role_policy.json -} - -// IAM policy for EKS cluster ELB service link -resource "aws_iam_policy" "eks_cluster_elb_service_link_policy" { - name = "${var.cluster_prefix}-eks-cluster-elb-service-link-policy" - policy = data.aws_iam_policy_document.eks_cluster_elb_service_link_role_policy.json -} - -// IAM policy for AWS Load Balancer Controller -resource "aws_iam_policy" "alb_policy" { - name = "AWSLoadBalancerControllerIAMPolicy" - policy = file("${path.module}/iam_policy.json") -} - -// Attachment of AWS Load Balancer Controller IAM policy to EKS cluster role -resource "aws_iam_role_policy_attachment" "alb_policy" { - policy_arn = aws_iam_policy.alb_policy.arn - role = aws_iam_role.eks_cluster_role.name -} - -// Attachment of AmazonEKS policies to EKS cluster role -resource "aws_iam_role_policy_attachment" "eks_cluster_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" - role = aws_iam_role.eks_cluster_role.name -} - -resource "aws_iam_role_policy_attachment" "eks_service_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" - role = aws_iam_role.eks_cluster_role.name -} - -// Attachment of AmazonEKSVPCResourceController policy to EKS cluster role -resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller_policy" { - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" - role = aws_iam_role.eks_cluster_role.name -} - -// Attachment of EKS cluster ELB service link policy to EKS cluster role -resource "aws_iam_role_policy_attachment" "eks_cluster_elb_service_link_policy_attachment" { - policy_arn = aws_iam_policy.eks_cluster_elb_service_link_policy.arn - role = aws_iam_role.eks_cluster_role.name -} - -################################################################################# -# Cloudwatch for the cluster -################################################################################# - -// CloudWatch log group for EKS cluster -resource "aws_cloudwatch_log_group" "eks_cluster_cloudwatch_log_group" { - count = length(var.eks_cluster_enabled_log_types) > 0 ? 1 : 0 - name = "/aws/eks/${var.cluster_prefix}-cluster" - retention_in_days = var.eks_cluster_log_retention_in_days - - // Tags for the CloudWatch log group - tags = { - Name = "${var.cluster_prefix}-cloudwatch" - Environment = "all-environments" - } -} +###################################################################################### +# EKS Cluster +###################################################################################### + +// AWS EKS Cluster resource definition +resource "aws_eks_cluster" "eks_cluster" { + name = "${var.cluster_prefix}-cluster" // Name of the EKS cluster + role_arn = aws_iam_role.eks_cluster_role.arn // IAM role ARN for the EKS cluster + version = var.kubernetes_version // Kubernetes version for the cluster + + // VPC configuration for the cluster + vpc_config { + subnet_ids = var.private_subnet_ids // Subnet IDs where EKS resources will be deployed + } + + // Kubernetes network configuration + kubernetes_network_config { + service_ipv4_cidr = var.eks_cluster_service_ipv4_cidr // CIDR block for Kubernetes service IPs + } + + // Timeouts configuration for create, delete, and update operations + timeouts { + create = var.eks_cluster_create_timeout + delete = var.eks_cluster_delete_timeout + update = var.eks_cluster_update_timeout + } + + // Dependencies on IAM resources and policies + depends_on = [ + aws_iam_role_policy_attachment.eks_cluster_policy, + aws_iam_role_policy_attachment.eks_vpc_resource_controller_policy, + aws_iam_role_policy_attachment.eks_cluster_elb_service_link_policy_attachment, + + aws_iam_role.eks_cluster_role, + aws_iam_policy.alb_policy, + aws_cloudwatch_log_group.eks_cluster_cloudwatch_log_group, + ] + + // Tags for the EKS cluster resource + tags = { + Name = "${var.cluster_prefix}-cluster" + Environment = "all-environment" + } +} + +################################################################################# +# Creating Role and Policies for the cluster +################################################################################# + +// IAM policy document for EKS cluster assume role policy +data "aws_iam_policy_document" "eks_cluster_assume_role_policy" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["eks.amazonaws.com"] + } + actions = [ + "sts:AssumeRole", + ] + } +} + +// IAM policy document for EKS cluster ELB service link role policy +data "aws_iam_policy_document" "eks_cluster_elb_service_link_role_policy" { + statement { + effect = "Allow" + actions = [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeInternetGateways", + "ec2:DescribeAddresses", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:*" + ] + resources = ["*"] + } +} + +// IAM role for EKS cluster +resource "aws_iam_role" "eks_cluster_role" { + name = "${var.cluster_prefix}-eks-cluster-role" + assume_role_policy = data.aws_iam_policy_document.eks_cluster_assume_role_policy.json +} + +// IAM policy for EKS cluster ELB service link +resource "aws_iam_policy" "eks_cluster_elb_service_link_policy" { + name = "${var.cluster_prefix}-eks-cluster-elb-service-link-policy" + policy = data.aws_iam_policy_document.eks_cluster_elb_service_link_role_policy.json +} + +// IAM policy for AWS Load Balancer Controller +resource "aws_iam_policy" "alb_policy" { + name = "AWSLoadBalancerControllerIAMPolicy" + policy = file("${path.module}/iam_policy.json") +} + +// Attachment of AWS Load Balancer Controller IAM policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "alb_policy" { + policy_arn = aws_iam_policy.alb_policy.arn + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of AmazonEKS policies to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_cluster_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" + role = aws_iam_role.eks_cluster_role.name +} + +resource "aws_iam_role_policy_attachment" "eks_service_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of AmazonEKSVPCResourceController policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller_policy" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" + role = aws_iam_role.eks_cluster_role.name +} + +// Attachment of EKS cluster ELB service link policy to EKS cluster role +resource "aws_iam_role_policy_attachment" "eks_cluster_elb_service_link_policy_attachment" { + policy_arn = aws_iam_policy.eks_cluster_elb_service_link_policy.arn + role = aws_iam_role.eks_cluster_role.name +} + +################################################################################# +# Cloudwatch for the cluster +################################################################################# + +// CloudWatch log group for EKS cluster +resource "aws_cloudwatch_log_group" "eks_cluster_cloudwatch_log_group" { + count = length(var.eks_cluster_enabled_log_types) > 0 ? 1 : 0 + name = "/aws/eks/${var.cluster_prefix}-cluster" + retention_in_days = var.eks_cluster_log_retention_in_days + + // Tags for the CloudWatch log group + tags = { + Name = "${var.cluster_prefix}-cloudwatch" + Environment = "all-environments" + } +} diff --git a/modules/eks/nodes/main.tf b/modules/eks/nodes/main.tf index f86bc27..f85e7e8 100644 --- a/modules/eks/nodes/main.tf +++ b/modules/eks/nodes/main.tf @@ -1,124 +1,124 @@ -################################################################################# -# VM Node Group -################################################################################# - -// AWS EKS Node Group resource -resource "aws_eks_node_group" "node_group" { - count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type - cluster_name = var.cluster_name // Name of the EKS cluster - node_group_name = "${var.cluster_prefix}-${var.node_environment}-node-group" // Name of the node group - node_role_arn = aws_iam_role.vm_node_group[0].arn // IAM role ARN for the node group - subnet_ids = var.subnet_ids // Subnet IDs for the node group instances - instance_types = var.instance_type // Instance types for the node group - disk_size = var.disk_size // Disk size for the node group instances - - // Scaling configuration for the node group - scaling_config { - desired_size = var.desired_size // Desired number of instances - max_size = var.max_size // Maximum number of instances - min_size = var.min_size // Minimum number of instances - } - - // Lifecycle configuration to ignore changes in desired_size - lifecycle { - ignore_changes = [scaling_config[0].desired_size] - } - - // Update configuration for the node group - update_config { - max_unavailable = 1 // Maximum number of unavailable instances during updates - } - - // Dependencies on IAM role policies before creating the node group - depends_on = [ - aws_iam_role.vm_node_group, - aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy[0], - aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy[0], - aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly[0], - ] -} - -// IAM role for VM Node Group -resource "aws_iam_role" "vm_node_group" { - count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type - name = "${var.cluster_prefix}-${var.node_environment}-vm-role" // Name of the IAM role - - // Assume role policy allowing EC2 instances to assume this role - assume_role_policy = jsonencode({ - Statement = [{ - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "ec2.amazonaws.com" - } - }] - Version = "2012-10-17" - }) -} - -// IAM role policy attachment for AmazonEKSWorkerNodePolicy -resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" { - count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" // ARN of the policy - role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to -} - -// IAM role policy attachment for AmazonEKS_CNI_Policy -resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" { - count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type - policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" // ARN of the policy - role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to -} - -// IAM role policy attachment for AmazonEC2ContainerRegistryReadOnly -resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" { - count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type - policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" // ARN of the policy - role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to -} - -################################################################################# -# Fargate Profile -################################################################################# - -// AWS EKS Fargate Profile resource -resource "aws_eks_fargate_profile" "fargate" { - count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type - cluster_name = var.cluster_name // Name of the EKS cluster - fargate_profile_name = "${var.cluster_prefix}-${var.node_environment}-fargate-profile" // Name of the Fargate profile - pod_execution_role_arn = aws_iam_role.fargate_iam[0].arn // IAM role ARN for Fargate pods - subnet_ids = var.subnet_ids // Subnet IDs for Fargate - - // Dynamic selector for Fargate profile - dynamic "selector" { - for_each = var.selector != null && length(var.selector) > 0 ? toset(var.selector) : [] // Selectors for namespaces - content { - namespace = selector.value // Namespace selector - } - } -} - -// IAM role for Fargate pods -resource "aws_iam_role" "fargate_iam" { - count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type - name = "${var.cluster_prefix}-${var.node_environment}-fargate-role" // Name of the IAM role - - // Assume role policy allowing EKS Fargate pods to assume this role - assume_role_policy = jsonencode({ - Statement = [{ - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "eks-fargate-pods.amazonaws.com" - } - }] - Version = "2012-10-17" - }) -} - -// IAM role policy attachment for AmazonEKSFargatePodExecutionRolePolicy -resource "aws_iam_role_policy_attachment" "AmazonEKSFargatePodExecutionRolePolicy" { - count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type - policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" // ARN of the policy - role = aws_iam_role.fargate_iam[0].name // Name of the IAM role to attach the policy to -} +################################################################################# +# VM Node Group +################################################################################# + +// AWS EKS Node Group resource +resource "aws_eks_node_group" "node_group" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + cluster_name = var.cluster_name // Name of the EKS cluster + node_group_name = "${var.cluster_prefix}-${var.node_environment}-node-group" // Name of the node group + node_role_arn = aws_iam_role.vm_node_group[0].arn // IAM role ARN for the node group + subnet_ids = var.subnet_ids // Subnet IDs for the node group instances + instance_types = var.instance_type // Instance types for the node group + disk_size = var.disk_size // Disk size for the node group instances + + // Scaling configuration for the node group + scaling_config { + desired_size = var.desired_size // Desired number of instances + max_size = var.max_size // Maximum number of instances + min_size = var.min_size // Minimum number of instances + } + + // Lifecycle configuration to ignore changes in desired_size + # lifecycle { + # ignore_changes = [scaling_config[0].desired_size] + # } + + // Update configuration for the node group + update_config { + max_unavailable = 1 // Maximum number of unavailable instances during updates + } + + // Dependencies on IAM role policies before creating the node group + depends_on = [ + aws_iam_role.vm_node_group, + aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy[0], + aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy[0], + aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly[0], + ] +} + +// IAM role for VM Node Group +resource "aws_iam_role" "vm_node_group" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + name = "${var.cluster_prefix}-${var.node_environment}-vm-role" // Name of the IAM role + + // Assume role policy allowing EC2 instances to assume this role + assume_role_policy = jsonencode({ + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "ec2.amazonaws.com" + } + }] + Version = "2012-10-17" + }) +} + +// IAM role policy attachment for AmazonEKSWorkerNodePolicy +resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +// IAM role policy attachment for AmazonEKS_CNI_Policy +resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +// IAM role policy attachment for AmazonEC2ContainerRegistryReadOnly +resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" { + count = var.node_type == "vm" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" // ARN of the policy + role = aws_iam_role.vm_node_group[0].name // Name of the IAM role to attach the policy to +} + +################################################################################# +# Fargate Profile +################################################################################# + +// AWS EKS Fargate Profile resource +resource "aws_eks_fargate_profile" "fargate" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + cluster_name = var.cluster_name // Name of the EKS cluster + fargate_profile_name = "${var.cluster_prefix}-${var.node_environment}-fargate-profile" // Name of the Fargate profile + pod_execution_role_arn = aws_iam_role.fargate_iam[0].arn // IAM role ARN for Fargate pods + subnet_ids = var.subnet_ids // Subnet IDs for Fargate + + // Dynamic selector for Fargate profile + dynamic "selector" { + for_each = var.selector != null && length(var.selector) > 0 ? toset(var.selector) : [] // Selectors for namespaces + content { + namespace = selector.value // Namespace selector + } + } +} + +// IAM role for Fargate pods +resource "aws_iam_role" "fargate_iam" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + name = "${var.cluster_prefix}-${var.node_environment}-fargate-role" // Name of the IAM role + + // Assume role policy allowing EKS Fargate pods to assume this role + assume_role_policy = jsonencode({ + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "eks-fargate-pods.amazonaws.com" + } + }] + Version = "2012-10-17" + }) +} + +// IAM role policy attachment for AmazonEKSFargatePodExecutionRolePolicy +resource "aws_iam_role_policy_attachment" "AmazonEKSFargatePodExecutionRolePolicy" { + count = var.node_type == "fargate" ? 1 : 0 // Conditional creation based on node_type + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" // ARN of the policy + role = aws_iam_role.fargate_iam[0].name // Name of the IAM role to attach the policy to +} diff --git a/modules/eks/nodes/variables.tf b/modules/eks/nodes/variables.tf index 01b6422..57cdcc8 100644 --- a/modules/eks/nodes/variables.tf +++ b/modules/eks/nodes/variables.tf @@ -1,67 +1,67 @@ -################################################################################# -# Variables -################################################################################# - - -// Prefix used in naming resources within the EKS cluster -variable "cluster_prefix" { - type = string -} - -// Name of the EKS cluster -variable "cluster_name" { - type = string -} - -// List of subnet IDs where EKS resources (nodes or Fargate profiles) will be deployed -variable "subnet_ids" { - type = list(string) -} - -// Desired number of instances in the node group (default: 1) -variable "desired_size" { - type = number - default = 1 -} - -// Maximum number of instances in the node group (default: 1) -variable "max_size" { - type = number - default = 1 -} - -// Minimum number of instances in the node group (default: 1) -variable "min_size" { - type = number - default = 1 -} - -// List of instance types for nodes in the node group (default: ["t3.medium"]) -variable "instance_type" { - type = list(string) - default = ["t3.medium"] -} - -// Environment identifier used in naming resources within the cluster -variable "node_environment" { - type = string -} - -// Size of the disk attached to each instance in the node group (default: "30" GB) -variable "disk_size" { - type = string - default = "30" -} - -// Type of the node group to create. Possible values are 'fargate' or 'vm'. -variable "node_type" { - description = "Type of the node group to create. Possible values are 'fargate' or 'vm'." - type = string - default = "vm" -} - -// List of namespaces for Fargate profile selectors (optional) -variable "selector" { - description = "List of namespaces for Fargate profile selectors." - type = list(string) -} +################################################################################# +# Variables +################################################################################# + + +// Prefix used in naming resources within the EKS cluster +variable "cluster_prefix" { + type = string +} + +// Name of the EKS cluster +variable "cluster_name" { + type = string +} + +// List of subnet IDs where EKS resources (nodes or Fargate profiles) will be deployed +variable "subnet_ids" { + type = list(string) +} + +// Desired number of instances in the node group (default: 1) +variable "desired_size" { + type = number + default = 1 +} + +// Maximum number of instances in the node group (default: 1) +variable "max_size" { + type = number + default = 1 +} + +// Minimum number of instances in the node group (default: 1) +variable "min_size" { + type = number + default = 1 +} + +// List of instance types for nodes in the node group (default: ["t3.medium"]) +variable "instance_type" { + type = list(string) + default = ["t3.medium"] +} + +// Environment identifier used in naming resources within the cluster +variable "node_environment" { + type = string +} + +// Size of the disk attached to each instance in the node group (default: "30" GB) +variable "disk_size" { + type = string + default = "30" +} + +// Type of the node group to create. Possible values are 'fargate' or 'vm'. +variable "node_type" { + description = "Type of the node group to create. Possible values are 'fargate' or 'vm'." + type = string + default = "vm" +} + +// List of namespaces for Fargate profile selectors (optional) +variable "selector" { + description = "List of namespaces for Fargate profile selectors." + type = list(string) +} diff --git a/modules/eks/output.tf b/modules/eks/output.tf index 4f6847a..fc5791f 100644 --- a/modules/eks/output.tf +++ b/modules/eks/output.tf @@ -1,16 +1,16 @@ -###################################################################################### -# Outputs for the KS Modules -###################################################################################### - - -// Output: Cluster Endpoint -output "cluster_endpoint" { - description = "Endpoint for EKS control plane" - value = aws_eks_cluster.eks_cluster.endpoint -} - -// Output: Cluster Name -output "cluster_name" { - description = "Kubernetes Cluster Name" - value = aws_eks_cluster.eks_cluster.name -} +###################################################################################### +# Outputs for the KS Modules +###################################################################################### + + +// Output: Cluster Endpoint +output "cluster_endpoint" { + description = "Endpoint for EKS control plane" + value = aws_eks_cluster.eks_cluster.endpoint +} + +// Output: Cluster Name +output "cluster_name" { + description = "Kubernetes Cluster Name" + value = aws_eks_cluster.eks_cluster.name +} diff --git a/modules/eks/variables.tf b/modules/eks/variables.tf index 473123b..5f85ada 100644 --- a/modules/eks/variables.tf +++ b/modules/eks/variables.tf @@ -1,63 +1,63 @@ -###################################################################################### -# Variable for the Eks Modules -###################################################################################### - -// Prefix used to apply generic naming to the EKS Cluster -variable "cluster_prefix" { - description = "To apply generic naming to EKS Cluster" - type = string -} - -// Kubernetes version for the EKS Cluster -variable "kubernetes_version" { - description = "Kubernetes version for EKS Cluster" - type = string - default = "1.29" -} - -// List of Control Plane Logging options to enable -variable "eks_cluster_enabled_log_types" { - description = "List of Control Plane Logging options to enable" - type = list(any) - default = ["api", "audit"] -} - -// CloudWatch log events retention period in days for EKS Cluster -variable "eks_cluster_log_retention_in_days" { - description = "Cloudwatch log events retention period in days for EKS Cluster" - type = number - default = 7 -} - -// EKS Cluster - Kubernetes Service IP address range -variable "eks_cluster_service_ipv4_cidr" { - description = "EKS Cluster - Kubernetes Service IP address range" - type = string - default = "10.43.0.0/16" -} - -// Average wait time in minutes for the EKS Cluster to be created -variable "eks_cluster_create_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be created" - type = string - default = "30m" -} - -// Average wait time in minutes for the EKS Cluster to be deleted -variable "eks_cluster_delete_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be deleted" - type = string - default = "15m" -} - -// Average wait time in minutes for the EKS Cluster to be updated -variable "eks_cluster_update_timeout" { - description = "Average wait time in minutes for the EKS Cluster to be updated" - type = string - default = "60m" -} - -// List of private subnet IDs where EKS resources will be deployed -variable "private_subnet_ids" { - type = list(string) -} +###################################################################################### +# Variable for the Eks Modules +###################################################################################### + +// Prefix used to apply generic naming to the EKS Cluster +variable "cluster_prefix" { + description = "To apply generic naming to EKS Cluster" + type = string +} + +// Kubernetes version for the EKS Cluster +variable "kubernetes_version" { + description = "Kubernetes version for EKS Cluster" + type = string + default = "1.29" +} + +// List of Control Plane Logging options to enable +variable "eks_cluster_enabled_log_types" { + description = "List of Control Plane Logging options to enable" + type = list(any) + default = ["api", "audit"] +} + +// CloudWatch log events retention period in days for EKS Cluster +variable "eks_cluster_log_retention_in_days" { + description = "Cloudwatch log events retention period in days for EKS Cluster" + type = number + default = 7 +} + +// EKS Cluster - Kubernetes Service IP address range +variable "eks_cluster_service_ipv4_cidr" { + description = "EKS Cluster - Kubernetes Service IP address range" + type = string + default = "10.43.0.0/16" +} + +// Average wait time in minutes for the EKS Cluster to be created +variable "eks_cluster_create_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be created" + type = string + default = "30m" +} + +// Average wait time in minutes for the EKS Cluster to be deleted +variable "eks_cluster_delete_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be deleted" + type = string + default = "15m" +} + +// Average wait time in minutes for the EKS Cluster to be updated +variable "eks_cluster_update_timeout" { + description = "Average wait time in minutes for the EKS Cluster to be updated" + type = string + default = "60m" +} + +// List of private subnet IDs where EKS resources will be deployed +variable "private_subnet_ids" { + type = list(string) +} diff --git a/modules/rds/main.tf b/modules/rds/main.tf index e7d341e..61556d9 100644 --- a/modules/rds/main.tf +++ b/modules/rds/main.tf @@ -1,75 +1,75 @@ -# KMS Key for RDS -resource "aws_kms_key" "kms" { - description = "KMS key for RDS" -} - -data "aws_rds_engine_version" "current" { - engine = var.db_engine - version = var.db_version -} - - -# Security group for RDS instance -resource "aws_security_group" "rds_sg" { - name_prefix = "${var.cluster_prefix}-${var.db_environment}-rds-sg" - description = "Security group for RDS instance" - vpc_id = var.vpc_id - - ingress { - from_port = var.db_port - to_port = var.db_port - protocol = "tcp" - cidr_blocks = var.allowed_ip # Consider restricting this to your IP range or VPC - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "${var.cluster_prefix}-${var.db_environment}-rds-sg" - } -} - -# Subnet group for RDS instance -resource "aws_db_subnet_group" "subnet_group" { - name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" - subnet_ids = var.subnet_ids - description = "Subnet group for RDS instance" - - tags = { - Name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" - } - depends_on = [ - aws_security_group.rds_sg - ] -} - -# RDS instance -resource "aws_db_instance" "db_instance" { - allocated_storage = var.db_storage - # identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" - identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" - db_name = var.db_name - engine = var.db_engine - engine_version = var.db_version - instance_class = var.db_instance_class - - vpc_security_group_ids = [aws_security_group.rds_sg.id] - db_subnet_group_name = aws_db_subnet_group.subnet_group.name - - # manage_master_user_password = true - # master_user_secret_kms_key_id = aws_kms_key.kms.key_id - username = var.db_username - password = var.db_password - skip_final_snapshot = true - delete_automated_backups = true - - tags = { - Name = "${var.cluster_prefix}-${var.db_environment}-db" - } - depends_on = [ aws_db_subnet_group.subnet_group, aws_security_group.rds_sg ] -} +# KMS Key for RDS +resource "aws_kms_key" "kms" { + description = "KMS key for RDS" +} + +data "aws_rds_engine_version" "current" { + engine = var.db_engine + version = var.db_version +} + + +# Security group for RDS instance +resource "aws_security_group" "rds_sg" { + name_prefix = "${var.cluster_prefix}-${var.db_environment}-rds-sg" + description = "Security group for RDS instance" + vpc_id = var.vpc_id + + ingress { + from_port = var.db_port + to_port = var.db_port + protocol = "tcp" + cidr_blocks = var.allowed_ip # Consider restricting this to your IP range or VPC + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-rds-sg" + } +} + +# Subnet group for RDS instance +resource "aws_db_subnet_group" "subnet_group" { + name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" + subnet_ids = var.subnet_ids + description = "Subnet group for RDS instance" + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-rds-sng" + } + depends_on = [ + aws_security_group.rds_sg + ] +} + +# RDS instance +resource "aws_db_instance" "db_instance" { + allocated_storage = var.db_storage + # identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" + identifier = "${lower(var.cluster_prefix)}-${lower(var.db_environment)}-db" + db_name = var.db_name + engine = var.db_engine + engine_version = var.db_version + instance_class = var.db_instance_class + + vpc_security_group_ids = [aws_security_group.rds_sg.id] + db_subnet_group_name = aws_db_subnet_group.subnet_group.name + + # manage_master_user_password = true + # master_user_secret_kms_key_id = aws_kms_key.kms.key_id + username = var.db_username + password = var.db_password + skip_final_snapshot = true + delete_automated_backups = true + + tags = { + Name = "${var.cluster_prefix}-${var.db_environment}-db" + } + depends_on = [ aws_db_subnet_group.subnet_group, aws_security_group.rds_sg ] +} diff --git a/modules/rds/outputs.tf b/modules/rds/outputs.tf index 995d296..aee4a99 100644 --- a/modules/rds/outputs.tf +++ b/modules/rds/outputs.tf @@ -1,24 +1,24 @@ -############################################################################## -# Outputs -############################################################################# - -# Output: Database Instance Endpoint -# The endpoint address of the RDS instance -output "db_instance_endpoint" { - description = "The endpoint address of the RDS instance" - value = aws_db_instance.db_instance.endpoint -} - -# Output: Database Instance ID -# The unique identifier of the RDS instance -output "db_instance_id" { - description = "The unique identifier of the RDS instance" - value = aws_db_instance.db_instance.id -} - -# Output: RDS Security Group ID -# The ID of the security group associated with the RDS instance -output "rds_security_group_id" { - description = "The ID of the security group associated with the RDS instance" - value = aws_security_group.rds_sg.id -} +############################################################################## +# Outputs +############################################################################# + +# Output: Database Instance Endpoint +# The endpoint address of the RDS instance +output "db_instance_endpoint" { + description = "The endpoint address of the RDS instance" + value = aws_db_instance.db_instance.endpoint +} + +# Output: Database Instance ID +# The unique identifier of the RDS instance +output "db_instance_id" { + description = "The unique identifier of the RDS instance" + value = aws_db_instance.db_instance.id +} + +# Output: RDS Security Group ID +# The ID of the security group associated with the RDS instance +output "rds_security_group_id" { + description = "The ID of the security group associated with the RDS instance" + value = aws_security_group.rds_sg.id +} diff --git a/modules/rds/variables.tf b/modules/rds/variables.tf index faab1dd..07391a9 100644 --- a/modules/rds/variables.tf +++ b/modules/rds/variables.tf @@ -1,85 +1,85 @@ -############################################################################## -# Outputs -############################################################################# - -# Variable Definitions - -# Prefix for naming resources -variable "cluster_prefix" { - description = "Prefix for naming resources" - type = string -} - -# Storage size for the database -variable "db_storage" { - description = "Allocated storage size for the RDS instance in GB" - type = number -} - -# Environment for the database (e.g., dev, prod) -variable "db_environment" { - description = "Environment for the database (e.g., dev, prod)" - type = string -} - -# Database engine type (e.g., postgres, mysql) -variable "db_engine" { - description = "Type of the database engine (e.g., postgres, mysql)" - type = string -} - -# Instance class for the database -variable "db_instance_class" { - description = "Instance class for the RDS database instance" - type = string -} - -# Port for the database -variable "db_port" { - description = "Port number on which the database accepts connections. Defaults to 5432 for PostgreSQL" - type = string - default = "5432" -} - -# Allowed IP addresses for database access -variable "allowed_ip" { - description = "List of allowed IP addresses for database access" - type = list(string) - default = ["0.0.0.0/0"] -} - -# Version of the database engine -variable "db_version" { - description = "Version of the database engine" - type = string -} - -# Name of the database -variable "db_name" { - description = "Name of the database" - type = string -} - -# Username for the database -variable "db_username" { - description = "Username for the database" - type = string -} - -# Password for the database -variable "db_password" { - description = "Password for the database" - type = string -} - -# List of subnet IDs for the database -variable "subnet_ids" { - description = "List of subnet IDs for the RDS instance" - type = list(string) -} - -# ID of the VPC -variable "vpc_id" { - description = "ID of the VPC" - type = string -} +############################################################################## +# Outputs +############################################################################# + +# Variable Definitions + +# Prefix for naming resources +variable "cluster_prefix" { + description = "Prefix for naming resources" + type = string +} + +# Storage size for the database +variable "db_storage" { + description = "Allocated storage size for the RDS instance in GB" + type = number +} + +# Environment for the database (e.g., dev, prod) +variable "db_environment" { + description = "Environment for the database (e.g., dev, prod)" + type = string +} + +# Database engine type (e.g., postgres, mysql) +variable "db_engine" { + description = "Type of the database engine (e.g., postgres, mysql)" + type = string +} + +# Instance class for the database +variable "db_instance_class" { + description = "Instance class for the RDS database instance" + type = string +} + +# Port for the database +variable "db_port" { + description = "Port number on which the database accepts connections. Defaults to 5432 for PostgreSQL" + type = string + default = "5432" +} + +# Allowed IP addresses for database access +variable "allowed_ip" { + description = "List of allowed IP addresses for database access" + type = list(string) + default = ["0.0.0.0/0"] +} + +# Version of the database engine +variable "db_version" { + description = "Version of the database engine" + type = string +} + +# Name of the database +variable "db_name" { + description = "Name of the database" + type = string +} + +# Username for the database +variable "db_username" { + description = "Username for the database" + type = string +} + +# Password for the database +variable "db_password" { + description = "Password for the database" + type = string +} + +# List of subnet IDs for the database +variable "subnet_ids" { + description = "List of subnet IDs for the RDS instance" + type = list(string) +} + +# ID of the VPC +variable "vpc_id" { + description = "ID of the VPC" + type = string +} diff --git a/modules/vpc/gateway/main.tf b/modules/vpc/gateway/main.tf index 9e2914d..82f20e5 100644 --- a/modules/vpc/gateway/main.tf +++ b/modules/vpc/gateway/main.tf @@ -1,46 +1,46 @@ -####################################################### -# Internet Gateway -####################################################### - -# Resource: aws_internet_gateway.this -# Description: Creates an Internet Gateway if gateway_type is "internet" to provide internet access to public subnets. -resource "aws_internet_gateway" "this" { - count = var.gateway_type == "internet" ? 1 : 0 - - vpc_id = var.vpc_id - - tags = { - Name = "${var.cluster_prefix}-${var.gateway_type}-gateway" - } -} - -####################################################### -# Elastic IP (EIP) -####################################################### - -# Resource: aws_eip.nat -# Description: Creates an Elastic IP (EIP) if gateway_type is "nat" to associate with a NAT Gateway. -resource "aws_eip" "nat" { - count = var.gateway_type == "nat" ? 1 : 0 - - tags = { - Name = "${var.cluster_prefix}-eip" - } -} - -####################################################### -# NAT Gateway -####################################################### - -# Resource: aws_nat_gateway.this -# Description: Creates a NAT Gateway if gateway_type is "nat" to allow private subnet instances to access the internet. -resource "aws_nat_gateway" "this" { - count = var.gateway_type == "nat" ? 1 : 0 - - allocation_id = aws_eip.nat[0].id - subnet_id = var.subnet_id - - tags = { - Name = "${var.cluster_prefix}-nat-gateway" - } -} +####################################################### +# Internet Gateway +####################################################### + +# Resource: aws_internet_gateway.this +# Description: Creates an Internet Gateway if gateway_type is "internet" to provide internet access to public subnets. +resource "aws_internet_gateway" "this" { + count = var.gateway_type == "internet" ? 1 : 0 + + vpc_id = var.vpc_id + + tags = { + Name = "${var.cluster_prefix}-${var.gateway_type}-gateway" + } +} + +####################################################### +# Elastic IP (EIP) +####################################################### + +# Resource: aws_eip.nat +# Description: Creates an Elastic IP (EIP) if gateway_type is "nat" to associate with a NAT Gateway. +resource "aws_eip" "nat" { + count = var.gateway_type == "nat" ? 1 : 0 + + tags = { + Name = "${var.cluster_prefix}-eip" + } +} + +####################################################### +# NAT Gateway +####################################################### + +# Resource: aws_nat_gateway.this +# Description: Creates a NAT Gateway if gateway_type is "nat" to allow private subnet instances to access the internet. +resource "aws_nat_gateway" "this" { + count = var.gateway_type == "nat" ? 1 : 0 + + allocation_id = aws_eip.nat[0].id + subnet_id = var.subnet_id + + tags = { + Name = "${var.cluster_prefix}-nat-gateway" + } +} diff --git a/modules/vpc/gateway/outputs.tf b/modules/vpc/gateway/outputs.tf index ea0e464..9fb1e8a 100644 --- a/modules/vpc/gateway/outputs.tf +++ b/modules/vpc/gateway/outputs.tf @@ -1,24 +1,24 @@ -####################################################### -# Outputs -####################################################### - -# Output: internet_gateway_id -# Description: The ID of the Internet Gateway if gateway_type is "internet", otherwise null. -output "internet_gateway_id" { - description = "The ID of the Internet Gateway" - value = var.gateway_type == "internet" ? aws_internet_gateway.this[0].id : null -} - -# Output: nat_gateway_id -# Description: The ID of the NAT Gateway if gateway_type is "nat", otherwise null. -output "nat_gateway_id" { - description = "The ID of the NAT Gateway" - value = var.gateway_type == "nat" ? aws_nat_gateway.this[0].id : null -} - -# Output: nat_gateway_eip -# Description: The Elastic IP of the NAT Gateway if gateway_type is "nat", otherwise null. -output "nat_gateway_eip" { - description = "The Elastic IP of the NAT Gateway" - value = var.gateway_type == "nat" ? aws_eip.nat[0].public_ip : null -} +####################################################### +# Outputs +####################################################### + +# Output: internet_gateway_id +# Description: The ID of the Internet Gateway if gateway_type is "internet", otherwise null. +output "internet_gateway_id" { + description = "The ID of the Internet Gateway" + value = var.gateway_type == "internet" ? aws_internet_gateway.this[0].id : null +} + +# Output: nat_gateway_id +# Description: The ID of the NAT Gateway if gateway_type is "nat", otherwise null. +output "nat_gateway_id" { + description = "The ID of the NAT Gateway" + value = var.gateway_type == "nat" ? aws_nat_gateway.this[0].id : null +} + +# Output: nat_gateway_eip +# Description: The Elastic IP of the NAT Gateway if gateway_type is "nat", otherwise null. +output "nat_gateway_eip" { + description = "The Elastic IP of the NAT Gateway" + value = var.gateway_type == "nat" ? aws_eip.nat[0].public_ip : null +} diff --git a/modules/vpc/gateway/variables.tf b/modules/vpc/gateway/variables.tf index cfc14c4..4875ae6 100644 --- a/modules/vpc/gateway/variables.tf +++ b/modules/vpc/gateway/variables.tf @@ -1,43 +1,43 @@ -####################################################### -# Variables -####################################################### - -# Variable: cluster_prefix -# Description: Prefix to apply generic naming to resources like VPC and subnets -variable "cluster_prefix" { - type = string -} - -# Variable: vpc_id -# Description: The ID of the VPC where the gateway will be attached -variable "vpc_id" { - description = "The ID of the VPC" - type = string -} - -# Variable: gateway_type -# Description: Type of gateway to create: 'nat' for NAT Gateway or 'internet' for Internet Gateway -variable "gateway_type" { - description = "Type of gateway: nat or internet" - type = string - validation { - condition = contains(["nat", "internet"], var.gateway_type) - error_message = "gateway_type must be either 'nat' or 'internet'." - } -} - -# Variable: subnet_id -# Description: The ID of the subnet in which to place the NAT Gateway (required if gateway_type is 'nat') -variable "subnet_id" { - description = "The ID of the subnet in which to place the NAT Gateway (required if NAT Gateway)" - type = string - default = null -} - -# Variable: tags -# Description: Tags to assign to the gateway -variable "tags" { - description = "Tags to assign to the gateway" - type = map(string) - default = {} -} +####################################################### +# Variables +####################################################### + +# Variable: cluster_prefix +# Description: Prefix to apply generic naming to resources like VPC and subnets +variable "cluster_prefix" { + type = string +} + +# Variable: vpc_id +# Description: The ID of the VPC where the gateway will be attached +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# Variable: gateway_type +# Description: Type of gateway to create: 'nat' for NAT Gateway or 'internet' for Internet Gateway +variable "gateway_type" { + description = "Type of gateway: nat or internet" + type = string + validation { + condition = contains(["nat", "internet"], var.gateway_type) + error_message = "gateway_type must be either 'nat' or 'internet'." + } +} + +# Variable: subnet_id +# Description: The ID of the subnet in which to place the NAT Gateway (required if gateway_type is 'nat') +variable "subnet_id" { + description = "The ID of the subnet in which to place the NAT Gateway (required if NAT Gateway)" + type = string + default = null +} + +# Variable: tags +# Description: Tags to assign to the gateway +variable "tags" { + description = "Tags to assign to the gateway" + type = map(string) + default = {} +} diff --git a/modules/vpc/main.tf b/modules/vpc/main.tf index 343266a..2b1d018 100644 --- a/modules/vpc/main.tf +++ b/modules/vpc/main.tf @@ -1,104 +1,104 @@ -####################################################### -# VPC and Subnets -####################################################### - -# Create a VPC with DNS support and hostnames enabled -resource "aws_vpc" "vpc" { - cidr_block = var.cidr - enable_dns_support = true - enable_dns_hostnames = true - - tags = { - Name = "${var.cluster_prefix}-vpc" - } -} - -# Create public subnets -module "public_subnets" { - - source = "./subnet" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_type = "public" - cidr = var.cidr - subnet_bits = var.subnet_bits - offset = 0 -} - -# Create private subnets -module "private_subnets" { - - source = "./subnet" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_type = "private" - cidr = var.cidr - subnet_bits = var.subnet_bits - offset = 1 -} - -# Create storage subnets -module "storage_subnets" { - source = "./subnet" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_type = "storage" - cidr = var.cidr - subnet_bits = var.subnet_bits - offset = 2 -} - -####################################################### -# Gateways -####################################################### - -# Create an Internet Gateway for the public subnets -module "internet_gateway" { - source = "./gateway" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - gateway_type = "internet" -} - -# Create a NAT Gateway for the private and storage subnets -module "nat_gateway" { - source = "./gateway" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - gateway_type = "nat" - subnet_id = module.public_subnets.subnet_ids[0] -} - -####################################################### -# Route Tables -####################################################### - -# Create a public route table and associate it with public subnets -module "public_route_table" { - source = "./route_table" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_ids = module.public_subnets.subnet_ids - route_table_type = "public" - internet_gateway_id = module.internet_gateway.internet_gateway_id -} - -# Create a private route table and associate it with private subnets -module "private_route_table" { - source = "./route_table" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_ids = module.private_subnets.subnet_ids - route_table_type = "private" - nat_gateway_id = module.nat_gateway.nat_gateway_id -} - -# Create a storage route table and associate it with storage subnets -module "storage_route_table" { - source = "./route_table" - cluster_prefix = var.cluster_prefix - vpc_id = aws_vpc.vpc.id - subnet_ids = module.storage_subnets.subnet_ids - route_table_type = "private" - nat_gateway_id = module.nat_gateway.nat_gateway_id -} +####################################################### +# VPC and Subnets +####################################################### + +# Create a VPC with DNS support and hostnames enabled +resource "aws_vpc" "vpc" { + cidr_block = var.cidr + enable_dns_support = true + enable_dns_hostnames = true + + tags = { + Name = "${var.cluster_prefix}-vpc" + } +} + +# Create public subnets +module "public_subnets" { + + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "public" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 0 +} + +# Create private subnets +module "private_subnets" { + + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "private" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 1 +} + +# Create storage subnets +module "storage_subnets" { + source = "./subnet" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_type = "storage" + cidr = var.cidr + subnet_bits = var.subnet_bits + offset = 2 +} + +####################################################### +# Gateways +####################################################### + +# Create an Internet Gateway for the public subnets +module "internet_gateway" { + source = "./gateway" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + gateway_type = "internet" +} + +# Create a NAT Gateway for the private and storage subnets +module "nat_gateway" { + source = "./gateway" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + gateway_type = "nat" + subnet_id = module.public_subnets.subnet_ids[0] +} + +####################################################### +# Route Tables +####################################################### + +# Create a public route table and associate it with public subnets +module "public_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.public_subnets.subnet_ids + route_table_type = "public" + internet_gateway_id = module.internet_gateway.internet_gateway_id +} + +# Create a private route table and associate it with private subnets +module "private_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.private_subnets.subnet_ids + route_table_type = "private" + nat_gateway_id = module.nat_gateway.nat_gateway_id +} + +# Create a storage route table and associate it with storage subnets +module "storage_route_table" { + source = "./route_table" + cluster_prefix = var.cluster_prefix + vpc_id = aws_vpc.vpc.id + subnet_ids = module.storage_subnets.subnet_ids + route_table_type = "private" + nat_gateway_id = module.nat_gateway.nat_gateway_id +} diff --git a/modules/vpc/output.tf b/modules/vpc/output.tf index 177624b..cb7390d 100644 --- a/modules/vpc/output.tf +++ b/modules/vpc/output.tf @@ -1,38 +1,38 @@ -####################################################### -# Outputs -####################################################### - -# Output: VPC ID -# The ID of the created VPC -output "vpc_id" { - description = "The ID of the created VPC" - value = aws_vpc.vpc.id -} - -# Output: Public Subnet IDs -# List of IDs of the created public subnets -output "public_subnets_ids" { - description = "List of IDs of the created public subnets" - value = module.public_subnets.subnet_ids -} - -# Output: Private Subnet IDs -# List of IDs of the created private subnets -output "private_subnet_ids" { - description = "List of IDs of the created private subnets" - value = module.private_subnets.subnet_ids -} - -# Output: Storage Subnet IDs -# List of IDs of the created storage subnets -output "storage_subnet_ids" { - description = "List of IDs of the created storage subnets" - value = module.storage_subnets.subnet_ids -} - -# Output: Internet Gateway ID -# The ID of the created Internet Gateway -output "internet_gateway_id" { - description = "The ID of the created Internet Gateway" - value = module.internet_gateway.internet_gateway_id -} +####################################################### +# Outputs +####################################################### + +# Output: VPC ID +# The ID of the created VPC +output "vpc_id" { + description = "The ID of the created VPC" + value = aws_vpc.vpc.id +} + +# Output: Public Subnet IDs +# List of IDs of the created public subnets +output "public_subnets_ids" { + description = "List of IDs of the created public subnets" + value = module.public_subnets.subnet_ids +} + +# Output: Private Subnet IDs +# List of IDs of the created private subnets +output "private_subnet_ids" { + description = "List of IDs of the created private subnets" + value = module.private_subnets.subnet_ids +} + +# Output: Storage Subnet IDs +# List of IDs of the created storage subnets +output "storage_subnet_ids" { + description = "List of IDs of the created storage subnets" + value = module.storage_subnets.subnet_ids +} + +# Output: Internet Gateway ID +# The ID of the created Internet Gateway +output "internet_gateway_id" { + description = "The ID of the created Internet Gateway" + value = module.internet_gateway.internet_gateway_id +} diff --git a/modules/vpc/route_table/main.tf b/modules/vpc/route_table/main.tf index eda25e3..13cbda0 100644 --- a/modules/vpc/route_table/main.tf +++ b/modules/vpc/route_table/main.tf @@ -1,43 +1,43 @@ -####################################################### -# Route Tables -####################################################### - -# Resource: aws_route_table -# Description: Manages a route table for a VPC. -resource "aws_route_table" "this" { - vpc_id = var.vpc_id - - # Dynamic Block: route (Public Route) - # Description: Defines a route for the public subnet(s) to route traffic via an Internet Gateway. - dynamic "route" { - for_each = var.route_table_type == "public" ? [1] : [] - content { - cidr_block = "0.0.0.0/0" - gateway_id = var.internet_gateway_id - } - } - - # Dynamic Block: route (Private Route) - # Description: Defines a route for the private subnet(s) to route traffic via a NAT Gateway. - dynamic "route" { - for_each = var.route_table_type == "private" ? [1] : [] - content { - cidr_block = "0.0.0.0/0" - nat_gateway_id = var.nat_gateway_id - } - } - - # Tags: Name - # Description: Tags the route table with a name based on the cluster prefix and route table type. - tags = { - Name = "${var.cluster_prefix}-${var.route_table_type}-rt" - } -} - -# Resource: aws_route_table_association -# Description: Associates subnet(s) with the specified route table. -resource "aws_route_table_association" "this" { - count = length(var.subnet_ids) - subnet_id = element(var.subnet_ids, count.index) - route_table_id = aws_route_table.this.id -} +####################################################### +# Route Tables +####################################################### + +# Resource: aws_route_table +# Description: Manages a route table for a VPC. +resource "aws_route_table" "this" { + vpc_id = var.vpc_id + + # Dynamic Block: route (Public Route) + # Description: Defines a route for the public subnet(s) to route traffic via an Internet Gateway. + dynamic "route" { + for_each = var.route_table_type == "public" ? [1] : [] + content { + cidr_block = "0.0.0.0/0" + gateway_id = var.internet_gateway_id + } + } + + # Dynamic Block: route (Private Route) + # Description: Defines a route for the private subnet(s) to route traffic via a NAT Gateway. + dynamic "route" { + for_each = var.route_table_type == "private" ? [1] : [] + content { + cidr_block = "0.0.0.0/0" + nat_gateway_id = var.nat_gateway_id + } + } + + # Tags: Name + # Description: Tags the route table with a name based on the cluster prefix and route table type. + tags = { + Name = "${var.cluster_prefix}-${var.route_table_type}-rt" + } +} + +# Resource: aws_route_table_association +# Description: Associates subnet(s) with the specified route table. +resource "aws_route_table_association" "this" { + count = length(var.subnet_ids) + subnet_id = element(var.subnet_ids, count.index) + route_table_id = aws_route_table.this.id +} diff --git a/modules/vpc/route_table/outputs.tf b/modules/vpc/route_table/outputs.tf index ec429fd..00c2950 100644 --- a/modules/vpc/route_table/outputs.tf +++ b/modules/vpc/route_table/outputs.tf @@ -1,10 +1,10 @@ -####################################################### -# Outputs -####################################################### - -# Output: route_table_id -# Description: Provides the ID of the created route table. -output "route_table_id" { - description = "The ID of the route table" - value = aws_route_table.this.id -} +####################################################### +# Outputs +####################################################### + +# Output: route_table_id +# Description: Provides the ID of the created route table. +output "route_table_id" { + description = "The ID of the route table" + value = aws_route_table.this.id +} diff --git a/modules/vpc/route_table/variables.tf b/modules/vpc/route_table/variables.tf index 272e84a..1f985cd 100644 --- a/modules/vpc/route_table/variables.tf +++ b/modules/vpc/route_table/variables.tf @@ -1,47 +1,47 @@ -####################################################### -# Variablesw -####################################################### - -# Variable Definitions - -# The ID of the VPC -variable "vpc_id" { - description = "The ID of the VPC" - type = string -} - -# The ID of the Internet Gateway (required if route table type is public) -variable "internet_gateway_id" { - description = "The ID of the Internet Gateway (required if public)" - type = string - default = null -} - -# The ID of the NAT Gateway (required if route table type is private) -variable "nat_gateway_id" { - description = "The ID of the NAT Gateway (required if private)" - type = string - default = null -} - -# Prefix for naming resources -variable "cluster_prefix" { - description = "Prefix for naming resources" - type = string -} - -# Type of route table: public or private -variable "route_table_type" { - description = "Type of route table: public or private" - type = string - validation { - condition = contains(["public", "private"], var.route_table_type) - error_message = "route_table_type must be either 'public' or 'private'." - } -} - -# List of subnet IDs to associate with the route table -variable "subnet_ids" { - description = "List of subnet IDs to associate with the route table" - type = list(string) -} +####################################################### +# Variablesw +####################################################### + +# Variable Definitions + +# The ID of the VPC +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# The ID of the Internet Gateway (required if route table type is public) +variable "internet_gateway_id" { + description = "The ID of the Internet Gateway (required if public)" + type = string + default = null +} + +# The ID of the NAT Gateway (required if route table type is private) +variable "nat_gateway_id" { + description = "The ID of the NAT Gateway (required if private)" + type = string + default = null +} + +# Prefix for naming resources +variable "cluster_prefix" { + description = "Prefix for naming resources" + type = string +} + +# Type of route table: public or private +variable "route_table_type" { + description = "Type of route table: public or private" + type = string + validation { + condition = contains(["public", "private"], var.route_table_type) + error_message = "route_table_type must be either 'public' or 'private'." + } +} + +# List of subnet IDs to associate with the route table +variable "subnet_ids" { + description = "List of subnet IDs to associate with the route table" + type = list(string) +} diff --git a/modules/vpc/subnet/main.tf b/modules/vpc/subnet/main.tf index 65f5b3c..7d0e742 100644 --- a/modules/vpc/subnet/main.tf +++ b/modules/vpc/subnet/main.tf @@ -1,33 +1,33 @@ -####################################################### -# Subnets -####################################################### - -#Data Source: AWS Availability Zones -# Fetches a list of all available availability zones in the current region -data "aws_availability_zones" "available_zones" {} - -# Local Variables -locals { - # Offset calculation based on the number of available availability zones - offset = length(data.aws_availability_zones.available_zones.names) -} - -# Resource: AWS Subnet -# Creates subnets across all available availability zones -resource "aws_subnet" "subnet" { - count = length(data.aws_availability_zones.available_zones.names) - - # CIDR block calculation for the subnet - cidr_block = cidrsubnet(var.cidr, var.subnet_bits, local.offset * var.offset + count.index) - - # VPC ID in which the subnet will be created - vpc_id = var.vpc_id - - # Assigns the subnet to a specific availability zone - availability_zone = data.aws_availability_zones.available_zones.names[count.index] - - # Tags assigned to the subnet for identification - tags = { - Name = "${var.cluster_prefix}-${lower(var.subnet_type)}-subnet-${count.index + 1}" - } -} +####################################################### +# Subnets +####################################################### + +#Data Source: AWS Availability Zones +# Fetches a list of all available availability zones in the current region +data "aws_availability_zones" "available_zones" {} + +# Local Variables +locals { + # Offset calculation based on the number of available availability zones + offset = length(data.aws_availability_zones.available_zones.names) +} + +# Resource: AWS Subnet +# Creates subnets across all available availability zones +resource "aws_subnet" "subnet" { + count = length(data.aws_availability_zones.available_zones.names) + + # CIDR block calculation for the subnet + cidr_block = cidrsubnet(var.cidr, var.subnet_bits, local.offset * var.offset + count.index) + + # VPC ID in which the subnet will be created + vpc_id = var.vpc_id + + # Assigns the subnet to a specific availability zone + availability_zone = data.aws_availability_zones.available_zones.names[count.index] + + # Tags assigned to the subnet for identification + tags = { + Name = "${var.cluster_prefix}-${lower(var.subnet_type)}-subnet-${count.index + 1}" + } +} diff --git a/modules/vpc/subnet/outputs.tf b/modules/vpc/subnet/outputs.tf index 55990f9..626857b 100644 --- a/modules/vpc/subnet/outputs.tf +++ b/modules/vpc/subnet/outputs.tf @@ -1,10 +1,10 @@ -####################################################### -# Subnets -####################################################### - -# Output: Subnet IDs -# Provides the IDs of the subnets created -output "subnet_ids" { - description = "The IDs of the created subnets" - value = aws_subnet.subnet[*].id -} +####################################################### +# Subnets +####################################################### + +# Output: Subnet IDs +# Provides the IDs of the subnets created +output "subnet_ids" { + description = "The IDs of the created subnets" + value = aws_subnet.subnet[*].id +} diff --git a/modules/vpc/subnet/variables.tf b/modules/vpc/subnet/variables.tf index 87aefea..2b9b516 100644 --- a/modules/vpc/subnet/variables.tf +++ b/modules/vpc/subnet/variables.tf @@ -1,45 +1,45 @@ -####################################################### -# Variables -####################################################### - -# Variable: cidr -# Description: The CIDR block of the VPC. -variable "cidr" { - description = "The CIDR block of the VPC" - type = string -} - -# Variable: subnet_bits -# Description: The number of bits for the subnet. -variable "subnet_bits" { - description = "The number of bits for subnet" - type = number -} - -# Variable: vpc_id -# Description: The ID of the VPC. -variable "vpc_id" { - description = "The ID of the VPC" - type = string -} - -# Variable: cluster_prefix -# Description: Prefix for the cluster, used for naming resources. -variable "cluster_prefix" { - description = "Prefix for the cluster" - type = string -} - -# Variable: subnet_type -# Description: Type of subnet (e.g., public, private, storage). -variable "subnet_type" { - description = "Type of subnet" - type = string -} - -# Variable: offset -# Description: Offset value used for calculating subnet CIDR blocks. -variable "offset" { - description = "Offset value for subnet calculation" - type = number -} +####################################################### +# Variables +####################################################### + +# Variable: cidr +# Description: The CIDR block of the VPC. +variable "cidr" { + description = "The CIDR block of the VPC" + type = string +} + +# Variable: subnet_bits +# Description: The number of bits for the subnet. +variable "subnet_bits" { + description = "The number of bits for subnet" + type = number +} + +# Variable: vpc_id +# Description: The ID of the VPC. +variable "vpc_id" { + description = "The ID of the VPC" + type = string +} + +# Variable: cluster_prefix +# Description: Prefix for the cluster, used for naming resources. +variable "cluster_prefix" { + description = "Prefix for the cluster" + type = string +} + +# Variable: subnet_type +# Description: Type of subnet (e.g., public, private, storage). +variable "subnet_type" { + description = "Type of subnet" + type = string +} + +# Variable: offset +# Description: Offset value used for calculating subnet CIDR blocks. +variable "offset" { + description = "Offset value for subnet calculation" + type = number +} diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index 8786388..361f88b 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -1,24 +1,24 @@ -####################################################### -# Variables -####################################################### - -# Variable: cluster_prefix -# Description: Prefix to apply generic naming to resources like VPC and subnets -variable "cluster_prefix" { - type = string - description = "Prefix to apply generic naming to resources like VPC and subnets" -} - -# Variable: cidr -# Description: CIDR block for the VPC -variable "cidr" { - type = string - description = "CIDR block for the VPC" -} - -# Variable: subnet_bits -# Description: Number of bits to use for subnet calculations -variable "subnet_bits" { - type = string - description = "Number of bits to use for subnet calculations" -} +####################################################### +# Variables +####################################################### + +# Variable: cluster_prefix +# Description: Prefix to apply generic naming to resources like VPC and subnets +variable "cluster_prefix" { + type = string + description = "Prefix to apply generic naming to resources like VPC and subnets" +} + +# Variable: cidr +# Description: CIDR block for the VPC +variable "cidr" { + type = string + description = "CIDR block for the VPC" +} + +# Variable: subnet_bits +# Description: Number of bits to use for subnet calculations +variable "subnet_bits" { + type = string + description = "Number of bits to use for subnet calculations" +} diff --git a/output.tf b/output.tf index 6277567..fdf83bd 100644 --- a/output.tf +++ b/output.tf @@ -1,39 +1,39 @@ -####################################################### -# Outputs -####################################################### - -# EKS cluster endpoint -output "cluster_endpoint" { - description = "Endpoint for EKS control plane" - value = module.eks.cluster_endpoint -} - -# AWS region -output "region" { - description = "AWS region" - value = var.region -} - -# EKS cluster name -output "cluster_name" { - description = "Kubernetes Cluster Name" - value = module.eks.cluster_name -} - -# RDS endpoints -output "rds_endpoints" { - description = "RDS Endpoints" - value = { for key, db in module.database : key => db.db_instance_endpoint } -} - -# Public subnets IDs -output "public_subnets" { - description = "IDs of public subnets" - value = module.vpc.public_subnets_ids -} - -# VPC ID -output "vpc_id" { - description = "ID of the VPC" - value = module.vpc.vpc_id -} +####################################################### +# Outputs +####################################################### + +# EKS cluster endpoint +output "cluster_endpoint" { + description = "Endpoint for EKS control plane" + value = module.eks.cluster_endpoint +} + +# AWS region +output "region" { + description = "AWS region" + value = var.region +} + +# EKS cluster name +output "cluster_name" { + description = "Kubernetes Cluster Name" + value = module.eks.cluster_name +} + +# RDS endpoints +output "rds_endpoints" { + description = "RDS Endpoints" + value = { for key, db in module.database : key => db.db_instance_endpoint } +} + +# Public subnets IDs +output "public_subnets" { + description = "IDs of public subnets" + value = module.vpc.public_subnets_ids +} + +# VPC ID +output "vpc_id" { + description = "ID of the VPC" + value = module.vpc.vpc_id +} diff --git a/terraform.tfvars b/terraform.tfvars index d509abb..78753cc 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -1,62 +1,62 @@ -# Terraform variables for configuring the infrastructure - -# To apply generic naming to EKS Cluster -cluster_prefix = "source4learn" - -# AWS Region for the infrastructure -region = "ap-southeast-2" - -# CIDR block for the VPC -cidr = "10.0.0.0/16" - -# Number of subnet bits -subnet_bits = 4 - -# Kubernetes version for EKS Cluster -kubernetes_version = "1.28" - -# List of Control Plane Logging options to enable -eks_cluster_enabled_log_types = ["api", "audit"] - -# Cloudwatch log events retention period in days for EKS Cluster -eks_cluster_log_retention_in_days = 7 - -# EKS Cluster - Kubernetes Service IP address range -eks_cluster_service_ipv4_cidr = "10.43.0.0/16" - -# Average wait time in minutes for the EKS Cluster to be created -eks_cluster_create_timeout = "30m" - -# Average wait time in minutes for the EKS Cluster to be deleted -eks_cluster_delete_timeout = "15m" - -# Average wait time in minutes for the EKS Cluster to be updated -eks_cluster_update_timeout = "60m" - -# Map of node groups to create with their respective configurations -nodes= { - dev = { - instance_type = ["t3.medium"] - node_type = "vm" - desired_size = 1 - max_size = 3 - min_size = 1 - } - prod = { - node_type = "fargate" - selector = ["production"] - } -} - -# Map of databases to create with their respective configurations -databases = { - dev = { - db_engine = "postgres" - db_instance_class = "db.t3.micro" - db_version = "13.13" - db_storage = 20 - db_name = "devapi2" - db_username = "devapi2admin" - db_password = "gNjx3jKUcoRk8JJ" - } -} +# Terraform variables for configuring the infrastructure + +# To apply generic naming to EKS Cluster +cluster_prefix = "source4learn" + +# AWS Region for the infrastructure +region = "ap-southeast-2" + +# CIDR block for the VPC +cidr = "10.0.0.0/16" + +# Number of subnet bits +subnet_bits = 4 + +# Kubernetes version for EKS Cluster +kubernetes_version = "1.28" + +# List of Control Plane Logging options to enable +eks_cluster_enabled_log_types = ["api", "audit"] + +# Cloudwatch log events retention period in days for EKS Cluster +eks_cluster_log_retention_in_days = 7 + +# EKS Cluster - Kubernetes Service IP address range +eks_cluster_service_ipv4_cidr = "10.43.0.0/16" + +# Average wait time in minutes for the EKS Cluster to be created +eks_cluster_create_timeout = "30m" + +# Average wait time in minutes for the EKS Cluster to be deleted +eks_cluster_delete_timeout = "15m" + +# Average wait time in minutes for the EKS Cluster to be updated +eks_cluster_update_timeout = "60m" + +# Map of node groups to create with their respective configurations +nodes= { + dev = { + instance_type = ["t3.medium"] + node_type = "vm" + desired_size = 3 + max_size = 4 + min_size = 1 + } + prod = { + node_type = "fargate" + selector = ["production"] + } +} + +# Map of databases to create with their respective configurations +databases = { + dev = { + db_engine = "postgres" + db_instance_class = "db.t3.micro" + db_version = "13.13" + db_storage = 20 + db_name = "devapi2" + db_username = "" + db_password = "" + } +} diff --git a/variables.tf b/variables.tf index 4d79e77..cf3a555 100644 --- a/variables.tf +++ b/variables.tf @@ -1,105 +1,105 @@ -####################################################### -# Terraform Variables -####################################################### -# Terraform Variables - -# To apply generic naming to EKS Cluster -variable "cluster_prefix" { - description = "Prefix to apply to EKS Cluster" - type = string - default = "source4learn" -} - -# AWS Region for the infrastructure -variable "region" { - description = "AWS Region where the infrastructure will be deployed" - type = string -} - -# CIDR block for the VPC -variable "cidr" { - description = "CIDR block for the VPC" - type = string -} - -# Number of subnet bits for subnet calculation -variable "subnet_bits" { - description = "Number of bits to use for subnetting" - type = number -} - -# Kubernetes version for EKS Cluster -variable "kubernetes_version" { - description = "Version of Kubernetes for the EKS Cluster" - type = string - default = "1.19" -} - -# List of Control Plane Logging options to enable -variable "eks_cluster_enabled_log_types" { - description = "List of Control Plane Logging options to enable" - type = list(any) - default = ["api", "audit"] -} - -# Cloudwatch log events retention period in days for EKS Cluster -variable "eks_cluster_log_retention_in_days" { - description = "Retention period in days for CloudWatch log events" - type = number - default = 7 -} - -# EKS Cluster - Kubernetes Service IP address range -variable "eks_cluster_service_ipv4_cidr" { - description = "IP address range for Kubernetes services in the EKS Cluster" - type = string - default = "10.43.0.0/16" -} - -# Average wait time in minutes for the EKS Cluster to be created -variable "eks_cluster_create_timeout" { - description = "Average wait time in minutes for EKS Cluster creation" - type = string - default = "30m" -} - -# Average wait time in minutes for the EKS Cluster to be deleted -variable "eks_cluster_delete_timeout" { - description = "Average wait time in minutes for EKS Cluster deletion" - type = string - default = "15m" -} - -# Average wait time in minutes for the EKS Cluster to be updated -variable "eks_cluster_update_timeout" { - description = "Average wait time in minutes for EKS Cluster update" - type = string - default = "60m" -} - -# Map of node groups to create with their respective configurations -variable "nodes" { - description = "Map of node groups to create with their respective configurations" - type = map(object({ - instance_type = optional(list(string)) - node_type = string - desired_size = optional(number) - max_size = optional(number) - min_size = optional(number) - selector = optional(list(string)) - })) -} - -# Map of databases to create with their respective configurations -variable "databases" { - description = "Map of databases to create with their respective configurations" - type = map(object({ - db_engine = string - db_instance_class = string - db_version = string - db_storage = number - db_name = string - db_username = string - db_password = string - })) -} +####################################################### +# Terraform Variables +####################################################### +# Terraform Variables + +# To apply generic naming to EKS Cluster +variable "cluster_prefix" { + description = "Prefix to apply to EKS Cluster" + type = string + default = "source4learn" +} + +# AWS Region for the infrastructure +variable "region" { + description = "AWS Region where the infrastructure will be deployed" + type = string +} + +# CIDR block for the VPC +variable "cidr" { + description = "CIDR block for the VPC" + type = string +} + +# Number of subnet bits for subnet calculation +variable "subnet_bits" { + description = "Number of bits to use for subnetting" + type = number +} + +# Kubernetes version for EKS Cluster +variable "kubernetes_version" { + description = "Version of Kubernetes for the EKS Cluster" + type = string + default = "1.19" +} + +# List of Control Plane Logging options to enable +variable "eks_cluster_enabled_log_types" { + description = "List of Control Plane Logging options to enable" + type = list(any) + default = ["api", "audit"] +} + +# Cloudwatch log events retention period in days for EKS Cluster +variable "eks_cluster_log_retention_in_days" { + description = "Retention period in days for CloudWatch log events" + type = number + default = 7 +} + +# EKS Cluster - Kubernetes Service IP address range +variable "eks_cluster_service_ipv4_cidr" { + description = "IP address range for Kubernetes services in the EKS Cluster" + type = string + default = "10.43.0.0/16" +} + +# Average wait time in minutes for the EKS Cluster to be created +variable "eks_cluster_create_timeout" { + description = "Average wait time in minutes for EKS Cluster creation" + type = string + default = "30m" +} + +# Average wait time in minutes for the EKS Cluster to be deleted +variable "eks_cluster_delete_timeout" { + description = "Average wait time in minutes for EKS Cluster deletion" + type = string + default = "15m" +} + +# Average wait time in minutes for the EKS Cluster to be updated +variable "eks_cluster_update_timeout" { + description = "Average wait time in minutes for EKS Cluster update" + type = string + default = "60m" +} + +# Map of node groups to create with their respective configurations +variable "nodes" { + description = "Map of node groups to create with their respective configurations" + type = map(object({ + instance_type = optional(list(string)) + node_type = string + desired_size = optional(number) + max_size = optional(number) + min_size = optional(number) + selector = optional(list(string)) + })) +} + +# Map of databases to create with their respective configurations +variable "databases" { + description = "Map of databases to create with their respective configurations" + type = map(object({ + db_engine = string + db_instance_class = string + db_version = string + db_storage = number + db_name = string + db_username = string + db_password = string + })) +} From f4db8d124f11789d3e971a9d14d5c9d14ef1da3f Mon Sep 17 00:00:00 2001 From: ravi Date: Sun, 7 Jul 2024 16:46:12 +0530 Subject: [PATCH 3/4] add ecr module --- modules/ecr/main.tf | 19 +++++++++++++++++++ modules/ecr/outputs.tf | 13 +++++++++++++ modules/ecr/variables.tf | 27 +++++++++++++++++++++++++++ terraform.tfvars | 20 +++++++++++++++++++- variables.tf | 12 +++++++++--- 5 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 modules/ecr/main.tf create mode 100644 modules/ecr/outputs.tf create mode 100644 modules/ecr/variables.tf diff --git a/modules/ecr/main.tf b/modules/ecr/main.tf new file mode 100644 index 0000000..f20192d --- /dev/null +++ b/modules/ecr/main.tf @@ -0,0 +1,19 @@ +################################################################################### +# Ecr Configuration +################################################################################### + +resource "aws_ecr_repository" "ecr" { + for_each = { for repo in var.repository_name : repo => repo } + + name = "${var.cluster_prefix}-${each.key}" + image_tag_mutability = var.image_tag_mutability + image_scanning_configuration { + scan_on_push = var.scan_on_push + } +} + + +# resource "aws_ecr_lifecycle_policy" "this" { +# repository = aws_ecr_repository.ecr.name +# policy = var.lifecycle_policy +# } diff --git a/modules/ecr/outputs.tf b/modules/ecr/outputs.tf new file mode 100644 index 0000000..77bd0bd --- /dev/null +++ b/modules/ecr/outputs.tf @@ -0,0 +1,13 @@ +################################################################################### +# Output Configuration +################################################################################### + +output "repository_urls" { + description = "The URLs of the created repositories" + value = { for key, ecr_repo in aws_ecr_repository.ecr : key => ecr_repo.repository_url } +} + +output "repository_names" { + description = "The names of the repositories" + value = { for key, _ in aws_ecr_repository.ecr : key => aws_ecr_repository.ecr[key].name } +} \ No newline at end of file diff --git a/modules/ecr/variables.tf b/modules/ecr/variables.tf new file mode 100644 index 0000000..d3ac32e --- /dev/null +++ b/modules/ecr/variables.tf @@ -0,0 +1,27 @@ +################################################################################### +# Variables +################################################################################### + + +variable "cluster_prefix" { + description = "Prefix for the ECR repositories" + type = string +} + +variable "repository_name" { + description = "The name of the ECR repository" + type = list(string) +} + +variable "image_tag_mutability" { + description = "The tag mutability setting for the repository. Valid values are MUTABLE and IMMUTABLE." + type = string + default = "MUTABLE" +} + + +variable "scan_on_push" { + description = "Indicates whether images are scanned after being pushed to the repository (true/false)." + type = bool + default = false +} \ No newline at end of file diff --git a/terraform.tfvars b/terraform.tfvars index 78753cc..2b5128b 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -56,7 +56,25 @@ databases = { db_version = "13.13" db_storage = 20 db_name = "devapi2" - db_username = "" + db_username = "devapi2admin" db_password = "" } } + + +# ECR configuration + +ecr = { + dev = { + repositories = [ + "deva", + "redis" + ] + } + prod = { + repositories = [ + "prodapi1", + "test2" + ] + } +} \ No newline at end of file diff --git a/variables.tf b/variables.tf index cf3a555..b51110c 100644 --- a/variables.tf +++ b/variables.tf @@ -98,8 +98,14 @@ variable "databases" { db_instance_class = string db_version = string db_storage = number - db_name = string - db_username = string - db_password = string })) } + + +# ECR variable +variable "ecr" { + type = map(object({ + repositories = list(string) + })) + +} \ No newline at end of file From 612f9c2f2dbb30359493c4497a420d5fe171fded Mon Sep 17 00:00:00 2001 From: Ravi <54009887+ravimahey@users.noreply.github.com> Date: Wed, 19 Nov 2025 01:46:30 +0530 Subject: [PATCH 4/4] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e813b8f..7ad3ea8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # terraform-aws-eks Hashicorp Terraform AWS EKS Module +Testing