Managing files, directories, and templates

A very useful Chef feature is the ability to manage files right from the Chef code. Either plain files can be copied or dynamic files can be generated through templates. We'll leverage this feature to create an example PHP test file and dynamically generate Apache VirtualHosts for our LAMP server, so you'll know how to reuse it anywhere else.

Getting ready

To work through this recipe, you will need the following:

  • A working Chef DK installation on the workstation
  • A working Chef client configuration on the remote host
  • Optionally, the Chef code from the previous recipes

How to do it…

We'll manage two different kinds of files in two different ways: a static file and a dynamic file generated from a template, so the most common usage is covered.

Managing a simple static file

Let's begin by creating a basic PHP file that will only display the phpinfo() result. This is done using the simple file resource with the file path as argument, giving its content inline. Other optional properties of the file resource include ownership information or the file mode. Add a file resource to the php/recipes/default.rb recipe:

file '/var/www/html/phpinfo.php' do
  content '<?php phpinfo(); ?>'
  mode '0644'
  owner 'root'
  group 'root'
end

Don't forget to bump the version in php/metadata.rb:

version '0.2.0'

Upload the new cookbook from your workstation:

$ knife cookbook upload php

Deploy using the Chef client on the remote node:

$ sudo chef-client

If you now navigate to http://node-hostname/phpinfo.php, you'll see the PHP information displayed.

This is the most static way of shipping a plain file.

Managing dynamic files and directories from a template

Let's now create a generic Apache virtual host to fully control what we'll do with our LAMP server, and not just live with the default configuration shipped with our Linux distribution. We want the website's root folder to be /var/www/<sitename> and the configuration file will live under /etc/httpd/conf.d/<sitename>.conf. We'll ship a sample HTML index file as well, to validate we're running the correct virtual host.

Start by generating a new recipe in the Apache cookbook using the chef command, to manage a default Virtual Host:

$ chef generate recipe cookbooks/apache virtualhost 

A new file named apache/recipes/virtualhost.rb is now created.

To store the name of our virtual host, let's create an attribute. An attribute is similar to a persisting node setting, declared in a cookbook in a file under the attribute directory, and can then be overridden by many mechanisms that we'll later discover. Start by generating an attributes file using the chef command:

$ chef generate attribute cookbooks/apache default

This will create a new file under apache/attributes/default.rb. To set the sitename attribute with default value of defaultsite, add the following in this file:

default["sitename"] = "defaultsite"

To create a new directory, let's use a resource named directory in the apache/recipes/virtualhost.rb file, with standard access rights. Note the Ruby #{node["sitename"]} syntax to access a node attribute from inside a string that will be recurring from now on:

directory "/var/www/#{node["sitename"]}" do
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

Let's reuse the file resource to create a basic index.html file with a simple string such as Hello from Chef! or whatever you find more appealing, in the apache/recipes/virtualhost.rb file:

file "/var/www/#{node["sitename"]}/index.html" do
  owner 'root'
  group 'root'
  mode '0644'
  content '<html><h1>Hello from Chef!</h1></html>'
end

Let's once again use the chef generator to create a new template for our Apache virtual host configuration file:

$ chef generate template cookbooks/apache virtualhost

This will create a template under apache/templates/ named virtuahost.erb. This is a standard ERB (short for Embedded Ruby) template. This template file will contain the virtual host Apache configuration for our site.

Let's start by populating the content of this ERB with a minimal Apache configuration file, using a new website variable that we'll set in a minute.

Note

A variable in an ERB template is prefixed with the @ character.

<VirtualHost *:80>
        ServerName <%= @website %>
        DocumentRoot /var/www/<%= @website %>
        ErrorLog /var/log/httpd/error-<%= @website %>.log
        CustomLog /var/log/httpd/access-<%= @website %>.log combined
        <Directory /var/www/<%= @website %>/ >
          Options Indexes FollowSymLinks MultiViews
          AllowOverride All
          Order allow,deny
          allow from all
        </Directory>
</VirtualHost>

This way, the whole configuration is dynamic; we'll be able to instantiate this cookbook for any site name of our choice and it will be dedicated to it.

Now let's use the template resource to generate a file from the template we just created, in the apache/recipes/virtualhost.rb file. This resource takes a source parameter, which is the template file we just created, and the variables to be injected. In our case, we want to inject the value of the sitename attribute, so it can be accessed by the template as @website:

template "/etc/httpd/conf.d/#{node["sitename"]}.conf" do
  source "virtualhost.erb"
  owner 'root'
  group 'root'
  mode '0644'
  variables(
    :website => "#{node["sitename"]}"
  )
end

Don't forget to bump the cookbook version in apache/metadata.rb:

version '0.3.0'

Upload the cookbook to Chef server from the workstation:

$ knife cookbook upload apache

Add the newly-created recipe to the remote node run list:

$ knife node run_list add <node name> apache::virtualhost

Apply the new cookbook on the remote host:

$ sudo chef-client

Restart the Apache server manually to take the changes into account (be sure we'll automate that in the next pages):

$ sudo systemctl restart httpd

Verify that the served page is the one we added:

$ curl http://node_ip_or_hostname/
<html><h1>Hello from Chef!</h1></html>

Good job! We've just covered how to manage files, directories, as well as dynamic templates, using pure Ruby code with Chef.

There's more…

Now that we have a LAMP server with Puppet, let's create a virtual host! Our goals are as follows:

  • Removing the default virtual host provided by Ubuntu
  • Creating our own virtual host, with a specific DocumentRoot and dedicated log files
  • Deploying a simple PHP page displaying the result of the function phpinfo()

These three operations will be done using the file directive.

On Ubuntu, we need to remove the default website in order to have virtual hosting up and running. This can be done easily in the Apache manifest; a file directive for the deletion of /etc/apache2/site-enabled/000-default.conf will remove the symlink and will disable the site:

class apache {
    package {'apache2':
       ensure => present,
    }

    service {'apache2':
       ensure => running,
       enable => true
    }

    file {'/etc/apache2/sites-enabled/000-default.conf':
       ensure => absent,
    }
}

Now let's create the code for the virtual host generation. The creation of a new virtual host must be done in /etc/apache2/sites-available, and will be generated from a template. Two languages are available:

  • ERB for Embedded Ruby.
  • EPP for Embedded Puppet (Puppet 4 and higher). Let's choose this one.

Our EPP template will use two parameters: the site name and the document root. Let's create a vhost.epp file in the modules/apache/templates directory:

<VirtualHost *:80>
  ServerName <%=$website%>
  DocumentRoot <%=$docroot%>
  <Directory <%=$docroot%>>
    Order deny,allow
    Allow from all
    AllowOverride All
  </Directory>
  ErrorLog /var/log/apache2/error-<%=$website%>.log
  CustomLog /var/log/apache2/access-<%=$website%>.log combined
</VirtualHost>

Now we need to instantiate this template. The best way is to think about something we could reuse as many times as needed (in case we would like to add more sites).

We previously used a class statement, but each class in Puppet can be used only once per catalog (remember, a catalog is the result of the compilation for a node). Fortunately, the define statement is used to define a block of code that can be used multiple times.

So let's define a file, module/apache/manifest/vhost.pp that will use such a statement:

define apache::vhost (
     $website,
     $docroot
) {

  file { "/etc/apache2/sites-available/$website.conf":
     ensure  => present,
     owner   => 'root',
     group   => 'root',
     mode    => '0640',
     content => epp('apache/vhost.epp',
                     {'website' => $website, 
                      'docroot'=>$docroot}),
  }

  file { "/etc/apache2/sites-enabled/$website.conf":
     ensure  => link,
     target  => "/etc/apache2/sites-available/$website.conf",
     require => File["/etc/apache2/sites-available/$website.conf"],
  }
}

The website name and the document root are the two parameters for our apache::vhost statement and are passed to the epp function along with the template file name in the first file directive.

On Ubuntu, to enable a site, a link must be created in /etc/apache2/site-enabled; the second file directive will handle it.

Finally, we need to deploy our PHP file under the DocumentRoot directory. This can be done directly in the main manifest using file directives to create the DocumentRoot directory and the file itself:

node 'web.pomes.pro' {
    $website=$fqdn;
    $docroot="/var/www/$fqdn";

    class {
      'apache':;
      'php':;
      'mariadb':;
    }
    apache::vhost {$website:
       website => $website,
       docroot => $docroot,
    }
    file { $docroot:
      ensure => directory,
      owner  => 'www-data',
      group  => 'www-data',
      mode   => '0755',
    }
    file {"$docroot/index.php":
      ensure  => present,
      owner   => 'www-data',
      group   => 'www-data',
      mode    => '0644',
      content => "<?php phpinfo() ?>",
    }
}

We can now run the Puppet agent again. For now, we need to restart Apache manually in order to have our virtual host running (as for Chef, we'll automate this in the next pages):

root@web:~# service apache2 reload

Now you should see the phpinfo page on http://web.pomes.pro

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.187.24