Accessing a variable within a previously declared instance of a defined type

puppet

I'm trying to define a static media server that uses a common website layout (e.g. with directories etc/, log/, html/, etc.), as well as an nginx config that will get included into a host-wide nginx config. The site's nginx config needs to make use of the doc root that gets defined by the declared layouts::website resource.

So, what I'd like to do is something like this:

class sites::static ($sites_dir) {

    $domain = "static.example.com"

    layouts::website {$domain:
        base_dir => $sites_dir,
        name => $domain,
    }

    nginx::siteconfig {$domain:
        domain => $domain,
        doc_root => $layouts::website[$domain]::doc_root,
    }
}

Which could then be used by declaring:

class {'sites::static': sites_dir => "/opt/sites"}

However, the above fails because the $layouts::website[$domain]::doc_root part is invalid. I've tried various alternatives here, unsuccessfully.

Is this possible? If not, how would you suggest I accomplish the stated goal of using a base layout that then needs to be used by various bits that will populate content within that base layout?

Best Answer

As far as I know, you can't get at variables inside defined resources.

I would approach this by reordering the resource type definitions and putting the nginx::siteconfig clause inside the layouts::website definition. (If every use of layouts::website should also have a nginx::siteconfig too, then nesting the one in the other is a good way to DRY.) If you need to have some cases where a use of layouts::website does not also have a nginx definition, you'll have to add a parameter to layouts::website, something like $nginx = true.

Also, the following bits of code:

layouts::website {$domain:
    name => $domain,
}

nginx::siteconfig {$domain:
    domain => $domain,
}

smell like unnecessary repetition to me. The website name and nginx domain seem like perfect candidates to be namevars so you can leave off the parameter in most cases.