I'm trying to set up a Puppet cron job with the following structure:
file { '/usr/local/sbin/file.py':
mode => '0755',
source => 'puppet:///modules/file.py',
require => File['/usr/local/sbin']
}
cron { "cronjob":
require => "ALL_THE_FILES_ABOVE"
command => "...command_to_run_script..."
minute => '*/1'
}
All of the above is in one file run_script.pp. I'm wondering how I can code the require => "ALL_THE_FILES_ABOVE" part.
Thanks!
Based on the information provided in your question, I am going to make the assumption that the contents of run_script.pp is many file resources and the listed cron resource. You state that you want the cron resource there to require all of the file resources in that class. Based on this, here is a clean and efficient solution.
There are a few complicated/advanced ways to arrive at a clean and efficient solution, but the easiest to understand is to use a resource default: https://puppet.com/docs/puppet/5.3/lang_defaults.html
With this, we can establish attribute/value pair defaults for all file resources contained in that scope. This would make it easier to use the before metaparameter on the file resources instead: https://puppet.com/docs/puppet/5.3/metaparameter.html#before
This simplifies the solution to a one-liner in your class:
File { before => Cron['cronjob'] }
Note there will be a caveat to this method, which is that if you are declaring, requiring, or containing a class within this manifest, then this default could be expanded to that "area of effect" and cause a circular dependency. In that case, you should use a per-expression resource default attribute: https://puppet.com/docs/puppet/5.3/lang_resources_advanced.html#per-expression-default-attributes
You can use a multiple require
file{'path/foo':}
file{'path/bar':}
file{'~/foobar':
require => [ File['path/foo'], File['path/bar'] ]
}
or you can use the ordering arrow
-> (ordering arrow; a hyphen and a greater-than sign) — Applies the resource on the left before the resource on the right.
file{'path/foo':} ->
file{'path/bar':} ->
file{'~/foobar':}
Here is more information about relationships and ordering in Puppet
Related
Let us say that I have a case in which I need to apply only two files from a Puppet configuration on some production servers, without touching the rest of the configuration.
/opt/aservice/myfile/thekey.conf
/opt/myfile/thekey.salt
Let's also say that these are controlled by the following Puppet manifest:
#
# author: Nathan Basanese (nathan#basanese.com)
# date: 04/17/2048
#
class keyconfig ( $cluster ){
notify {"Deploying key config. files to $fqdn":}
file {'/opt/aservice/key/config/thekey.conf':
ensure => present,
mode => '0644',
owner => 'aservice-serv',
group => 'aservice-serv',
source => "puppet:///modules/keyconfig/$cluster/thekey.conf",
}
file {'/opt/aservice/key/config/thekey.salt':
ensure => present,
mode => '0644',
owner => 'aservice-serv',
group => 'aservice-serv',
source => "puppet:///modules/keyconfig/$cluster/thekey.salt",
}
}
How would I apply ONLY these two files to a given server from a Puppet Master?
Perhaps, in the puppet agent command that is run on the target server, could I specify a specific Puppet class to use?
I have used the puppet resource command before, but I'm not sure that would work, here.
Every resource is automatically tagged with the fully qualified name of the class or defined type in which it is declared, and with every namespace segment of the class or type name, among other tags. You can use those tags to filter the resources that will be applied during a given catalog run. In the particular example you describe, you could use
puppet agent --no-daemonize --onetime --tags keyconfig
to apply only the resources declared in class keyconfig (and in any other class declared by keyconfig, recursively, but in this case there are no such other classes).
You can also declare tags manually by using the tag metaparameter in your resource declarations. That can allow you to provide for identifying custom collections of resources. And speaking of collections, you can use tags in the selection predicates of resource collectors, too.
The only way to do that is to have that node contain only the class you are wanting to have applied. In your site.pp you would have the following where the 'myhost.dns' is your fqdn. and $mycluster would be replaced by your cluster string.
node 'myhost.dns' {
class { 'keyconfig':
cluster => $mycluster,
}
}
I want my Puppet class to create a file resource with contents based on all instances of a particular defined type. I looked at this question with the idea of iterating over the instances to build the file, but apparently it's a "Bad Idea" per the one answer currently there.
Some background: I am building a monitor_service class in Puppet to deploy a custom monitoring application. The application reads a config file that tells it what to monitor, one item per line, along the lines of
ITEM: /var/things/thing-one (123)
ITEM: /var/things/thing-two (456)
I am also writing a defined type that deploys instances of the monitored items:
define my_thing::monitored_thing ( $port ) {
file { "/var/things/$name":
...
}
}
On a given node, I set up several monitored_things like
my_thing::monitored_thing { "thing-one":
port => 123
}
my_thing::monitored_thing { "thing-two":
port => 456
}
What's the "right" Puppet idiom for building the monitoring service config file? I would prefer for this to work in such a way that the monitor_service class doesn't have to be told which monitored_thing instances it is watching -- just creating a monitored_thing instance should cause it to be added to the config file automatically.
There are several ways to modify/declare only part of a file within multiple defined types:
Use puppetlabs-stdlib's file_line. This lets you specify that a file should contain a specific line. Best when you do not care about the other file contents and just want to make sure a line is present or absent.
Use puppetlabs-concat if you want to make sure that the final file only includes the fragments that you are specifying or the order of the fragments matters.
Use the augeas type if you need to edit/add configuration to a file with a more complicated structure, like xml, apache configurations, etc.
Looking at the Relationship Declarations section in the Puppet Style Guide about the '->' arrows, where 'x->y' means that y requires x to be installed before y, it says:
When possible, you should prefer metaparameters to relationship declarations.
that's a lot of syllables. Is that saying that you should prefer this
file { "/home/${user}/.ssh":
require => User[$user],
...
}
and not use the arrows like this?
User[$user] -> file { "/home/${user}/.ssh":
...
}
file { "/home/${user}/.ssh":
require => User[$user],
...
}
1.The above code even works with different manifests, when they are part of same catalog. So if you use metaparameters you have less work when you get a modification in future(unfortunately).
2.Chaining arrows is best used for Resource collectors, when you have to make relationship more than one resource, you can have this instead of putting require/before in all the resources.
I have code similar to the following:
class someclass($ensure = installed)
{
if($ensure == installed)
{
$installValue = installed
file { "someprogram.msi":
ensure => file,
source => 'somewhere',
path => 'C:/puppet-files/someprogram.msi',
}
}
else
{
$installValue = absent
}
package{ "someprogram":
ensure => $installValue,
source => 'C:/puppet-files/someprogram.msi',
}
}
Does the if statement containing the file resource ensure that the file resource will get applied before the package resource? Or do I need to explicitly state this in the metaparameters? Also, I am assuming that the $installValue will always be set before the package is installed, is that correct?
Thank you,
Derongan
You should specify the ordering explicitly, however the variable will be initialised correctly.
The ordering of resources in Puppet 3 is deterministic, but essentially random as it's based on hashes of the resource titles. In Puppet 3.3, this behaviour can be changed to the manifest order (release notes), but I wouldn't recommend relying on this - certainly if you're sharing the module, there's no guarantee that others use the same setting.
Since the file resource may not exist (if ensure => absent), you can't specify the relationship on the package resource. Instead, add before => Package['someprogram'], to the file resource.
Lets say I want to define a set of resources that have dependencies on each other, and the dependent resources should reuse parameters from their ancestors. Something like this:
server { 'my_server':
path => '/path/to/server/root',
...
}
server_module { 'my_module':
server => Server['my_server'],
...
}
The server_module resource both depends on my_server, but also wants to reuse the configuration of it, in this case the path where the server is installed. stdlib has functions for doing this, specifically getparam().
Is this the "puppet" way to handle this, or is there a better way to have this kind of dependency?
I don't think there's a standard "puppet way" to do this. If you can get it done using the stdlib and you're happy with it, then by all means do it that way.
Personally, if I have a couple defined resources that both need the same data I'll do one of the follow:
1) Have a manifest that creates both resources and passes the data both need via parameters. The manifest will have access to all data both resources need, whether shared or not.
2) Have both defined resources look up the data they need in Hiera.
I've been leaning more towards #2 lately.
Dependency is only a matter of declaring it. So your server_module resource would have a "require => Server['my_server']" parameter --- or the server resource would have a "before => Server_module['my_module']".