in software development
$ vagrant up
Create and configure lightweight, reproducible, and portable development environments.
one single config file
Vagrantfile
vagrant up # start vm(s) vagrant ssh # login vagrant halt # stop vm(s) vagrant destroy # delete vm(s)
vagrant init vagrant package # create new box from current vm state
vagrant #or vagrant help {command}
mkdir vagrant-tutorial cd vagrant-tutorial vagrant init hashicorp/precise32 vagrant up vagrant ssh- pwd - top - ls /vagrant - exit - vagrant halt
Vagrantfile
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "hashicorp/precise32" end
# -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. # Every Vagrant virtual environment requires a box to build off of. config.vm.box = "precise32" # The url from where the 'config.vm.box' box will be fetched if it # doesn't already exist on the user's system. # config.vm.box_url = "http://domain.com/path/to/above.box" # Create a forwarded port mapping which allows access to a specific port # within the machine from a port on the host machine. In the example below, # accessing "localhost:8080" will access port 80 on the guest machine. # config.vm.network :forwarded_port, guest: 80, host: 8080 # Create a private network, which allows host-only access to the machine # using a specific IP. # config.vm.network :private_network, ip: "192.168.33.10" # Create a public network, which generally matched to bridged network. # Bridged networks make the machine appear as another physical device on # your network. # config.vm.network :public_network # If true, then any SSH connections made will enable agent forwarding. # Default value: false # config.ssh.forward_agent = true # Share an additional folder to the guest VM. The first argument is # the path on the host to the actual folder. The second argument is # the path on the guest to mount the folder. And the optional third # argument is a set of non-required options. # config.vm.synced_folder "../data", "/vagrant_data" # Provider-specific configuration so you can fine-tune various # backing providers for Vagrant. These expose provider-specific options. # Example for VirtualBox: # # config.vm.provider :virtualbox do |vb| # # Don't boot with headless mode # vb.gui = true # # # Use VBoxManage to customize the VM. For example to change memory: # vb.customize ["modifyvm", :id, "--memory", "1024"] # end # # View the documentation for the provider you're using for more # information on available options. # Enable provisioning with Puppet stand alone. Puppet manifests # are contained in a directory path relative to this Vagrantfile. # You will need to create the manifests directory and a manifest in # the file precise32.pp in the manifests_path directory. # # An example Puppet manifest to provision the message of the day: # # # group { "puppet": # # ensure => "present", # # } # # # # File { owner => 0, group => 0, mode => 0644 } # # # # file { '/etc/motd': # # content => "Welcome to your Vagrant-built virtual machine! # # Managed by Puppet.\n" # # } # # config.vm.provision :puppet do |puppet| # puppet.manifests_path = "manifests" # puppet.manifest_file = "site.pp" # end # Enable provisioning with chef solo, specifying a cookbooks path, roles # path, and data_bags path (all relative to this Vagrantfile), and adding # some recipes and/or roles. # # config.vm.provision :chef_solo do |chef| # chef.cookbooks_path = "../my-recipes/cookbooks" # chef.roles_path = "../my-recipes/roles" # chef.data_bags_path = "../my-recipes/data_bags" # chef.add_recipe "mysql" # chef.add_role "web" # # # You may also specify custom JSON attributes: # chef.json = { :mysql_password => "foo" } # end # Enable provisioning with chef server, specifying the chef server URL, # and the path to the validation key (relative to this Vagrantfile). # # The Opscode Platform uses HTTPS. Substitute your organization for # ORGNAME in the URL and validation key. # # If you have your own Chef Server, use the appropriate URL, which may be # HTTP instead of HTTPS depending on your configuration. Also change the # validation key to validation.pem. # # config.vm.provision :chef_client do |chef| # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" # chef.validation_key_path = "ORGNAME-validator.pem" # end # # If you're using the Opscode platform, your validator client is # ORGNAME-validator, replacing ORGNAME with your organization name. # # If you have your own Chef Server, the default validation client name is # chef-validator, unless you changed the configuration. # # chef.validation_client_name = "ORGNAME-validator" end
one missing config entry
config.vm.hostname = "hello.example.com"
/vagrant
vagrant reload
vagrant destroy vagrant up
Edit the Vagrantfile
add line
config.vm.hostname = "jap1.zuehlke.ch"
uncomment and edit line
config.vm.network "private_network", ip: "192.168.33.11"
uncomment the section and edit the memory line
config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--memory", "512"] end
Create a file
echo "Hello" > helloWorld.txt
test
$ vagrant up $ vagrant ssh $ hostname -f $ top $ ls /vagrant $ exit
optional
ssh vagrant@192.168.33.11 Password: vagrant
Provisioners in Vagrant allow you to automatically install software, alter configurations, and more on the machine as part of the vagrant up process
Supported provisioner:
The Vagrantfile already contains some examples
# Enable provisioning with Puppet stand alone. Puppet manifests # are contained in a directory path relative to this Vagrantfile. # You will need to create the manifests directory and a manifest in # the file default.pp in the manifests_path directory. # # config.vm.provision "puppet" do |puppet| # puppet.manifests_path = "manifests" # puppet.manifest_file = "site.pp" # end
Adding this line to the configuration...
config.vm.provision "shell", inline: "echo Hello, World"
will print out a message on first startup
$ vagrant destroy $ vagrant up ==> default: Hello, World or $ vagrant provision
Puppet is a declarative, model-based approach to IT automation, helping you manage infrastructure throughout its lifecycle, from provisioning and configuration to orchestration and reporting.
Using Puppet, you can easily automate repetitive tasks, ...
Puppet can run in two modes:
site.pp is the main() in puppet
- Define modules and reference them from nodes.pp - Work with templates to reuse your module - Ruby templates - http://docs.puppetlabs.com/guides/templating.htmlDesign your system by defining resources like:
The documentation is your friend!
type { 'resource-title': attribute => 'value' }
The resource-title must be unique!?
file { '/var/tmp/helloWorld.txt': mode => 644, user => vagrant, group => vagrant, ensure => file, content => 'Hello world!' }
node 'basic-server' { file { '/etc/hosts': ensure => file, content => ' 192.168.33.10 jap.zuehlke.ch 192.168.33.11 jap1.zuehlke.ch 192.168.33.12 jap2.zuehlke.ch ' } } node 'jap1', 'jap1.zuehlke.ch' inherits 'basic-server' { package { 'curl': ensure => present } }
aptitude updateto the shell provisioning
/var/lib/tomcat7/webapps/ROOT/index.html
sudo puppet apply site.ppFind packages with
aptitude search {text}Define the installation order
require => Package['curl'],
config.vm.provision "shell", inline: "aptitude update"
Uncomment puppet standalone in Vagrantfile
config.vm.provision "puppet" do |puppet| puppet.manifests_path = "manifests" puppet.manifest_file = "site.pp" end
manifests/site.pp
node 'jap1', 'jap1.zuehlke.ch' { package { 'tomcat7': ensure => present } file { '/var/lib/tomcat7/webapps/ROOT/index.html': require => Package['tomcat7'], content => 'Hello JAP' } }
Mount and link!
- Mount with Vagrant - Link with PuppetCreate a webapplication
mvn archetype:generate \ -DgroupId=ch.zuehlke.jap \ -DartifactId=jap-app \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
Build it
cd jap-app mvn clean install
Log into your VM
vagrant ssh
/var/lib/tomcat7/webappsto the real war file.
file { '/var/lib/tomcat7/webapps/jap-app.war': ensure => link, target => '/vagrant/jap-app/target/jap-app.war', require => Package['tomcat7'] }
Run puppet to install the link
$ sudo puppet apply manifests/site.pp
Test your application. Browse to http://192.168.33.11:8080/jap-app/
$ vagrant destroy $ vagrant up
Browse to:
VMs can be exported and can be used as the base VM for other Vagrant projects.
$ vagrant package $ vagrant box add jap-app-dev package.box $ vagrant box list
Use the new box
$ mkdir jap-box-demo $ cd jap-box-demo $ vagrant init jap-app-dev
Think about: