In my environment I have Vmaware ESXi Free Edition and want to automate instalation and configuration of virtual machines. I choose Vagrant by HashiCorp.
What is Vagrant
Vagrant is a tool for building and managing virtual machine environment in a single workflow.
Vagrant provides easy to configure, reproducible, and portable work environments regardless of your role as a developer, operator, or designer to help maximize the productivity and flexibility. Machines are provisioned on top of VirtualBox, VMware, AWS, or any other provider. It leverages a declarative configuration file then, industry-standard provisioning tools such as shell scripts, Chef, Puppet or Ansible can automatically install and configure software, users, operating system configuration, etc. on the virtual machine.
Install Vagrant
I’m using OpenSuse Tumbleweed, so it is trivial to install Vagrant from repo.
gotanbl~:>sudo zypper in vagrant
Also, you could download and install vagrant from it’s official download page.
Install plugin for Vmware ESXi
To use this functionality we extend Vagrant with vagrant-vmware-esxi plugin.
First, install plugin:
gotanbl~:>vagrant plugin install vagrant-vmware-esxi
If you have conflicting dependencies with some package(example nokogiri) during install, start install with this command:
VAGRANT_DISABLE_STRICT_DEPENDENCY_ENFORCEMENT=1 vagrant plugin install vagrant-vmware-esxi
This variable you could use for install all other plugins.
After successfully installed plugin, verify that is on list of plugins.
gotanbl~:>vagrant plugin list
Requirements need to use plugin
- ovftool from VMWare, find it on VMWare ovftool download, need to have VMWare account
- Enable ssh access on VMWare ESXi host
- Boxes must have open-vm-tools or vmware-tools installed to properly transition to the ‘running’ state
- DHCP server on network where you installed machines
How to use plugin
Create directory where you store config and run
gotanbl~:>mkdir DIR && cd DIR
gotanbl~:>vagrant init
Command vagrant init create file Vagrantfile that you need to configure.
Next step is to provision our virtual machine from configuration.
gotanbl~:>vagrant up --provider=vmware_esxi
root@IP password:
Bringing machine 'default' up with 'vmware_esxi' provider...
==> default: Virtual Machine will be built.
VMware ovftool 4.2.0 (build-5965791)
==> default: --- --- ESXi Summary ---
==> default: --- ESXi host : IP
==> default: --- Virtual Network : ["VM Network"]
==> default: --- Disk Store : datastore1
==> default: --- Resource Pool : /
==> default: --- --- Guest Summary ---
==> default: --- VM Name : vagrant-test
==> default: --- Box : centos/7
==> default: --- Box Ver : 2004.01
==> default: --- Memsize (MB) : 2048
==> default: --- CPUS : 2
==> default: --- Nic Type : e1000
==> default: --- Guest OS type : centos7-64
==> default: --- --- Guest Build ---
Opening VMX source: /home/gotanbl/.vagrant.d/boxes/centos-VAGRANTSLASH-7/2004.01/vmware_desktop/ZZZZ_vagrant-test.vmx
Opening VI target: vi://root@IP:443/
Deploying to VI: vi://root@IP:443/
Transfer Completed
Completed successfully
==> default: --- VMID : 68
==> default: --- VM has been Powered On...
==> default: --- Waiting for state "running"
==> default: --- Success, state is now "running"
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Rsyncing folder: /home/gotanbl/vagrant/ => /vagrant
==> default: Running provisioner: shell...
default: Running: inline script
==> default: Running provisioner: ansible...
default: Running ansible-playbook...
How to configure Vagrantfile
Under Vagrant.configure(“2”) do |config| choose and specify box you want use, publicly available boxes that other makes or make your box(create box).
Vagrant.configure("2") do |config|
config.vm.box = "generic/centos7"
At this section you could specify version of box, does box update, configure network or sync folder - disable this
config.vm.synced_folder('.', '/vagrant', type: 'nfs', disabled: true)
#config.vm.synced_folder('.', '/vagrant', type: 'rsync', disabled: true)
# no need to disable both, one of them, depends on box used
Configure esxi provider, under config.vm.provider :vmware_esxi do |esxi|:
- esxi hostname or ip address
- esxi username and password
- guest name
- network
- datastore
- number of processors and amount of memory
- guest os and virtual machine version
- nic type
Example of config:
config.vm.provider :vmware_esxi do |esxi|:
esxi.esxi_hostname = 'IP'
esxi.esxi_username = 'root'
esxi.esxi_password = 'prompt:'
esxi.esxi_virtual_network = ['VM Network']
esxi.esxi_disk_store = 'datastore1'
#esxi.guest_boot_disk_size = 10 -> if you have additional disk
esxi.guest_name = 'vagrant_test'
esxi.guest_guestos = 'centos7-64'
esxi.guest_virtualhw_version = '13'
esxi.guest_memsize = '2048'
esxi.guest_numvcpus = '2'
Next is configuration of newly created Virtual Machine, example via bash and Ansible. It is possible to combine tools for configuration.
config.vm.provision "shell", inline: <<-SHELL
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
sed -in "s/PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
systemctl restart sshd
SHELL
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
end
You could add shell commands to script, put it in same folder as Vagrantfile.
Ansible playbook is also in Vagrantfile’s folder.
Access to VM through ssh is possible with:
gotanbl~:>ssh vagrant@IP # password is vagrant
gotanbl~:>ssh vagrant@IP -i INSECURE_PRIVATE_KEY
or Vagrant way
gotanbl~:>vagrant ssh
If you have error using insecure private key created during provisioning add this to VagrantFile under Vagrant.configure(2) do |config|
Vagrant.configure(2) do |config|
config.ssh.insert_key = false
Multimachine Vagrantfile
To create more than one virtual machine, Vagrantfile is as follows(source from creator of plugin on Github, multimachine Vagrantfile):
nodes = {
"vm-multi1" => ["generic/centos7", 1, 1024, NEXT_PARAM ],
"vm-multi2" => ["generic/centos7", 2, 2048, NEXT_PARAM ],
"vm-multi3" => ["bento/ubuntu-16.04", 2, 2048, NEXT_PARAM ],
}
Vagrant.configure(2) do |config|
nodes.each do | (name, cfg) |
box, numvcpus, memory, NEXT_PARAM = cfg
config.ssh.insert_key = false
config.vm.define name do |machine|
machine.vm.box = box
machine.vm.hostname = name
#machine.vm.synced_folder('.', '/Vagrantfiles', type: 'rsync')
machine.vm.provider :vmware_esxi do |esxi|
esxi.esxi_hostname = 'IP'
esxi.esxi_username = 'root'
esxi.esxi_password = 'prompt:'
esxi.esxi_virtual_network = "VM Network"
esxi.guest_numvcpus = numvcpus
esxi.guest_memsize = memory
esxi.guest_virtualhw_version = '13'
#esxi.guest_boot_disk_size = 40
esxi.esxi_disk_store = 'datastore1'
#esxi.guest_storage = storage
#esxi.clone_from_vm = box
SOME_CONFIG = NEXT_PARAM
end
machine.vm.provision "shell", inline: <<-SHELL
COMMANDS
SHELL
end
machine.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
end
end
end
end
This config will create 3 virtual machines. After creation, execute shell commands and ansible playbook.
In nodes variable is possible to define as much paramethers as we need. Must be declared at cfg variable definition and must be used in config file!
Useful commands
To access VM, command is vagrant ssh, and to destroy VM, command is vagrant destroy.
Other commands are:
- vagrant status
- vagrant suspend
- vagrant resume
- vagrant ssh-config
- vagrant snapshot push
- vagrant snapshot list
- vagrant snapshot-info
- vagrant halt
- vagrant provision
- vagrant address