2

I've been using Vagrant with Ansible to perform certain ETL tasks. This has provided some flexibility and transparency: jobs can be easily be moved around and the YAML playbook provides some level of documentation.

Here's a minimal example of the Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "hashicorp/precise64"

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "vagrantCronjobPlaybook.yml"
  end

end

... and the Ansible playbook:

# vagrantCronjobPlaybook.yml
- hosts: all
  user: vagrant
  sudo: True

    tasks:

    - name: leave the 'VM up' flag
      shell: "touch /vagrant/done"

    - name: shutdown the box
      shell: shutdown now

Ideally, I'd like to provision a box to perform some long-running task and, once it's complete, destroy the Vagrant box or at least power off. I tried adding a shutdown now to the playbook, but that didn't stop the VM. When I run this manually:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[... 'all is well' messages removed]
    default: /vagrant => /Users/awoolford/Documents/vagrantCronjob
==> default: Running provisioner: ansible...

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [default]

TASK: [leave the 'VM up' flag] ************************************************ 
changed: [default]

TASK: [shutdown the box] ****************************************************** 
changed: [default]

PLAY RECAP ******************************************************************** 
default                    : ok=3    changed=2    unreachable=0    failed=0 

... I see that the task completes:

$ ls done
done

However, simply performing a 'shutdown now' in the Ansible playbook doesn't stop the VM from running:

$ vagrant status
Current machine states:

default                   running (virtualbox)

Quesion) Is it possible for a Vagrant VM to destroy itself or power itself off?

A colleague suggested that we create a RESTful endpoint on the host that, on completion of a long-running job, the guest makes a call that triggers a vagrant destroy in the folder of the Vagrant box. On AWS, we've done used Python's Flask and boto package to terminate boxes in a similar manner. This all seems a bit clunky and I'm wondering if there's a better solution.

2
  • Have you tried Ansible's local tasks?
    – ceejayoz
    Sep 10, 2014 at 3:35
  • Thanks @ceejayoz. Are you suggesting that the entire workflow be performed on the host machine rather than in a guest VM? I wanted to use transient virtual machines for flexibility (ease of moving the activities to other hardware as utilization increases), reliability (to avoid the situation where a 'greedy' activity might consume all the memory or CPU), and to keep the server fairly clean. Sep 10, 2014 at 21:45

1 Answer 1

2

I haven't used ansible, but if you can configure it to do your "work" as a provisioning step, then a simple vagrant up && vagrant destroy should take care of it.

Vagrant will create your VM, start it, provision it (doing your work tasks) then destroy it.

2
  • Thanks James. That's perfect. On my setup, the vagrant destroy needed an extra switch: vagrant destroy --force to avoid the following error Vagrant is attempting to interface with the UI in a way that requires a TTY. Sep 11, 2014 at 18:14
  • Also, on my box the cron entry was missing the path to the ansible executable (/usr/local/bin/) and so had to be added to the PATH, e.g. 09 00 * * * export PATH=/usr/local/bin/:$PATH; cd /Users/biggus/vagrantCronjob; sh vagrant up && vagrant destroy --force. Sep 11, 2014 at 18:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .