├── .gitignore ├── outputs.tf ├── variables.tf ├── scripts ├── install_k8s_wrk.sh └── install_k8s_msr.sh ├── README.md └── main.tf /.gitignore: -------------------------------------------------------------------------------- 1 | .terraform/ 2 | .terraform.lock.hcl 3 | terraform.tfstate.backup 4 | terraform.tfstate -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_msr_public_ip" { 2 | description = "Public address IP of master" 3 | value = aws_instance.ec2_instance_msr.public_ip 4 | } 5 | 6 | output "instance_wrks_public_ip" { 7 | description = "Public address IP of worker" 8 | value = aws_instance.ec2_instance_wrk.*.public_ip 9 | } 10 | 11 | # output "instance_msr_privte_ip" { 12 | # description = "Private IP address of master" 13 | # value = aws_instance.ec2_instance_msr.private_ip 14 | # } 15 | 16 | # output "s3_bucket_name" { 17 | # description = "The S3 bucket name" 18 | # value = "k8s-${random_string.s3name.result}" 19 | # } 20 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "access_key" { #Todo: uncomment the default value and add your access key. 2 | description = "Access key to AWS console" 3 | default = "XXXXXXXXXXXXXXXXXXXXXXX" 4 | } 5 | 6 | variable "secret_key" { #Todo: uncomment the default value and add your secert key. 7 | description = "Secret key to AWS console" 8 | default = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" 9 | } 10 | 11 | variable "ami_key_pair_name" { #Todo: uncomment the default value and add your pem key pair name. Hint: don't write '.pem' exction just the key name 12 | default = "Latest" 13 | } 14 | variable "number_of_worker" { 15 | description = "number of worker instances to be join on cluster." 16 | default = 2 17 | } 18 | 19 | variable "region" { 20 | description = "The region zone on AWS" 21 | default = "us-east-1" #The zone I selected is us-east-1, if you change it make sure to check if ami_id below is correct. 22 | } 23 | 24 | variable "ami_id" { 25 | description = "The AMI to use" 26 | default = "ami-0a6b2839d44d781b2" #Ubuntu 20.04 27 | } 28 | 29 | variable "instance_type" { 30 | default = "t2.medium" #the best type to start k8s with it, 31 | } -------------------------------------------------------------------------------- /scripts/install_k8s_wrk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ######### ** FOR WORKER NODE ** ######### 4 | 5 | hostname k8s-wrk-${worker_number} 6 | echo "k8s-wrk-${worker_number}" > /etc/hostname 7 | 8 | export AWS_ACCESS_KEY_ID=${access_key} 9 | export AWS_SECRET_ACCESS_KEY=${private_key} 10 | export AWS_DEFAULT_REGION=${region} 11 | 12 | 13 | apt update 14 | apt install apt-transport-https ca-certificates curl software-properties-common -y 15 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 16 | add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" 17 | 18 | #Installing Docker 19 | apt update 20 | apt-cache policy docker-ce 21 | apt install docker-ce -y 22 | apt install awscli -y 23 | 24 | #Be sure to understand, if you follow official Kubernetes documentation, in Ubuntu 20 it does not work, that is why, I did modification to script 25 | #Adding Kubernetes repositories 26 | 27 | #Next 2 lines are different from official Kubernetes guide, but the way Kubernetes describe step does not work 28 | curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add 29 | echo "deb https://packages.cloud.google.com/apt kubernetes-xenial main" > /etc/apt/sources.list.d/kurbenetes.list 30 | 31 | #Turn off swap 32 | swapoff -a 33 | 34 | #Installing Kubernetes tools 35 | apt update 36 | apt install kubelet kubeadm kubectl -y 37 | 38 | #next line is getting EC2 instance IP, for kubeadm to initiate cluster 39 | #we need to get EC2 internal IP address- default ENI is eth0 40 | export ipaddr=`ip address|grep eth0|grep inet|awk -F ' ' '{print $2}' |awk -F '/' '{print $1}'` 41 | 42 | 43 | # the kubeadm init won't work entel remove the containerd config and restart it. 44 | rm /etc/containerd/config.toml 45 | systemctl restart containerd 46 | 47 | # to insure the join command start when the installion of master node is done. 48 | sleep 1m 49 | 50 | aws s3 cp s3://${s3buckit_name}/join_command.sh /tmp/. 51 | chmod +x /tmp/join_command.sh 52 | bash /tmp/join_command.sh 53 | -------------------------------------------------------------------------------- /scripts/install_k8s_msr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ######### ** FOR MASTER NODE ** ######### 4 | 5 | hostname k8s-msr-1 6 | echo "k8s-msr-1" > /etc/hostname 7 | 8 | export AWS_ACCESS_KEY_ID=${access_key} 9 | export AWS_SECRET_ACCESS_KEY=${private_key} 10 | export AWS_DEFAULT_REGION=${region} 11 | 12 | 13 | apt update 14 | apt install apt-transport-https ca-certificates curl software-properties-common -y 15 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 16 | add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" 17 | 18 | #Installing Docker 19 | apt update 20 | apt-cache policy docker-ce 21 | apt install docker-ce -y 22 | apt install awscli -y 23 | #Be sure to understand, if you follow official Kubernetes documentation, in Ubuntu 20 it does not work, that is why, I did modification to script 24 | #Adding Kubernetes repositories 25 | 26 | #Next 2 lines are different from official Kubernetes guide, but the way Kubernetes describe step does not work 27 | curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add 28 | echo "deb https://packages.cloud.google.com/apt kubernetes-xenial main" > /etc/apt/sources.list.d/kurbenetes.list 29 | 30 | #Turn off swap 31 | swapoff -a 32 | 33 | #Installing Kubernetes tools 34 | apt update 35 | apt install kubelet kubeadm kubectl -y 36 | 37 | #next line is getting EC2 instance IP, for kubeadm to initiate cluster 38 | #we need to get EC2 internal IP address- default ENI is eth0 39 | export ipaddr=`ip address|grep eth0|grep inet|awk -F ' ' '{print $2}' |awk -F '/' '{print $1}'` 40 | export pubip=`dig +short myip.opendns.com @resolver1.opendns.com` 41 | 42 | # the kubeadm init won't work entel remove the containerd config and restart it. 43 | rm /etc/containerd/config.toml 44 | systemctl restart containerd 45 | 46 | #Kubernetes cluster init 47 | #You can replace 172.16.0.0/16 with your desired pod network 48 | kubeadm init --apiserver-advertise-address=$ipaddr --pod-network-cidr=172.16.0.0/16 --apiserver-cert-extra-sans=$pubip > /tmp/restult.out 49 | cat /tmp/restult.out 50 | 51 | #to get join commdn 52 | tail -2 /tmp/restult.out > /tmp/join_command.sh; 53 | aws s3 cp /tmp/join_command.sh s3://${s3buckit_name}; 54 | #this adds .kube/config for root account, run same for ubuntu user, if you need it 55 | mkdir -p /root/.kube; 56 | cp -i /etc/kubernetes/admin.conf /root/.kube/config; 57 | cp -i /etc/kubernetes/admin.conf /tmp/admin.conf; 58 | chmod 755 /tmp/admin.conf 59 | 60 | #Add kube config to ubuntu user. 61 | mkdir -p /home/ubuntu/.kube; 62 | cp -i /etc/kubernetes/admin.conf /home/ubuntu/.kube/config; 63 | chmod 755 /home/ubuntu/.kube/config 64 | 65 | 66 | #to copy kube config file to s3 67 | # aws s3 cp /etc/kubernetes/admin.conf s3://${s3buckit_name} 68 | 69 | #Uncomment next line if you want calico Cluster Pod Network 70 | curl -o /root/calico.yaml https://docs.projectcalico.org/v3.16/manifests/calico.yaml 71 | sleep 5 72 | kubectl --kubeconfig /root/.kube/config apply -f /root/calico.yaml 73 | systemctl restart kubelet 74 | 75 | # Apply kubectl Cheat Sheet Autocomplete 76 | source <(kubectl completion bash) # set up autocomplete in bash into the current shell, bash-completion package should be installed first. 77 | echo "source <(kubectl completion bash)" >> /home/ubuntu/.bashrc # add autocomplete permanently to your bash shell. 78 | echo "source <(kubectl completion bash)" >> /root/.bashrc # add autocomplete permanently to your bash shell. 79 | alias k=kubectl 80 | complete -o default -F __start_kubectl k 81 | echo "alias k=kubectl" >> /home/ubuntu/.bashrc 82 | echo "alias k=kubectl" >> /root/.bashrc 83 | echo "complete -o default -F __start_kubectl k" >> /home/ubuntu/.bashrc 84 | echo "complete -o default -F __start_kubectl k" >> /root/.bashrc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Terraform to Bulding Kubernetes Cluster using EC2 instances 2 | [![LinkedIn][linkedin-shield]][linkedin-url] 3 | [![GitHub][github-shield]][github-url] 4 | 5 | 6 | I built this project to create my own lab for [Kuberntes](https://kubernetes.io/) cluster on AWS cloud using EC2 instances. I found [Terraform](https://www.terraform.io) is the best tool to create my K8S lab fastly with one command 🚀. 7 |
8 | 9 |  10 |
11 | 12 | ## Terraform Resources Used 13 | - EC2 14 | - One Master Node 15 | - Two Worker Node (can be increased) 16 | - VPC 17 | - Public Subnet 18 | - Internet Gateway 19 | - Route Table 20 | - Security Group 21 | - S3 Bucket 22 | 23 |