Search code examples
cronvagrantvagrantfile

How do I set up a Vagrant box to always have a cron job?


How do I configure my Vagrant configuration so that when I provision a machine its crontab is automatically configured? (vagrant is provisioned according to Chef(?) files)

As an example, I wanted to have the following cron set up:

5 * * * * curl http://www.google.com

Solution

  • Basic provisioning for things like this can easily be done without Chef/Puppet/Ansible and instead using the shell.

    The Vagrant docs cover this basic provisioning pretty well for their example of having the box download Apache from a boostrap.sh.

    Similarly you could follow the same steps in editing your Vagrantfile to call a bootstrap.sh file when being provisioned:

    Vagrant.configure("2") do |config|
      ...
      config.vm.provision :shell, path: "bootstrap.sh"
      ...
    end
    

    You could then create a bootstrap.sh file in the same directory as your Vagrantfile which would contain something like:

    #!/bin/bash
    # Adds a crontab entry to curl google.com every hour on the 5th minute
    
    # Cron expression
    cron="5 * * * * curl http://www.google.com"
        # │ │ │ │ │
        # │ │ │ │ │
        # │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
        # │ │ │ └────────── month (1 - 12)
        # │ │ └─────────────── day of month (1 - 31)
        # │ └──────────────────── hour (0 - 23)
        # └───────────────────────── min (0 - 59)
    
    # Escape all the asterisks so we can grep for it
    cron_escaped=$(echo "$cron" | sed s/\*/\\\\*/g)
    
    # Check if cron job already in crontab
    crontab -l | grep "${cron_escaped}"
    if [[ $? -eq 0 ]] ;
      then
        echo "Crontab already exists. Exiting..."
        exit
      else
        # Write out current crontab into temp file
        crontab -l > mycron
        # Append new cron into cron file
        echo "$cron" >> mycron
        # Install new cron file
        crontab mycron
        # Remove temp file
        rm mycron
    fi
    

    By default Vagrant provisioners run as root so this will append a cron job to the root user's crontab assuming it doesn't already exist. If you want to add it to the vagrant user's crontab then you will need to run the provisioner with the privileged flag set to false:

    config.vm.provision :shell, path: "bootstrap.sh", privileged: false