How To Deploy EKS, RDS cluster with Website Using Terraform
Hi Guys, In this, I’m going to Launch the cluster (EKS, RDS) with the website(WordPress) using the Terraform so that It’s totally on the cloud, which very easy to manged.
So Whats EKS?
In simple words its the Amazon’s Elastic Kubernetes Service you can learn more about it here.
Again Whats RDS?
Amazon Relational Database Service provides us the database service on the cloud cost effective and many more. Want to learn more about it click here.
You can check out about the Terraform here.
So what we required to set up the infrastructure
Prerequisite: AWS account, AWS CLI(configure the IAM user with admin Power), kubectl(with empty config file), Terraform.
STEP1
Create the Security Group for the RDS
resource "aws_security_group" "rds-sec-grp" {name = "RDS-Securty-Grp"description = "Allow MySQL Ports"ingress {description = "Allowing Connection for SSH"from_port = 3306to_port = 3306protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}egress {from_port = 0to_port = 0protocol = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "RDS-Server"}}
Here I have created the security group allowing the port 3306 as we know MySQL works by Default on this port only.
STEP2
Create The RDS instance template
resource "aws_db_instance" "rds" {allocated_storage = 20storage_type = "gp2"engine = "mysql"engine_version = "5.7"instance_class = "db.t2.micro"name = "mydb"username = "wp"password = "wordpress123"parameter_group_name = "default.mysql5.7"publicly_accessible = trueskip_final_snapshot = truevpc_security_group_ids = [aws_security_group.rds-sec-grp.id]tags = {name = "RDS_Main"}}
Here I have provisioned the 20Gb storage with t2.micro flavor of instance and the credentials with other details.
STEP3
Now We have to provision the EKS Cluster with the Roles and Policies
resource "aws_iam_role" "role" {name = "eks-cluster"assume_role_policy = <<POLICY{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "eks.amazonaws.com"},"Action": "sts:AssumeRole"}]}POLICY}resource "aws_iam_role_policy_attachment" "Mine-AmazonEKSClusterPolicy" {policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"role = aws_iam_role.role.name}resource "aws_iam_role_policy_attachment" "AmazonEKSVPCResourceController" {policy_arn = arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"role = aws_iam_role.role.name}
STEP4
Now Since We have provisioned the Role and permissions, We can now start creating the cluster
resource "aws_eks_cluster" "MyCluster" {depends_on = [aws_iam_role_policy_attachment.AmazonEKSVPCResourceController,aws_iam_role_policy_attachment.Mine-AmazonEKSClusterPolicy]name = "Cluster"role_arn = aws_iam_role.role.arnvpc_config {subnet_ids = ["subnet-d2e2d8ba", "subnet-83056ecf"]}tags = {Name = "EKS_Subnet"}}
It will automatically create a security group for the cluster
NOTE: Now there’s a catch We have to make sure that ROLES and Permission are created Before Cluster and deleted after the Cluster otherwise It will not be able to create or delete it.
STEP5
Now Since we Have created the cluster and Master is managed by the Amazon we are only left to provision the slaves or nodes.
resource "aws_iam_role" "role2" {name = "eks-node-group"assume_role_policy = jsonencode({Statement = [{Action = "sts:AssumeRole"Effect = "Allow"Principal = {Service = "ec2.amazonaws.com"}}]Version = "2012-10-17"})}resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" {policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"role = aws_iam_role.role2.name}resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" {policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"role = aws_iam_role.role2.name}resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" {policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"role = aws_iam_role.role2.name}
Here Again, I have created the ROLE and Permissions for the NODE GROUP
NOTE: You must have the admin power IAM user to perform these steps.
STEP6
Since we have provided the role and permissions, Now we can create the Node Group
resource "aws_eks_node_group" "node" {cluster_name = aws_eks_cluster.MyCluster.namenode_group_name = "node"node_role_arn = aws_iam_role.role2.arnsubnet_ids = ["subnet-d2e2d8ba", "subnet-83056ecf"]instance_types = ["t2.micro"]scaling_config {desired_size = 2max_size = 3min_size = 1}depends_on = [aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,]}
Here The Cluster will have 2 slaves (NODE) with a maximum limit of 3 and a minimum of 1.
And We Have Created the EKS Cluster
Now we need to configure the Kubectl so that we can interact with our cluster
STEP7
resource "null_resource" "null1" {depends_on = [aws_eks_node_group.node]provisioner "local-exec" {command = "aws eks --region ap-south-1 update-kubeconfig --name Cluster"}}
NOTE: MAKE SURE THE CONFIG FILE IS EMPTY OTHERWISE IT WILL FAIL.
Now we have the kubectl configure, to test this I’ve run some command
kubectl get nodes
STEP8
Now We are going to Deploy the WordPress and run service to expose the port of the pods
provider "kubernetes" {}resource "kubernetes_deployment" "mydeployment" {depends_on = [null_resource.null1]metadata {name = "wordpress"labels = {app = "wordpress"}}spec {replicas = 2selector {match_labels = {app = "wordpress"}}template {metadata {labels = {app = "wordpress"}}spec {container {image = "wordpress"name = "wordpress:4.8-apache"env{name = "WORDPRESS_DB_HOST"value = aws_db_instance.rds.address}env{name = "WORDPRESS_DB_USER"value = aws_db_instance.rds.name}env{name = "WORDPRESS_DB_PASSWORD"value = aws_db_instance.rds.password}port {container_port = 80}}}}}}resource "kubernetes_service" "Myservice"{depends_on = [kubernetes_deployment.mydeployment]metadata {name = "exposeportofwp"}spec {selector = {app = kubernetes_deployment.mydeployment.metadata.0.labels.app}port {node_port = 30001port = 80target_port = 80}type = "LoadBalancer"}}
We have successfully deployed the container with WordPress running in it
As we Can see I have used the type as LoadBalancer so it will automatically create a classic L.B of AWS
It will also create an Auto-Scaling Group for Load-Balancing
AND at last, The WordPress is Launch
NOTE: The Setup requires almost 15–20 min to fully provision
Don’t delete any resource manually
terraform destroy --auto-approve
Use the above command in your terminal from your directory
You Can Find The Whole Code in my GitHub Repository