diff --git a/README.md b/README.md index dfaee22..460ce38 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,4 @@ This is an example repository to showcase some IaC usage with different cloud pr - [two-instances](html-db-website/aws-ec2/two-instances) - [aws-ec2+rds](html-db-website/aws-ec2+rds) - [aws-ecs+rds](html-db-website/aws-ecs+rds) + - [aws-eks](html-db-website/aws-eks) diff --git a/html-db-website/aws-eks/README.md b/html-db-website/aws-eks/README.md new file mode 100644 index 0000000..43a4d33 --- /dev/null +++ b/html-db-website/aws-eks/README.md @@ -0,0 +1,79 @@ +# AWS-EKS + +This is an example repository containing Terraform code. It contains the code to deploy a basic application (html web page + relational database) using EKS with an EC2 node pool for `kube-system` deployment (coredns, aws-load-balancer-controller) and a Fargate pool for the application deployment. + +## Tree +``` +. +├── misc +│   └── architecture.dot.png # Generated with https://github.com/patrickchugh/terravision. +├── README.md +└── terraform + ├── files + │   ├── alb-policy.json + │   ├── alb-values.yaml + │   └── html-db-values.yaml + ├── iam.tf + ├── kubernetes.tf # We are deploying Kubernetes objects here. + ├── main.tf + ├── network.tf + ├── outputs.tf + ├── provider.tf + ├── security_group.tf + └── variables.tf +``` + +## Architecture diagram + + + +## Infracost + +```shell + Name Monthly Qty Unit Monthly Cost + + aws_eks_cluster.nginx + └─ EKS cluster 730 hours $73.00 + + aws_nat_gateway.eks + ├─ NAT gateway 730 hours $32.85 + └─ Data processed Monthly cost depends on usage: $0.045 per GB + + aws_eks_fargate_profile.nginx + ├─ Per GB per hour 1 GB $3.24 + └─ Per vCPU per hour 1 CPU $29.55 + + aws_eks_node_group.system_nodes + ├─ Instance usage (Linux/UNIX, on-demand, t3.medium) 730 hours $30.37 + └─ Storage (general purpose SSD, gp2) 20 GB $2.00 + + OVERALL TOTAL $171.01 + +*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options. + +────────────────────────────────── +31 cloud resources were detected: +∙ 4 were estimated +∙ 27 were free + +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ +┃ Project ┃ Baseline cost ┃ Usage cost* ┃ Total cost ┃ +┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━┫ +┃ terraform ┃ $171 ┃ - ┃ $171 ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━┛ +``` + +## Helpful informations + +Must export database username and password before usage. +```shell +export TF_VAR_db_username= +export TF_VAR_db_password= +``` + +Use this command to get merge the kubeconfig with `~/.kube/config`: +```shell +aws eks update-kubeconfig --name nginx-cluster --region us-east-1 +``` + +You may need to delete `validatingwebhookconfigurations` and `mutatingwebhookconfigurations` during `terraform destroy`. diff --git a/html-db-website/aws-eks/misc/architecture.dot.png b/html-db-website/aws-eks/misc/architecture.dot.png new file mode 100644 index 0000000..47c5d7d Binary files /dev/null and b/html-db-website/aws-eks/misc/architecture.dot.png differ diff --git a/html-db-website/aws-eks/terraform/files/alb-policy.json b/html-db-website/aws-eks/terraform/files/alb-policy.json new file mode 100644 index 0000000..761d0e7 --- /dev/null +++ b/html-db-website/aws-eks/terraform/files/alb-policy.json @@ -0,0 +1,251 @@ +{ + "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", + "ec2:GetSecurityGroupsForVpc", + "ec2:DescribeIpamPools", + "ec2:DescribeRouteTables", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTrustStores", + "elasticloadbalancing:DescribeListenerAttributes", + "elasticloadbalancing:DescribeCapacityReservation" + ], + "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", + "elasticloadbalancing:ModifyListenerAttributes", + "elasticloadbalancing:ModifyCapacityReservation", + "elasticloadbalancing:ModifyIpPools" + ], + "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", + "elasticloadbalancing:SetRulePriorities" + ], + "Resource": "*" + } + ] +} diff --git a/html-db-website/aws-eks/terraform/files/alb-values.yaml b/html-db-website/aws-eks/terraform/files/alb-values.yaml new file mode 100644 index 0000000..245fd88 --- /dev/null +++ b/html-db-website/aws-eks/terraform/files/alb-values.yaml @@ -0,0 +1,9 @@ +clusterName: "${CLUSTER_NAME}" +serviceAccount: + create: false + name: "${SERVICE_ACCOUNT_NAME}" +region: "${AWS_REGION}" +vpcId: "${VPC_ID}" +subnets: + - "${SUBNET_1}" + - "${SUBNET_2}" diff --git a/html-db-website/aws-eks/terraform/files/html-db-values.yaml b/html-db-website/aws-eks/terraform/files/html-db-values.yaml new file mode 100644 index 0000000..e08b93a --- /dev/null +++ b/html-db-website/aws-eks/terraform/files/html-db-values.yaml @@ -0,0 +1,18 @@ +db: + password: "${DB_PASSWORD}" + name: "${DB_NAME}" + user: "${DB_USER}" + +ingress: + enabled: true + className: "alb" + host: "" + annotations: + kubernetes.io/ingress.class: alb + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip + alb.ingress.kubernetes.io/subnets: "${SUBNET_1}, ${SUBNET_2}" + alb.ingress.kubernetes.io/security-groups: "${ALB_SG_ID}" + alb.ingress.kubernetes.io/healthcheck-port: "8080" + alb.ingress.kubernetes.io/healthcheck-path: "/" + alb.ingress.kubernetes.io/healthcheck-protocol: HTTP diff --git a/html-db-website/aws-eks/terraform/iam.tf b/html-db-website/aws-eks/terraform/iam.tf new file mode 100644 index 0000000..7b7d000 --- /dev/null +++ b/html-db-website/aws-eks/terraform/iam.tf @@ -0,0 +1,125 @@ +resource "aws_iam_role" "eks_cluster" { + name = "nginx-eks-cluster-role" + assume_role_policy = data.aws_iam_policy_document.eks_assume_role.json +} + +data "aws_iam_policy_document" "eks_assume_role" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["eks.amazonaws.com"] + } + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role_policy_attachment" "eks_cluster" { + role = aws_iam_role.eks_cluster.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" +} + +resource "aws_iam_role" "fargate" { + name = "nginx-fargate-role" + assume_role_policy = data.aws_iam_policy_document.fargate_assume_role.json +} + +data "aws_iam_policy_document" "fargate_assume_role" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["eks-fargate-pods.amazonaws.com"] + } + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role_policy_attachment" "fargate" { + role = aws_iam_role.fargate.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" +} + +resource "aws_iam_role" "eks_nodes" { + name = "nginx-nodegroup-role" + assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json +} + +data "aws_iam_policy_document" "ec2_assume_role" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role_policy_attachment" "eks_worker" { + role = aws_iam_role.eks_nodes.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" +} + +resource "aws_iam_role_policy_attachment" "eks_cni" { + role = aws_iam_role.eks_nodes.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" +} + +resource "aws_iam_role_policy_attachment" "eks_registry" { + role = aws_iam_role.eks_nodes.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" +} + + +resource "aws_iam_policy" "alb_controller" { + name = "AWSLoadBalancerControllerIAMPolicy" + policy = file("${path.module}/files/alb-policy.json") +} + +data "aws_iam_policy_document" "alb_assume_role" { + statement { + effect = "Allow" + + principals { + type = "Federated" + identifiers = [aws_iam_openid_connect_provider.eks.arn] + } + + actions = ["sts:AssumeRoleWithWebIdentity"] + + condition { + test = "StringEquals" + variable = "${replace(aws_iam_openid_connect_provider.eks.url, "https://", "")}:sub" + values = ["system:serviceaccount:kube-system:aws-load-balancer-controller"] + } + } +} + +resource "aws_iam_role" "alb_controller" { + name = "eks-alb-controller-role" + assume_role_policy = data.aws_iam_policy_document.alb_assume_role.json +} + +resource "aws_iam_role_policy_attachment" "alb_controller" { + role = aws_iam_role.alb_controller.name + policy_arn = aws_iam_policy.alb_controller.arn +} + +data "aws_eks_cluster" "nginx" { + name = aws_eks_cluster.nginx.name +} + +data "aws_eks_cluster_auth" "nginx" { + name = aws_eks_cluster.nginx.name +} + +data "tls_certificate" "eks" { + url = data.aws_eks_cluster.nginx.identity[0].oidc[0].issuer +} + +resource "aws_iam_openid_connect_provider" "eks" { + url = data.aws_eks_cluster.nginx.identity[0].oidc[0].issuer + client_id_list = ["sts.amazonaws.com"] + thumbprint_list = [data.tls_certificate.eks.certificates[0].sha1_fingerprint] +} diff --git a/html-db-website/aws-eks/terraform/kubernetes.tf b/html-db-website/aws-eks/terraform/kubernetes.tf new file mode 100644 index 0000000..0742706 --- /dev/null +++ b/html-db-website/aws-eks/terraform/kubernetes.tf @@ -0,0 +1,58 @@ +resource "kubernetes_service_account_v1" "alb_controller" { + metadata { + name = "aws-load-balancer-controller" + namespace = "kube-system" + + annotations = { + "eks.amazonaws.com/role-arn" = aws_iam_role.alb_controller.arn + } + } +} + +resource "helm_release" "alb_controller" { + depends_on = [ + aws_eks_cluster.nginx, + aws_eks_fargate_profile.nginx, + aws_eks_node_group.system_nodes, + kubernetes_service_account_v1.alb_controller + ] + + name = "aws-load-balancer-controller" + repository = "https://aws.github.io/eks-charts" + chart = "aws-load-balancer-controller" + namespace = "kube-system" + + values = [ + templatefile("${path.module}/files/alb-values.yaml", { + CLUSTER_NAME = aws_eks_cluster.nginx.name + SERVICE_ACCOUNT_NAME = kubernetes_service_account_v1.alb_controller.metadata[0].name + AWS_REGION = var.aws_region + VPC_ID = aws_vpc.eks.id + SUBNET_1 = aws_subnet.eks[0].id + SUBNET_2 = aws_subnet.eks[1].id + }) + ] +} + +resource "helm_release" "html-db" { + depends_on = [helm_release.alb_controller] + + name = "html-db" + repository = "https://falltrades.github.io/cloud-example" + chart = "html-db" + namespace = "default" + atomic = true + force_update = true + recreate_pods = true + + values = [ + templatefile("${path.module}/files/html-db-values.yaml", { + SUBNET_1 = aws_subnet.public[0].id + SUBNET_2 = aws_subnet.public[1].id + ALB_SG_ID = aws_security_group.alb.id + DB_NAME = var.db_name + DB_USER = var.db_username + DB_PASSWORD = var.db_password + }) + ] +} diff --git a/html-db-website/aws-eks/terraform/main.tf b/html-db-website/aws-eks/terraform/main.tf new file mode 100644 index 0000000..df82dde --- /dev/null +++ b/html-db-website/aws-eks/terraform/main.tf @@ -0,0 +1,47 @@ +resource "aws_eks_cluster" "nginx" { + depends_on = [aws_iam_role_policy_attachment.eks_cluster] + + name = "nginx-cluster" + role_arn = aws_iam_role.eks_cluster.arn + + vpc_config { + subnet_ids = aws_subnet.eks[*].id + endpoint_public_access = true + endpoint_private_access = false + } +} + +resource "aws_eks_fargate_profile" "nginx" { + depends_on = [aws_eks_cluster.nginx] + + cluster_name = aws_eks_cluster.nginx.name + fargate_profile_name = "nginx-fargate" + pod_execution_role_arn = aws_iam_role.fargate.arn + subnet_ids = aws_subnet.eks[*].id + + selector { + namespace = "default" + + labels = { + app = "nginx" + } + } +} + +resource "aws_eks_node_group" "system_nodes" { + depends_on = [aws_eks_cluster.nginx] + + cluster_name = aws_eks_cluster.nginx.name + node_group_name = "system-nodes" + node_role_arn = aws_iam_role.eks_nodes.arn + subnet_ids = aws_subnet.eks[*].id + + scaling_config { + desired_size = 1 + max_size = 1 + min_size = 1 + } + + instance_types = ["t3.medium"] +} + diff --git a/html-db-website/aws-eks/terraform/network.tf b/html-db-website/aws-eks/terraform/network.tf new file mode 100644 index 0000000..4f9e4ad --- /dev/null +++ b/html-db-website/aws-eks/terraform/network.tf @@ -0,0 +1,82 @@ +resource "aws_vpc" "eks" { + cidr_block = "10.0.0.0/16" + enable_dns_support = true + enable_dns_hostnames = true +} + +data "aws_availability_zones" "available" {} + +resource "aws_subnet" "public" { + count = 2 + vpc_id = aws_vpc.eks.id + cidr_block = cidrsubnet(aws_vpc.eks.cidr_block, 8, count.index + 10) + availability_zone = data.aws_availability_zones.available.names[count.index] + map_public_ip_on_launch = true + + tags = { + Name = "eks-public-${count.index}" + "kubernetes.io/role/elb" = "1" # This tag tells the controller this is a public subnet + } +} + +resource "aws_subnet" "eks" { + count = 2 + vpc_id = aws_vpc.eks.id + cidr_block = cidrsubnet(aws_vpc.eks.cidr_block, 8, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] + map_public_ip_on_launch = true + + tags = { + "kubernetes.io/cluster/nginx-cluster" = "shared" + "kubernetes.io/role/elb" = "1" + } +} + +resource "aws_internet_gateway" "eks" { + vpc_id = aws_vpc.eks.id +} + +resource "aws_eip" "nat" { + domain = "vpc" +} + +resource "aws_nat_gateway" "eks" { + depends_on = [aws_internet_gateway.eks] + + allocation_id = aws_eip.nat.id + subnet_id = aws_subnet.public[0].id + + tags = { + Name = "eks-nat-gateway" + } +} + +resource "aws_route_table" "public" { + vpc_id = aws_vpc.eks.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.eks.id + } +} + +resource "aws_route_table_association" "public" { + count = 2 + subnet_id = aws_subnet.public[count.index].id + route_table_id = aws_route_table.public.id +} + +resource "aws_route_table" "eks" { + vpc_id = aws_vpc.eks.id + + route { + cidr_block = "0.0.0.0/0" + nat_gateway_id = aws_nat_gateway.eks.id + } +} + +resource "aws_route_table_association" "eks" { + count = length(aws_subnet.eks) + subnet_id = aws_subnet.eks[count.index].id + route_table_id = aws_route_table.eks.id +} diff --git a/html-db-website/aws-eks/terraform/outputs.tf b/html-db-website/aws-eks/terraform/outputs.tf new file mode 100644 index 0000000..84e02ff --- /dev/null +++ b/html-db-website/aws-eks/terraform/outputs.tf @@ -0,0 +1,13 @@ +# Wait for the Ingress to be created by Helm, then read its status +data "kubernetes_ingress_v1" "html_db_ingress" { + depends_on = [helm_release.html-db] + metadata { + name = "html-db-ingress" # Must match the name in your Helm templates/ingress.yaml + namespace = "default" + } +} + +output "ingress_url" { + description = "The public URL of the ALB" + value = "http://${data.kubernetes_ingress_v1.html_db_ingress.status[0].load_balancer[0].ingress[0].hostname}" +} diff --git a/html-db-website/aws-eks/terraform/provider.tf b/html-db-website/aws-eks/terraform/provider.tf new file mode 100644 index 0000000..10bcd00 --- /dev/null +++ b/html-db-website/aws-eks/terraform/provider.tf @@ -0,0 +1,47 @@ +terraform { + required_version = ">= 1.6" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 6.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 3.0.1" + } + helm = { + source = "hashicorp/helm" + version = "~> 3.1.1" + } + tls = { + source = "hashicorp/tls" + version = "~> 4.2.1" + } + } +} + +provider "aws" { + region = var.aws_region + s3_use_path_style = true + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true +} + +provider "kubernetes" { + host = aws_eks_cluster.nginx.endpoint + cluster_ca_certificate = base64decode( + aws_eks_cluster.nginx.certificate_authority[0].data + ) + token = data.aws_eks_cluster_auth.nginx.token +} + +provider "helm" { + kubernetes = { + host = aws_eks_cluster.nginx.endpoint + cluster_ca_certificate = base64decode( + aws_eks_cluster.nginx.certificate_authority[0].data + ) + token = data.aws_eks_cluster_auth.nginx.token + } +} diff --git a/html-db-website/aws-eks/terraform/security_group.tf b/html-db-website/aws-eks/terraform/security_group.tf new file mode 100644 index 0000000..6796886 --- /dev/null +++ b/html-db-website/aws-eks/terraform/security_group.tf @@ -0,0 +1,27 @@ +resource "aws_security_group" "alb" { + name = "nginx-alb-sg" + vpc_id = aws_vpc.eks.id + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_security_group_rule" "alb_to_nodes" { + type = "ingress" + from_port = 8080 + to_port = 8080 + protocol = "tcp" + security_group_id = aws_eks_cluster.nginx.vpc_config[0].cluster_security_group_id + source_security_group_id = aws_security_group.alb.id # From the previous step +} diff --git a/html-db-website/aws-eks/terraform/variables.tf b/html-db-website/aws-eks/terraform/variables.tf new file mode 100644 index 0000000..643ee53 --- /dev/null +++ b/html-db-website/aws-eks/terraform/variables.tf @@ -0,0 +1,23 @@ +variable "aws_region" { + description = "the AWS region" + type = string + default = "us-east-1" +} + +variable "db_username" { + description = "DB Root username" + type = string + sensitive = true +} + +variable "db_password" { + description = "DB Root Password" + type = string + sensitive = true +} + +variable "db_name" { + description = "DB Root name" + type = string + default = "tasklist_db" +}