Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Vagrant Provisioning with Puppet

Automating software installations is an important part of deploying virtual machines with Vagrant. This process is called provisioning and can be integrated with DevOps tools, such as Puppet. Let's see how to do that.


advertisement

Automating software installations is an important part of deploying virtual machines with Vagrant. This process is called provisioning and can be integrated with DevOps tools, such as Puppet. Let's see how to do that.

Vagrantfile Configuration

The configuration for any Vagrant virtual machine is in the Vagrantfile. This is where we will instruct Vagrant to use Puppet to install software or execute commands:

config.vm.provision "puppet" do | puppet |
    puppet.manifests_path = "puppet"
    puppet.manifest_file  = "main.pp"
end


Manifests path is the folder where the manifest file will be located, while the manifest file is the file which contains the Puppet commands. We have the following directory structure now:

|-- Vagrantfile
|-- puppet
    |-- main.pp

Manifest file uses its own configuration language, whose syntax is adapted to sysadmins and DevOps professionals. The main units of the manifest files are resources. There are many types of resources, while the most common are: exec, package, service and file. Exec executes a shell command, package installs a package (e.g. through apt or yum), service manages running services and file is used for file management. Let's see how declaring resources works in a practical example.

Provisioning a Web Server

Vagrant is often used by developers to quickly set up a development environment, that would be similar to the production environment. That usually includes provisioning the LAMP stack installation and configuration. We will start by updating the apt repositories:

exec {'apt-update':
    command => '/usr/bin/sudo /usr/bin/apt-get update'
}

Then, install PHP:

package {'php5':
    ensure => latest,
    require => Exec['apt-update']
}

According to the parameters outlined above, Puppet will install the php5 package from apt/yum, make sure that the latest version of the package has been downloaded and run the installation only after the update has been finished.

After that, we will install the PHP packages that are used very often, such as cURL, gd, imagick and others:

package {['php5-apcu', 'php5-cli', 'php5-common', 'php5-curl', 'php5-gd', 'php5-imagick', 'php5-intl', 'php5-json', 'php5-mcrypt', 'php5-mysql', 'php5-sqlite', 'php5-xdebug']:
    ensure => latest,
    require => Package['php5']
}

Once PHP and its libraries are ready, we will install Apache Web server and its PHP module:

package {'apache2':
    ensure => latest,
    require => Package['php5']
}

package {'libapache2-mod-php5':
    ensure => latest,
    require => [Package['apache2'], Package['php5']]
}

The last LAMP stack package that needs to be installed is the MySQL server:

package {'mysql-server':
    ensure => latest,
    require => Exec['apt-update']
}

Let's make sure that Apache and MySQL services are up and running:

service {'apache2':
  ensure => running,
  require => Package['apache2']
}

service {'mysql':
  ensure => running,
  require => Package['mysql-server']
}

At this point, the LAMP stack is successfully installed. However, the Puppet allows us to further configure the server in order to make it more convenient for developers. As the next step, we will install git:

package {'git':
    ensure => latest
}

Enable Apache mod_rewrite:

exec {'apache-mod-rewrite':
    command => '/usr/sbin/a2enmod rewrite',
    notify => Service['apache2'],
    require => Package['apache2']
}

Disable the default virtual host and create a new one:

exec {'apache-disable-default-site':
    command => '/usr/sbin/a2dissite 000-default',
    notify => Service['apache2'],
    require => Package['apache2']
}

file {'apache-dev-site':
    path => '/etc/apache2/sites-enabled/dev.conf',
    target => '/vagrant/puppet/assets/apache-dev.conf',
    notify => Service['apache2'],
    require => Package['apache2']
}

Note the path and target values. The path is the location of the file on the virtual machine, while the target is the location of the file on the host machine. That means that we will create an apache-dev.conf file in the assets folder on the host machine. During provisioning, that file will be copied to the virtual machine. Apache-dev.conf could look, for example, like this:

<VirtualHost *:80>
	ServerName dev.local

	ServerAdmin webmaster@localhost
	DocumentRoot /vagrant

	ErrorLog /vagrant/error.log
	CustomLog /vagrant/access.log combined

	<Directory /vagrant>
            Require all granted
            AllowOverride All
            Options FollowSymlinks
        </Directory>
</VirtualHost>

Finally, let's create a MySQL database:

exec {'create-db':
    command => '/usr/bin/mysql -u root < /vagrant/puppet/assets/database.sql',
    require => [Package['mysql-server'], Service['mysql']]
}

To create the database, we will import the SQL file from the host machine to the virtual machine. Let's create a file named database.sql, which contains the following SQL code:

create database if not exists development collate 'utf8_unicode_ci'; 

Wrap it up

The entire main.pp file will now look like this:

exec {'apt-update':
    command => '/usr/bin/sudo /usr/bin/apt-get update'
}

package {'php5':
    ensure => latest,
    require => Exec['apt-update']
}

package {['php5-apcu', 'php5-cli', 'php5-common', 'php5-curl', 'php5-gd', 'php5-imagick', 'php5-intl', 'php5-json', 'php5-mcrypt', 'php5-mysql', 'php5-sqlite', 'php5-xdebug']:
    ensure => latest,
    require => Package['php5']
}

package {'apache2':
    ensure => latest,
    require => Package['php5']
}

package {'libapache2-mod-php5':
    ensure => latest,
    require => [Package['apache2'], Package['php5']]
}

package {'mysql-server':
    ensure => latest,
    require => Exec['apt-update']
}

service {'apache2':
  ensure => running,
  require => Package['apache2']
}

service {'mysql':
  ensure => running,
  require => Package['mysql-server']
}

package {'git':
    ensure => latest
}

exec {'apache-mod-rewrite':
    command => '/usr/sbin/a2enmod rewrite',
    notify => Service['apache2'],
    require => Package['apache2']
}

exec {'apache-disable-default-site':
    command => '/usr/sbin/a2dissite 000-default',
    notify => Service['apache2'],
    require => Package['apache2']
}

file {'apache-dev-site':
    path => '/etc/apache2/sites-enabled/dev.conf',
    target => '/vagrant/puppet/assets/apache-dev.conf',
    notify => Service['apache2'],
    require => Package['apache2']
}

exec {'create-db':
    command => '/usr/bin/mysql -u root < /vagrant/puppet/assets/database.sql',
    require => [Package['mysql-server'], Service['mysql']]
}

The final step is to run vagrant up from terminal. After creating the virtual machine, Vagrant will automatically do the provisioning.

The Puppet commands mentioned in this tutorial are just the basic ones. For more information, take a look at the documentation.

Get paid for original Dev tips!


   
Vojislav is a web developer, designer and entrepreneur, based in Belgrade, Serbia. He has been working as a freelancer for more than 6 years, having completed more than 50 projects for clients from all over the worlds, specializing in designing and developing personal portfolios and e-commerce websites using Laravel PHP framework and WordPress content management system. Right now, he works as a full-time senior web developer in a company from Copenhagen.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date