With the increasing complexity of modern applications and infrastructure, manual setup and configuration are no longer efficient or scalable. Automation tools like Kubernetes, Vagrant, and Terraform provide a way to define infrastructure and application configurations as code, allowing for version control, reproducibility, and scalability. These tools enable organizations to achieve consistent and repeatable deployments, reduce human errors, and accelerate the time to market for their applications.

Kubernetes, as a container orchestration platform, automates the deployment, scaling, and management of containerized applications. It abstracts away the underlying infrastructure, allowing developers and operators to focus on defining the desired state of their applications and leaving Kubernetes to handle the execution and management of those applications.

Vagrant, on the other hand, automates the setup and provisioning of development environments by defining virtual machines as code. It eliminates the need for manual environment configuration, allowing developers to quickly create and share reproducible development environments. This automation saves time and ensures consistency across development teams.

Terraform takes automation a step further by providing infrastructure-as-code capabilities. It allows organizations to define and provision infrastructure resources across various cloud providers and infrastructure platforms. With Terraform, infrastructure configurations can be written as code, enabling automation, collaboration, and version control. This approach removes manual intervention in the infrastructure provisioning process and provides a scalable and efficient way to manage infrastructure resources.

When used together, Kubernetes, Vagrant, and Terraform can greatly simplify the process of deploying a Kubernetes cluster. Vagrant can be used to set up the necessary virtual machines for the cluster, while Terraform can provision the required infrastructure resources. Once the infrastructure is in place, Kubernetes can be deployed and managed using its own tools like kubeadm or kops.

The significant advantages associated when using Kubernetes, Vagrant, and Terraform together when deploying a Kubernetes cluster are:

  • Scalability and Flexibility: Kubernetes provides built-in scalability features, allowing applications to scale horizontally and handle increased traffic and workloads. Combined with Terraform, which can provision and manage infrastructure resources on various cloud providers, organizations can easily scale their Kubernetes clusters based on demand. Vagrant also offers flexibility by allowing developers to create and replicate development environments with ease.
  • Simplified Deployment: Kubernetes abstracts away the complexities of managing containerized applications, while Vagrant and Terraform automate the setup and provisioning of the required infrastructure resources. This combination allows for streamlined and simplified deployment processes, reducing the time and effort required to get a Kubernetes cluster up and running.
  • Collaboration and Team Productivity: The use of these automation tools promotes collaboration and enhances team productivity. Infrastructure configurations and deployment scripts can be stored in version control systems, enabling multiple team members to contribute, review, and collaborate on the infrastructure setup. This improves transparency, knowledge sharing, and overall efficiency within the team.
  • Consistency and Reproducibility: By using infrastructure-as-code practices with Terraform and Vagrant, organizations can ensure consistent and reproducible deployments. Infrastructure and development environments can be defined in code and shared across teams, reducing the risk of configuration errors and inconsistencies.
  • Time and Cost Savings: Automation reduces manual intervention and eliminates repetitive tasks, saving time and effort. It minimizes human errors and accelerates the deployment process. With faster and more efficient deployments, organizations can bring their applications to market quicker, resulting in potential cost savings and competitive advantages.
  • Portability and Multi-Cloud Support: Kubernetes, Vagrant, and Terraform support multiple cloud providers and infrastructure platforms. This allows organizations to deploy their Kubernetes clusters in various environments, including on-premises data centres, public clouds, or hybrid cloud setups. The flexibility and portability offered by these tools enable organizations to adopt a multi-cloud strategy and avoid vendor lock-in.

Join me as we learn how to deploy a Kubernetes Cluster Using Vagrant & Terraform.

Install the Required Packages

For this guide, you need to have:

Install VirtualBox:

Install Vagrant:

Verify your Vagrant installation:

vagrant --version

Install Ansible

You can install Ansible on Linux using the below commands:

##On Ubuntu / Debian
sudo apt update
sudo apt install ansible

##On RHEL/Rocky Linux/Alma Linux
sudo yum install epel-release
sudo yum install ansible ansible-core

Verify the installation:

$ ansible --version
ansible [core 2.13.6]
  config file = None
  configured module search path = ['/Users/jkmutai/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/Cellar/ansible/6.6.0/libexec/lib/python3.10/site-packages/ansible
  ansible collection location = /Users/jkmutai/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.8 (main, Oct 13 2022, 10:17:43) [Clang 14.0.0 (clang-1400.0.29.102)]
  jinja version = 3.1.2
  libyaml = True

Create Kubernetes cluster using Vagrant

Once the required packages have been installed, you can proceed and spin a Kubernetes cluster using Vagrant.

First, clone the repository that provides the required configs:

git clone https://github.com/techviewleo/virtualbox-kubernetes.git
cd virtualbox-kubernetes

In the directory, there is a Vagrantfile and several other files like Ansible playbooks etc. You can open the Vagrantfile for editing:

vim Vagrantfile

The file has default variables declared, you can modify them to suit your environment. For example;

  • IMAGE_NAME = “bento/ubuntu-16.04” This can be changed to any other version. (Try and report issues if any)
  • NODES = 2 defines the number of worker nodes in the cluster. Based on this value, Vagrant will create multiple nodes automatically.
  • CLUSTER_NAME = “demo” can be changed if you need another cluster in the same workstation (cluster name will be prefixed with VM name to identify)
  • APISERVER_ADVERTISE_ADDRESS = “192.168.56.102” and NODE_IP_ADDRESS_RANGE = “192.168.56” are used based on vboxnet0 Host-only adaptor. If you using a different network, then modify the IP addresses accordingly.

To use the host-only network on Virtualbox, create it with the command:

VBoxManage hostonlyif create

List the created interface:

$ VBoxManage list dhcpservers
NetworkName:    HostInterfaceNetworking-vboxnet0
Dhcpd IP:       192.168.56.100
LowerIPAddress: 192.168.56.101
UpperIPAddress: 192.168.56.254
NetworkMask:    255.255.255.0
Enabled:        Yes
Global Configuration:
    minLeaseTime:     default
    defaultLeaseTime: default
    maxLeaseTime:     default
    Forced options:   None
    Suppressed opts.: None
        1/legacy: 255.255.255.0
Groups:               None
Individual Configs:   None

If any hostname changes are made in the Vagrant file, you also need to modify them in the Playbook.

$ vim kubernetes-setup/controlplane-playbook.yml 
# Step 2.3: Initialize the Kubernetes cluster with kubeadm using the below code (applicable only on controlplane node).
  - name: Initialize the Kubernetes cluster using kubeadm
    command: sudo kubeadm init --apiserver-advertise-address={{ apiserver_advertise_address }} --apiserver-cert-extra-sans={{ apiserver_advertise_address }} --node-name demo-k8s-controlplane --pod-network-cidr=192.168.0.0/16

Save the changes and apply the file:

vagrant up

If all goes well, you will see Ansible scripts executed as well.

Deploy Kubernetes Cluster Using Vagrant Terraform

View the running VMs on VirtualBox:

Deploy Kubernetes Cluster Using Vagrant Terraform 1

Now we need to access the Kubernetes cluster provisioned form or workstation. To achieve that, you need to obtain the KUBECONFIG file from the control plane.

SSH into the control plane with the command:

vagrant ssh controlplane

Once there, copy the config to your workstation:

scp ~/.kube/config  username@IP_Address:~/.kube/config

Replace the username and IP_Address with the exact details for your workstation. Once copied, exit SSH:

exit

To access the cluster, install kubectl on the workstation:

curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin

Deploy Kubernetes Networking

At this point, the cluster is up but the nodes are not ready. To verify that, use:

$ kubectl get nodes -o wide
NAME                    STATUS     ROLES           AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
demo-compute-1          NotReady   <none>          6m7s    v1.27.2   <none>           <none>        Ubuntu 20.04.6 LTS   5.4.0-144-generic   containerd://1.6.21
demo-compute-2          NotReady   <none>          3m22s   v1.27.2   <none>           <none>        Ubuntu 20.04.6 LTS   5.4.0-144-generic   containerd://1.6.21
demo-k8s-controlplane   NotReady   control-plane   8m55s   v1.27.2   192.168.56.102   <none>        Ubuntu 20.04.6 LTS   5.4.0-144-generic   containerd://1.6.21

For the nodes to get ready, we need to deploy the network. Begin by installing the operator:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml

Now pull and apply the manifests:

curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml -O
kubectl create -f custom-resources.yaml

View the pods after some time:

$ kubectl get pods --all-namespaces
NAMESPACE         NAME                                            READY   STATUS    RESTARTS      AGE
calico-system     calico-kube-controllers-789dc4c76b-rr47f        0/1     Running   2 (28s ago)   2m39s
calico-system     calico-node-fhhbp                               0/1     Running   0             2m40s
calico-system     calico-node-nf45v                               0/1     Running   0             2m40s
calico-system     calico-node-vb22h                               0/1     Running   0             2m40s
calico-system     calico-typha-5b89ffb9bd-ch2j9                   1/1     Running   0             2m40s
calico-system     calico-typha-5b89ffb9bd-ftrlv                   1/1     Running   0             2m31s
calico-system     csi-node-driver-j8tnb                           2/2     Running   0             2m40s
calico-system     csi-node-driver-q49c2                           2/2     Running   0             2m40s
calico-system     csi-node-driver-rlj7n                           2/2     Running   0             2m40s
kube-system       coredns-5d78c9869d-kmrpp                        0/1     Running   0             16m
kube-system       coredns-5d78c9869d-pbmk9                        0/1     Running   0             16m
kube-system       etcd-demo-k8s-controlplane                      1/1     Running   0             16m
kube-system       kube-apiserver-demo-k8s-controlplane            1/1     Running   0             16m
kube-system       kube-controller-manager-demo-k8s-controlplane   1/1     Running   0             16m
kube-system       kube-proxy-22rgh                                1/1     Running   0             16m
kube-system       kube-proxy-klpwz                                1/1     Running   0             11m
kube-system       kube-proxy-n6jl5                                1/1     Running   0             13m
kube-system       kube-scheduler-demo-k8s-controlplane            1/1     Running   0             16m
tigera-operator   tigera-operator-549d4f9bdb-2q494                1/1     Running   0             2m49s

View the nodes:

$ kubectl get nodes
NAME                    STATUS   ROLES           AGE   VERSION
demo-compute-1          Ready    <none>          15m   v1.27.2
demo-compute-2          Ready    <none>          12m   v1.27.2
demo-k8s-controlplane   Ready    control-plane   18m   v1.27.2

Automate Deployments on Kubernetes using Terraform

We will be using Terraform to automate resource deployment in the Kubernetes cluster. First, ensure that Terraform is installed on your system. This can be done by following any of the below guides:

Verify the installation:

$ terraform  version
Terraform v1.4.6
on linux_amd64

When connecting to your cluster with Terraform, you can use the below authentication methods. The most recommended is first and the least recommended last

in this guide, we will use kubeconfig authentication. For that, you need the config_path and config_context.

View your current context with the command:

$ kubectl config current-context
kubernetes-admin@kubernetes

After obtaining your context name, proceed to create a Teraform script for the deployment.

For this guide, we will deploy a simple Nginx app on the Kubernetes cluster.

mkdir ~/nginx && cd  ~/nginx
vim kubernetes-nginx.tf

In the file add the lines below:

provider "kubernetes" {
  config_path    = "~/.kube/config"
  config_context = "kubernetes-admin@kubernetes"
}

resource "kubernetes_deployment" "nginx" {
  metadata {
    name = "nginx-deployment"
    labels = {
      app = "nginx"
    }
  }

  spec {
    replicas = 3

    selector {
      match_labels = {
        app = "nginx"
      }
    }

    template {
      metadata {
        labels = {
          app = "nginx"
        }
      }

      spec {
        container {
          name  = "nginx"
          image = "nginx:latest"
          port {
            container_port = 80
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "nginx" {
  metadata {
    name = "nginx-service"
  }

  spec {
    selector = {
      app = "nginx"
    }

    port {
      node_port   = 30201
      port        = 80
      target_port = 80
    }
   type = "NodePort"
  }
}

Replace the variable in bold as desired. Then run the Terraform script.

terraform init
terraform plan
terraform apply

Proceed as shown when applying the changes:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

The deployment should then happen as shown:

Deploy Kubernetes Cluster Using Vagrant Terraform 2

View if the pods are running:

$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-77cd647b9c-8tttn   1/1     Running   0          2m59s
nginx-deployment-77cd647b9c-gnpqp   1/1     Running   0          2m59s
nginx-deployment-77cd647b9c-l5rdd   1/1     Running   0          2m59s

$ kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP        73m
nginx-service   NodePort    10.97.92.142   <none>        80:30201/TCP   7m45s

You can also view the status with the command:

terraform show

You can now access the service using your NodeIP address which is 192.168.56.51 and 192.168.56.52.

For example:

$ curl http://192.168.56.51:30201
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

That marks the end of this guide on how to deploy Kubernetes Cluster Using Vagrant & Terraform. You can now agree with me that these 3 tools can make it so easy t deploy and manage resources in a Kubernetes cluster. I hope this was informative.

See more:

LEAVE A REPLY

Please enter your comment!
Please enter your name here