In this post we will shed the light a little bit on vagrant provisioning. To be more practical we will go through a workflow to configure you host machine and keep all your vms in-sync with it (configuration wise).


  • git, we will use it to version control our dotfiles (configuration files) and especially to host (push / clone) them in a code hosting platform (github / gitlab / …).
  • GNU stow. It’s an awesome CLI tool built by GNU to manage symlink farms.
  • A bit of shell scripting knowledge
  • Vagrant of course, and a up & working virtual machine. (preferably Ubuntu ~ previous parts in the comments).

stow mini tutorial

The main things you want to know when it come to GNU stow are:

  • packages: a collection of files and directories which we want to administer (symlink). (specified with -S option)
  • stow directory: is the directory containing all the packages. (specified with -d option)
  • target directory: is the directory we want to symlink our packages to. (specified with -t option)

Although It depends on the stow version you’re using, most of the time the stow directory is the current directory by default and target directory is its parent in the file system. Finally there is 3 operation stowing, unstowing (delete), and restowing (delete and stow again). stow mini example Let consider this example folder structure

$ pwd/home/username/videos/movies$ tree.
├── django
|    └── django.mp4
├── enemy
│   ├── enemy.mp4
│   └──
├── her
│   └── her.mkv
└── whoami
├── whoami.mkv

In this example we will consider:

  • videos/ : our stow folder
  • movies/ : our package

What we want is the content of the movies folder to be accessible from our Desktop/ folder.

1$ stow -d /home/username/videos -S movies -t /home/usename/Desktop

and tada !!! when we check our Desktop we’ll find all the movies/ subfolders symlinked there. We can do this instead (command short form).

1$ cd /home/username/videos
2$ stow movies -t /home/usename/Desktop

Remember that the default stow dir is the current dir. -S short for –stow is optional.

Let the fun begin

First thing first, we open the Vagrantfile and add this:

1config.vm.provision "shell", path:"", privileged:false

This will tell vagrant to provision our vm using a shell script in the same folder as our vagrantfile. Then we create the shell script and grant it the x permission.

4STOW_DIR="$HOME/dotfiles"# TARGET_DIR="$HOME"# TARGET_DIR is redundant in this case because it's by default the STOW_DIR parent.
5DEPS='git stow curl'
6# install the script dependenciessudo apt updatesudo apt install -y $DEPS
7# install the package listcurl $PKGS_URL > $PKGS_FILEsudo apt install -y $(grep 'core' $PKGS_FILE | cut -f1 -d,)
8# install the dotfiles with stow (and git)git clone "${CONFIGS_URL}" "$STOW_DIR"cd $STOW_DIRstow -vv */cd -

Finally run

1vagrant provision

Vagrant provision will run our script against our vm. Provisioning !!

Ideas and Conclusion

The script is self explanatory. The first part is about installing the dependencies git, stow and curl. the last is about getting our dotfiles from a remote git repo and installing them with stow.

The ambiguous part is the the one in the middle. There we download a csv file containing the packages we want to install in our vm. the grep is to select only the packages tagged with core. you can use another format and filter the file your way of course.

!! The script is a POC (proof of concept), and it’s nowhere near ready to use. Do not use it in a machine you care about, you can start with a vagrant vm. and then extend the script to fit your needs.

I’m working on a more robust cross distro script. and I would love to hear your ideas.

Thank you for reading. see you next time.