You can use the plethora of Vagrant Boxes available online, but there are times that you want/need to create your own Vagrant Box, based on specific requirements, with specific packages and most importantly with a specific ssh key pair.
In this guide I will walk through the process of creating a Vagrant BOX from scratch. I will be using a Mac with VMware Fusion and my Vagrant Box will be based on RHEL/CentOS.
1)Create a kickstart configuration file that you will use to automate the installation.
You can do it manually but I prefer/recommend using a kickstart file because you are software-defining the resulting machine and you can source control it. I placed the kickstart on a web server, in this case in my own Mac system so that it is reachable by the VM during installation.
Pre-requisites:
root password:
You can use the password ‘vagrant‘ as is on the kickstart, or you can provide the SHA512 hash of the root password you want. You can do this in several ways from a Linux terminal
mkpasswd -m sha-512 OR python -c 'import crypt; print crypt.crypt("password", "$6$somesalt$")' //You then place this hash in the kickstart below, for example: // rootpw --iscrypted $6$AcXXXXXX$ZfE9iCSvnezqs3/t47dcPRxozcWACkdITx38T.oTMESLzVv8yjSm1pVE4JC5FmdGojpg8StRhfi.peduXXXXX
SSH key pair:
You need to create a key pair that you will use for Vagrant. The way it works is that the generated public key will be added to the authorized keys allowed to ssh as the user ‘vagrant’ in the custom Vagrant BOX while the vagrant software on the host(Mac) will use the private key to connect from the host(Mac) to the Vagrant BOX(vm)
You can create the ssh key pair as follows:
ssh-keygen -t rsa -C "Vagrant" -f 'vagrant_rsa' // You then place the contents of vagrant_rsa.pub on the kickstart below, replacing the XXXX.....'s
Once you have the password and SSH keys, you can use the below kickstart (replacing the password and SSH public key accordingly)
# ks.cfg install cdrom text lang en_US.UTF-8 keyboard us network --onboot yes --device eth0 --bootproto dhcp --noipv6 rootpw vagrant firewall --disabled authconfig --enableshadow --passalgo=sha512 selinux --disabled timezone --utc America/New_York bootloader --location=mbr --driveorder=sda --append="crashkernel=auto" zerombr clearpart --initlabel --drives=sda --all part /boot --fstype=ext4 --size=500 part pv.100 --grow --size=1 volgroup vg0 --pesize=4096 pv.100 logvol swap --name=lv_swap --vgname=vg0 --size=2048 logvol / --fstype=ext4 --name=lv_root --vgname=vg0 --grow --size=1024 poweroff ## Install needed software (this is for ESX5/Fusion5 compatibility) repo --name=vmware-tools-collection --baseurl=http://packages.vmware.com/tools/esx/5.0u3/rhel6/x86_64 %packages --nobase @core vmware-tools-hgfs vmware-tools-esx-nox openssh-clients %end %post ############################### BEGIN post-kickstart actions # See: https://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html /bin/rm -f /etc/udev/rules.d/70-persistent-net.rules /bin/ln -s /dev/null /etc/udev/rules.d/70-persistent-net.rules /bin/rm -rf /dev/.udev/ /bin/rm /lib/udev/rules.d/75-persistent-net-generator.rules # Clean hardcoded MAC address /bin/sed -i -e 's/^HWADDR=.*$//' -e 's/^UUID=.*$//' /etc/sysconfig/network-scripts/ifcfg-eth0 # Make boot verbose /bin/sed -i -e 's/^splash/#splash/' -e 's/^hidden/#hidden/' -e 's/rhgb//' -e 's/quiet//' /boot/grub/grub.conf # Remove screensaver/blank screen /bin/sed -i -r s/"(^[\t]*kernel.*)"/"\1 consoleblank=0"/ /boot/grub/grub.conf ### BEGIN: Vagrant specific pre-requisites ### # Enable vmhgfs /bin/echo "modprobe vmhgfs" > /etc/sysconfig/modules/vmhgfs.modules /bin/chmod +x /etc/sysconfig/modules/vmhgfs.modules # Create vagrant user /usr/sbin/useradd vagrant /bin/mkdir /home/vagrant/.ssh /bin/chmod 700 /home/vagrant/.ssh cat > /home/vagrant/.ssh/authorized_keys <<'VAGRANT_RSA' ssh-rsa XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX vagrant VAGRANT_RSA /bin/chmod 600 /home/vagrant/.ssh/authorized_keys /bin/chown -R vagrant /home/vagrant/.ssh ## Allow vagrant user to sudo /bin/sed -i -e 's/Defaults[[:space:]]*requiretty/###Allow vagrant user to sudo\nvagrant ALL=(ALL:ALL) NOPASSWD:ALL\nDefaults requiretty\nDefaults:vagrant !requiretty/' /etc/sudoers ### END: Vagrant specific pre-requisites ### # Clean yum stuff to make resulting machine leaner yum clean all ############################### END post-kickstart actions %end
2) Creating the custom VM
Add new VM
Create a custom virtual machine
Click on Customize settings
Select 1CPU and 1GB of RAM (The VM should be as minimal as possible, you can increase CPU and RAM from Vagrant)
Disable unnecessary stuff (print sharing, bluetooth, sound card)
3) Start installation
Boot VM and add the RHEL/CentOS ISO disk (Choose Disc or Disc Image...)
Point to the kickstart file served by the web server
Installation will proceed and the VM will be powered off (based on the kickstart 'poweroff' option)
4) Once VM is off Disable CD drive
5) Quit VMware Fusion (this is to clear the lock files so that you have a pristine VM)
6) Difragment and Shrink the VMDK
john@mac:~$ /Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -d ~/Documents/Virtual\ Machines.localized/vagrant_rhel6_64.vmwarevm/Virtual\ Disk.vmdk Defragment: 100% done. john@mac:~$ /Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager -k ~/Documents/Virtual\ Machines.localized/vagrant_rhel6_64.vmwarevm/Virtual\ Disk.vmdk Shrink: 100% done. Shrink completed successfully.
7) On the folder where the virtual machine was created, create the following metadata.json file:
john@mac:~/Documents/Virtual Machines.localized/vagrant_rhel6_64.vmwarevm $ printf "{\n\t\"provider\":\"vmware_desktop\"\n}\n" > metadata.json john@mac:~/Documents/Virtual Machines.localized/vagrant_rhel6_64.vmwarevm $ cat metadata.json { "provider":"vmware_desktop" }
8) Create the Vagrant box container
john@mac:~/Documents/Virtual Machines.localized/vagrant_rhel6_64.vmwarevm $ tar cvzf vagrant-rhel6.box ./* a ./Virtual Disk-s001.vmdk a ./Virtual Disk-s002.vmdk a ./Virtual Disk-s003.vmdk a ./Virtual Disk-s004.vmdk a ./Virtual Disk-s005.vmdk a ./Virtual Disk-s006.vmdk a ./Virtual Disk-s007.vmdk a ./Virtual Disk-s008.vmdk a ./Virtual Disk-s009.vmdk a ./Virtual Disk-s010.vmdk a ./Virtual Disk-s011.vmdk a ./Virtual Disk.vmdk a ./metadata.json a ./vagrant_rhel6_64.nvram a ./vagrant_rhel6_64.plist a ./vagrant_rhel6_64.vmsd a ./vagrant_rhel6_64.vmx a ./vagrant_rhel6_64.vmxf a ./vmware.log
9) Add the Box to Vagrant
john@mac:~$ vagrant box add -name vagrant-rhel6 ~/Documents/workspace/vagrant/boxes/vagrant-rhel6.box ==> box: Adding box 'vagrant-rhel6' (v0) for provider: box: Downloading: file:///Users/john/Documents/workspace/vagrant/boxes/vagrant-rhel6.box ==> box: Successfully added box 'vagrant-rhel6' (v0) for 'vmware_desktop'!
Note: You can also add this Vagrant Box to a webserver so that it can be shared with others, in my case I uploaded the Box to a web server:
john@mac:~$ scp ~/Documents/workspace/vagrant/boxes/vagrant-rhel6.box john@webserver:/var/www/html/vagrant/
Update: You can create a Vagrant Box Catalog that will allow versioning of the Boxes and allows the end-users/developers to get automatic update notifications when you have an updated Vagrant box: Versioning and Update Notifications for your Vagrant boxes
Comments
Leave a comment Trackback