Packages, Files, and Services II (nginx)
Puppet
In Puppet, the combined configuration to be applied to a host is called a catalog, and the process of applying it is called a run.
The Puppet client software is called the agent. Puppet calls the definition of the
host itself a node. The Puppet server is called the master.
The following code declares a resource of type service:
class nginx { package { 'apache2.2-common': ensure => absent, } package { 'nginx': ensure => installed, require => Package['apache2.2-common'], } service { 'nginx': ensure => running, require => Package['nginx'], } }
The first part of the code:
package { 'apache2.2-common': ensure => absent, }
On Ubuntu, the default setup includes the Apache web server, which would conflict with nginx if we tried to run it at the same time. So by specifying ensure => absent, we remove the Apache package.
The middle section declares the nginx package:
package { 'nginx': ensure => installed, require => Package['apache2.2-common'], }
The require attribute tells Puppet that this resource depends on another resource, which must be applied first. In this case, we want the removal of Apache to be applied before the installation of nginx.
In the last part, we declare the nginx service:
service { 'nginx': ensure => running, require => Package['nginx'], }
Service resources manage daemons, or background processes, on the server. The ensure attribute tells Puppet what state the service should be in:
ensure => running,
Though nginx is installed and running, but it's not serving a website yet. To do that, we have to have Puppet install a config file on the server to define an nginx virtual host. This will tell nginx how to respond to requests for the 'bogo' website.
We'll create a simple website for nginx to serve:
- Create the directory /var/www/bogo:
ubuntu@ip-172-31-45-62:~$ sudo mkdir -p /var/www/bogo
- Add an HTML file:
ubuntu@ip-172-31-45-62:~$ sudo su -c 'echo "bogo site" >/var/www/bogo/index.html'
- Now we want to create the virtual host file for Puppet to deploy.
Create the directory modules/nginx/files:ubuntu@ip-172-31-45-62:~$ sudo mkdir -p modules/nginx/files
- Create the file modules/nginx/files/bogo.conf with the
following contents:
server { listen 80; root /var/www/bogo; server_name bogo.com; }
- Edit the file modules/nginx/manifests/init.pp so it looks like this:
class nginx { package { 'nginx': ensure => installed, } service { 'nginx': ensure => running, require => Package['nginx'], } file { '/etc/nginx/sites-enabled/default': source => 'puppet:///modules/nginx/bogo.conf', notify => Service['nginx'], } }
file { '/etc/nginx/sites-enabled/default':
This line declares a file resource with the path /etc/nginx/sites-enabled/default.
source => 'puppet:///modules/nginx/bogo.conf',
source is a file attribute that tells Puppet where to find a copy of the file:puppet:///modules/nginx/bogo.conf
This looks like a URL, but it tells Puppet to look in the modules/nginx/files directory for a file named cat-pictures.conf.
notify is an attribute that tells Service['nginx'] to restart whenever there is change.
notify => Service['nginx'],
- Run puppet and make sure everything worked properly, request the website:
ubuntu@puppet-agent:~$ sudo puppet agent --test Info: Retrieving plugin Info: Caching catalog for puppet-agent.ec2.internal Info: Applying configuration version '1419914163' Notice: /Stage[main]/Exec/Exec[Run a command]/returns: executed successfully Notice: Finished catalog run in 0.29 seconds ubuntu@puppet-agent:~$ netstat -antlp (No info could be read for "-p": geteuid()=1000 but you should be root.) Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 172.31.43.38:22 64.71.28.178:37040 ESTABLISHED - tcp6 0 0 :::22 :::* LISTEN - ubuntu@puppet-agent:~$ curl localhost <html> <head><title>404 Not Found</title></head> <body bgcolor="white"> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.4.6 (Ubuntu)</center> </body> </html>
The following covers most services:
class NAME { package { NAME: ensure => installed, } service { NAME: ensure => running, require => Package[NAME], } file { '/etc/NAME.conf': source => 'puppet:///modules/NAME/NAME.conf', notify => Service[NAME], } }
- The service NAME should be running
- Before the service NAME is started, the package NAME should be installed
- Before the service NAME is started, the file /etc/NAME.conf should be present (remember that "A notifies B" implies "B requires A")
- If the file /etc/NAME.conf changes, restart the service NAME
Puppet
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization