Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

We have a base 'nginx' class, and nodes' classes include this base class and add their configuration files under /etc/nginx/conf.d

I'd like to have the nginx service subscribe to /etc/nginx/conf.d in a single location, so that people writing the nodes' classes don't have to remember to add notify => Service['nginx']. I've tried using this Puppet code below, but it didn't work (ie, after I modified application.conf, the nginx service wasn't reloaded).

Is this possible?

modules/nginx/init.pp

class nginx {
  package { 'nginx':
    ensure => installed,
  }

  service { 'nginx':
    ensure     => running,
    enable     => true,
    hasstatus  => true,
    hasrestart => true,
    require    => Package['nginx'],
    subscribe  => File['/etc/nginx', '/etc/nginx/conf.d'],
  }

  file { ['/etc/nginx', '/etc/nginx/conf.d']:
    ensure  => directory,
    owner   => application,
    group   => application,
    recurse => true,
  }
}

modules/application/init.pp

class application {    
  file {'/etc/nginx/conf.d/application.conf': 
    ensure  => present,
    owner   => application,
    group   => application,
    source  => 'puppet:///modules/application/application.conf',
    require => Package['nginx'],
  }
}
share|improve this question

3 Answers 3

With Puppet I've found that if the what you're doing does not work immediately, you're probably trying to do something that you shouldn't. In this case, you probably don't want each individual site just dropping a config file in nginx/conf.d. Instead, you'd want to create a defined resource that represents a nginx vhost. Within that resource you'd take care of dropping the correct configuration file into conf.d, and notifying the nginx service.

An advantage to doing this is you can standardize all the configuration you need. For example, most nginx sites are going to need gzip on. Let's say you forget this, would you rather make this change in your default template, or have to find every defined nginx config to change? Or lets say another vulnerability is found in the ciphers used for HTTPS. With one standard nginx config, that's one place you need to change it. With each application dropping it's own config file, you're going to be changing it everywhere.

share|improve this answer

Not sure if this'd work, but how about creating a simple exec that generates a single file based on the contents of the monitored directory, subscribe to that file, and then trigger your restart...

for example:

class nginx {
  package { 'nginx':
    ensure => installed,
  }

  service { 'nginx':
    ensure     => running,
    enable     => true,
    hasstatus  => true,
    hasrestart => true,
    require    => Package['nginx'],
    subscribe  => File['/etc/nginx', '/etc/nginx/conf.d'],
  }

  file { ['/etc/nginx', '/etc/nginx/conf.d']:
    ensure  => directory,
    owner   => application,
    group   => application,
    recurse => true,
  }


  exec { "/tmp/nginx-config-checksum":
    path    => "/usr/local/bin/:/bin:/usr/sbin",
    command => 'find /etc/nginx/conf.d | xargs md5sum > /tmp/nginx-config-checksum',
  }
  file { "/tmp/nginx-config-checksum"        
    notify  => Service['nginx']
  }
}
share|improve this answer

If you need to abstract out common functionality into something reusable, your best option is to create a defined type. Something like this should work:

define nginx::config_fragment (
  $group,
  $owner,
  $source,
) {
  file { "/etc/nginx/conf.d/${title}.conf":
    ensure => 'file',
    group  => $group,
    owner  => $owner,
    source => $source,
  }
}

Then, in your site.pp, set a default on your resource type:

Nginx::Config_fragment {
  group  => 'application',
  owner  => 'application',
  notify => Service['nginx'],
}

The file will notify the enclosing defined type whenever a refresh is triggered, which will then schedule a reload on the nginx service.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.