0
votes

I am writing some extensions to jfryman's nginx module.

I have a number of servers that have nginx installed, and have different sites:

e.g.

Live = site1.domain
Staging  = site1.staging.domain
Development = site1.development.domain, site2.development.domain, site3.development.domain (etc)

So, to save my sanity, I've created some module "extra" files, per the documentation : i.e., modules/nginx/manifests/amcustom/site1.pp etc.

Now - all these sites contain custom configurations for Nginx, so to make me not repeat the same code, I created the following as a "template" for the variables - and it is called ~/modules/nginx/manifests/amcustom/ux_std_vhost.pp and contain :

class  nginx::amcustom::ux_std_vhost {

        file { $nginx_dirs:
                ensure => 'directory',
                owner => 'gitpull',
                group => 'www-data',
                mode => 0750,
        }

        nginx::resource::vhost { "${webshortname}.${domain}":
                ensure  => present,
                rewrite_to_https => true,
                www_root        => "${full_web_path}/${webshortname}.${domain}/latest/",
                index_files     => [ 'index.html' ],
                location_cfg_append     => $location_cfg_append,
                ssl             => true,
                ssl_cert        => "puppet:///modules/nginx/$webshortname.$domain.nginx.crt",
                ssl_key         => "puppet:///modules/nginx/$webshortname.$domain.key",
                ssl_protocols   => 'TLSv1 TLSv1.1 TLSv1.2',
                ssl_ciphers     => '"EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH !EDH+aRSA !RC4 !a
NULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"',
        vhost_cfg_ssl_prepend   =>  {
                'add_header'   => '"Strict-Transport-Security" "max-age=15768000"'
                },
        location_raw_append     => [ 'if ($http_origin ~* (https?://[^/]*\.domain(:[0-9]+)?)) {', 'add_header "Access-Control-Allow-Origin" "$http_origin";', '}' ],
                }

}

What I need to do - is to use this one "Standard" file, and pass it variables for each of the sites:

 ~/amcustom/site1.pp
 ~/amcustom/site2.pp
...etc

The contents of these config files would be:

class nginx::amcustom::site1_config inherits nginx::amcustom::ux_std_vhost {
# Define my Variables:

        $full_web_path = [ '/var/sites' ]
        $webshortname  = [ 'site1' ]
        $domain        = [ 'domain' ]
        $location_cfg_append = undef
        $nginx_dirs = [ "$full_web_path/", "$full_web_path/$webshortname.$domain/" ]


        }

class nginx::amcustom::site1 {
        include ::nginx,nginx::amcustom::site1_config
        require users::amcustom::gitpull_ux
        }

Problem that I have is that the variables I have specified don't get passed to my class (detailed nginx::resource::vhost) and the error reported is:

puppet-agent[20280]: Failed to apply catalog: Parameter path failed on File[undef]: File paths must be fully qualified, not 'undef' at /etc/puppet/environments/development/modules/nginx/manifests/amcustom/ux_std_vhost.pp:8

The puppet documentation is currently melting my head with this, so some easy to understand help would really be appreciated.

TIA.

AM

2

2 Answers

0
votes

Puppet class inheritance does not work that way. The subclass can override properties of resources declared by its parent (or more distant ancestor), and it can see the values of their variables, but it cannot cause them to see different values for their variables than they otherwise would. In fact, the parent class is fully evaluated before the subclass, which characteristic is exploited to implement the params class pattern.

Class inheritance for any other purpose than the params class pattern is widely considered poor style these days. Automatic data binding (via Hiera) solves pretty much all the other problems that class inheritance ever did, and more. Supposing that you're running at least Puppet 3.0 (latest is 4.3) you can make automatic data binding work for you, too. The main change to your class would be to make the adjustable variables it relies upon into class parameters. You would then need to configure your Hiera data repository to provide the appropriate values in each node's context.

0
votes

You've got the wrong approach here. You don't create "class templates" and inherit them to build specific variants.

A manifest "template" if you will is created as a defined type. It does not need to live in the nginx module either. It would be wise to just leave that in its upstream state. Add your own module.

define my_site_nginx::vhost($nginx_dirs,$webshortname,$domain,...) {
    file { $nginx_dirs: ... }
    nginx::resource::vhost { "${webshortname}.${domain}":
            ensure  => present,
            ...
    }
}