Vagrant for begginers
Tags: vagrant, automation, devops, virtualmachines
Published: 2022-12-06 12:33:31

## Introduction

Vagrant, a open source project to create and maintain VMs, was supposedly a side project by [Mitchell Hashimoto](https://twitter.com/mitchellh) and the company name Hashicorp was found around it. It is mainly used to create portable development environments. Vagrant cloud containes these ready-to-run vagrant boxes, which can be setup within minutes, provided, you have installed Vagrant and other utilities required along with it. 

Vagrant can create VMs through configuration files or bootstrapped scripts, which can be easily automated using tools like bash, ansible, chef, puppet etc. 

### What are we going to do ? 

The Idea here is to learn about the basic capabilities of vagrant, this can help the readers take up medium or maybe advanced topics to further their expertise. 

For simplicity's stake we assume everyone has installed vagrant , if not [there you go!](https://developer.hashicorp.com/vagrant/tutorials/getting-started/getting-started-install). We are going to start up a VM, inside which apache server would be serving up a site. 

Just to be clear, we are going to start up not just a VM with some basic configurations but then we are going to install apache2 ; a web server and then host a simple website on it, we are going to make the site available inside your network, meaning it can be easily accessed through not just the host machine but also your mobiles or other laptops if they're connected to your wifi or router. At the end, we are going to see how all of this can be automated .Good deal ! read up ahead.

**Note: ** Although we are hosting a website to learn vagrant, It's actually used to setup devlopment environments and shouldn't be used to setup Production environments.

## Setting up the tools 

Well, the only tools you require is Vagrant and a VM provider, fun fact!  vagrant supports multiple VM providers vmware, virtualbox , docker etc.  So you can go ahead with this tutorial, if you have any of these VM providers installed already. Although i wouldn't prefer Docker, because of two reasons, reason 1 being, most of the config is done on dockerfiles and second we would deviate from the core lessons that vagrant has to offer. 

so our first command is going to be `vagrant init ubuntu/jammy64` this creates a Vagrantfile that contain configurations for our VM, it's written in `ruby`, but you wouldn't need to learn it. ubuntu/jammy64 is the `box` name. **Box ** in vagrant are usually the name of the linux distros, or names people give their VMs and then upload it to `vagrant cloud`. Where you can share and use these boxes. Similar to images in Docker.

`vagrant up` downloads the box and then boots it up, `vagrant ssh` would log you inside the box and `logout` will simply log you out of the box. 

### Installing the web server

Now that we are able to bring up the VM, next we will manually try to install the apache server on it. before that we are going to perform the below actions.
- We are going to update our system dependencies using `sudo apt update` . This is standard practice to keep your system updated.
- The command to install apache from the apt repository for ubuntu is `sudo apt install apache2` , you could easily get this from google, if you want to try installing something else.
- We can just type`systemctl status apache2` in the terminal to check the status of the apache server. It should already be running 
- You can try sending a request to the site, using `curl -v localhost:80`. curl is a terminal based tool to check the status of websites. It will send some text back , what we're looking for is `200 OK` this lets us know that site is up and running at port 80.

### Networking.

Well, both the VM and the web server are up and running but this site can't be accessed on the host machine. what's the point you may ask? and... you're right, a site that is only available on the local machine isn't useful at all. 

Now comes the networking, There are a number of ways to make this site available to local network or even the internet. you can go through this link for basic or even advanced usage of networking with vagrant [Networking Vagrant](https://developer.hashicorp.com/vagrant/docs/networking). 

We are going to make our site available on our local network through something called port-forwarding. We are going to map one of the ports on the host machine to port 80 of the VM i.e. ( host:4567 -> VM:80),
 The traffic sent to host:4567 will be directed to port 80 of the VM. 
```
config.vm.network "forwarded_port", guest:80, host:4567
``` 
this single line should do the trick inside the vagrant file. Do this change to the Vagrantfile, save it and do `vagrant reload`. you can try visiting `localhost:4567` , voila ! you will see the default page of apache server , now the only thing left is to replace apache default webpage to custom simple html and css based website. you can simply paste the content of your website inside the folder `/var/www/html/`. how would you do this ? Your root directory, where Vagrantfile is created, is the directory that gets mounted as `/vagrant` inside the VM so you can move files to this root directory and then move this files to `/var/www/html` inside the VM.

### TL;DR 

Now we are all set, you can `vagrant destroy` which will delete the VM and all of its content. 

Vagrant will take a config file:`Vagrantfile` and spin up a VM. Below you can view our Vagrant file to understand what all actions it will perform.

```
Vagrant.configure("2") do |config|

# Initial linux distro 
  config.vm.box = "ubuntu/jammy64"

# commands to be executed once the VM is provisioned
  config.vm.provision "shell" , inline: <<-END 

# update the system dependencies
  apt-get update

# Install the apache webserver
  apt-get install -y apache2

# copy over website content to where apache keeps the default site content.
  if ! [ -L /var/www ]; then
    rm -rf /var/www/html
    cp -r /vagrant/website/  /var/www/html
  fi
  echo "Container provisioned at $(date)! Welcome "
  END
# port forwarding to make the site accessible out of the VM
  config.vm.network "forwarded_port", guest:80, host:4567
end

``` 
 
if you run `vagrant up` with `Vagrantfile` same as the above code, you would be able to do achieve all the things that are discussed in this blog.


### References 
https://www.tutorialworks.com/linux-vm-vagrant/