devxlogo

Vagrant Provisioning with Puppet

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.

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:

	ServerName dev.local	ServerAdmin webmaster@localhost	DocumentRoot /vagrant	ErrorLog /vagrant/error.log	CustomLog /vagrant/access.log combined	            Require all granted            AllowOverride All            Options FollowSymlinks        

Finally, let’s create a MySQL database:

exec {'create-db':    command => '/usr/bin/mysql -u root  [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  [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!

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist