I'd like to be able to create files based on the contents of an array. Here is what I have tried:
class make_files (
$servers = ['server-1','server-2','server-3'],
) {
file { $servers :
path => '/tmp',
content => $servers,
}
}
... but when I execute this like so ...
# puppet apply --modulepath=/root/modules -e 'include make_files'
... I get this output:
Notice: Compiled catalog for host-001 in environment production in 0.13 seconds
Error: Cannot alias File[server-2] to ["/tmp"] at /root/modules/make_files/manifests/init.pp:9; resource ["File", "/tmp"] already declared at /root/modules/make_files/manifests/init.pp:9
I was hoping to have three files ...
# ls /tmp/server-?
/tmp/server-1 /tmp/server-2 /tmp/server-3
# cat /tmp/server-?
server-1
server-2
server-3
It would really be cool if someone could tell me how to get the files to be named: server-1.cfg, server-2.cfg and server-3.cfg.
Any help is appreciated thanks!
First of all you already defined resource File['/tmp'], in init.pp file.
This is the main cause of the problem you got:
Error: Cannot alias File[server-2] to ["/tmp"] at /root/modules/make_files/manifests/init.pp:9; resource ["File", "/tmp"] already declared at /root/modules/make_files/manifests/init.pp:9
Please check the meaning of the path attribute. Maybe this will clarify the problem.
Create
$files_to_create = ['/path/server-1','/path/server-2','/path/server-3']
and then use it:
file { $files_to_create :
content => $servers,
}
Please also be sure that /path directory already exist in the filesystem. So far puppet is not able to create intermediate directories.
Related
I am trying to create a puppet manifest using inifile. This would be for a configuration file where I need to have the following format.
[safe]
directory = /home/foo
directory = /home/test
directory = /home/something
I know that there is a way to use directory1, and directory2 but I was wondering if there is a way to do it without changing the directory since it needs that specific attribute. This implementation is meant for puppet manifest.
Also, I was thinking puppetlabs/inifile module but if there is another option to achieve this would be great too.
Thanks for the help in advance
So far, I have an implementation like:
ini_setting { 'procedure cache size':
ensure => present,
path => '/var/lib/somethning/test.config',
section => 'safe',
setting => 'directory',
value => '/home/foo',
indent_char => "\t",
}
This is for each directory. The purpose for this implementation is to address the new git configuration for safe.repository in the recent update. My understanding is that for multiple directories, it adds a new value as directory = <directory> I don't believe that it likes directories separate by commas.
First I thought about file_line, but this is not idempotent for multi-line settings (you get problems when you run again). You can try:
Sample puppet code dir.pp
$safe_directories="directory = /home/foo
directory = /home/test
directory = /home/something"
notice "Testing\n${safe_directories}"
file { "/tmp/result.ini":
ensure => present,
content => template('/tmp/layout.erb'),
}
notice "Check /tmp/result.ini"
Sample template /tmp/layout.erb
[unsafe]
directory=/unsafe
[safe]
<%=#safe_directories%>
otherfield=secure
[header3]
nothing = here
Now run command from commandline
puppet apply dir.pp
This is most likely an anti-pattern, but I'd like to know nonetheless:
I need to extract a tgz which is in puppet and then move the contents somewhere else. Is it possible, in a puppet exec { }, to refer to the file where it is stored on disk?
For example, puppet is available at /usr/local/puppet, and the tgz file I need it in /usr/local/puppet/modules/components/files/file.tgz. In the exec { } can I do something like command => "/bin/cp $modules/components/files/file.tgz /somewhere_else" ? Or do I have to declare a file { source => "..." } block first?
Both approaches are correct if you run puppet with puppet apply.
In master-agent architecture using exec to copy file probably will not work at all.
In my opinion using file resource is more "puppet-like" but is has one significant drawback.
You can use:
file { '/some_path/somewhere_else':
source => '/usr/local/puppet/modules/components/files/file.tgz',
}
This will create file /some_path/somewhere_else with the same content as /usr/local/puppet/modules/components/files/file.tgz (it will make a copy of the original file).
But if /some_path doesn't not exist in the file system, the command will fail.
If you are working with tgz files you can also consider using some of the archive puppet modules e.g gini.
UPDATE:
I can propose two approaches:
Use puppet file server to serve files (or define module path for old puppet versions). Next just use it e.g:
file { '/some_path/somewhere_else':
source => "puppet:///modules/components/file.tgz',
}
Define custom facter fact 1, 2 that points path in your filesystem containing required files. E.g:
file { '/some_path/somewhere_else':
source => "${::my_custom_fact}/some_path/file.tgz',
}
I do not think that any of the core facts might be useful for you.
This is a pretty simple problem, and I have read a number of suggested solutions, but I still can't get puppet apply to import the git::config class. Here is my file setup:
I import the git module via nodes.pp:
#/etc/puppet/manifests/nodes.pp
node default {
}
include git
site.pp imports nodes.pp:
#/etc/puppet/manifests/site.pp
import 'nodes.pp'
The git module is defined as follows:
#/etc/puppet/modules/git/manifests/init.pp
class git {
include git::install
include git::config
}
class git::install{
package {'git': => present }
}
and the config file:
#/etc/puppet/modules/git/manifests/config.pp
define git::config{
[some code here]
}
When I run puppet apply, puppet does not find the git::config class:
sudo puppet apply --modulepath=/etc/puppet/modules /etc/puppet/manifests/site.pp
Error: Could not find class git::config for xxxx on node xxxx.
The original module was puppetlabs-git (same folder structure), but I have recreated the error using the simplified file structure (above).
Update 1
Typo above, the git config.pp and init.pp are in folder /modules/git/manifests and the config.pp file reads 'define git::config'
You cannot call include on git::config. git::config is a defined type, not a class. The syntax to use a defined type is as follows:
git::config { 'the_name_var':
param1 => 'foo',
param2 => 'bar'
}
Hope this helps
Your puppet code structure is wrong. You need move your pp file to manifests folders.
/etc/puppet/modules/git/init.pp
/etc/puppet/modules/git/config.pp
to
/etc/puppet/modules/git/manifests/init.pp
/etc/puppet/modules/git/manifests/config.pp
I am trying to pull things out into roles and profiles and am having an issue. I am using puppet apply for all of this as I am using it to finish setting up my Puppet Master. If I define my node in site.pp as shown here:
[root#puppet puppetdbsetup]# cat manifests/site.pp
node 'puppet' {
include ::roles::puppetmaster
}
I get this error:
[root#puppet puppetdbsetup]# puppet apply manifests/site.pp --environmentpath /etc/puppet/environments --environment puppetdbsetup --noop
Notice: Compiled catalog for puppet.belkin in environment puppetdbsetup in 1.29 seconds
Error: Could not find dependency Class[Puppet::Install] for File[/etc/puppet/hiera.yaml] at /etc/puppet/environments/puppetdbsetup/modules/p
uppet/manifests/master.pp:31
If I run puppetmaster.pp (shown below) with puppet apply directly it doesn't throw the same error.
[root#puppet puppetdbsetup]# cat modules/roles/manifests/puppetmaster.pp
class roles::puppetmaster {
#include profiles::base
include profiles::puppet::master
}
Can anyone tell me why this is and how to fix it? As a side note, all three modules referenced here are hand written... none are Forge modules.
Update 1
Here is my puppet::install class:
[root#puppet puppetdbsetup]# cat modules/puppet/manifests/install.pp
class puppet::install {
package { 'puppet':
ensure => present,
}
}
Somewhere in your manifest, you are declaring a File[/etc/puppet/hiera.yaml] that depends on Class[Puppet::Install], like
file { '/etc/puppet/hiera.yaml': require => Class['puppet::install'] }
or so
Class['puppet::install'] -> file { '/etc/puppet/hiera.yaml': ... }
or something in that vein.
What you are lacking is the actual declaration of the class either via
include puppet::install # nice!
or
class { 'puppet::install': } # please don't
If in doubt, add the include line near the file declaration. It is usually safe to include a class multiple times.
If you apply puppetmaster.pp directly, you're just defining the class not applying it.
You need to do puppet apply -e 'include ::roles::puppetmaster' to be comparible.
The other error is probably caused by modules/puppet/manifests/install.pp not existing, or the class definition in the file not starting with
class puppet::install (
....
....
) {
I'm installing a package from a module (Nginx in this specific case) and would like to include a configuration file from outside of the module, i.e. from a top level files directory parallel to the top level manifests directory. I don't see any way to source the file though without including it in a module or in my current Vagrant environment referring to the absolute local path.
Does Puppet allow for sourcing files from outside of modules as described in the documentation?
if I understand your question correctly, you can.
In your module a simple code like this
file { '/path/to/file':
ensure => present,
source => [
"puppet:///files/${fqdn}/path/to/file",
"puppet:///files/${hostgroup}/path/to/file",
"puppet:///files/${domain}/path/to/file",
"puppet:///files/global/path/to/file",
],
}
will do the job. The /path/to/file will be sourced using a file located in the "files" Puppet share.
(in the example above, it search in 4 different locations).
update maybe you're talking about a directory to store files which is not shared by Puppet fileserver (look at http://docs.puppetlabs.com/guides/file_serving.html), and in this case you can't i think, Vagrant or not, but you can add it to your Puppet fileserver to do it. I thinks it's the best (and maybe only) way to do it.
If you have a number of Vagrant VMs you can simply store files within your Vagrant project directory (containing your VagrantFile).
This directory is usually available to all VMs as /vagrant within the VM on creation.
If you want other directories on your computer to be available to your VMs just add the following to your VagrantFile
# see http://docs.vagrantup.com/v1/docs/config/vm/share_folder.html
config.vm.share_folder "v-packages", "/vagrant_packages", "../../dpkg"
Then to use the files within puppet you can simply treat them as local files to the VM
# bad example, bub basically use 'source => 'file:///vagrant/foo/bar'
file { '/opt/cassandra':
ensure => directory,
replace => true,
purge => true,
recurse => true,
source => 'file:///vagrant/conf/dist/apache-cassandra-1.2.0',
}
This is probably only wise to do if you only using local puppet manifests/modules.
Probably too late to help bennylope, but for others who happen across this question, as I did before figuring it out for myself ...
Include stuff like this in your Vagrantfile ...
GUEST_PROVISIONER_CONFDIR = "/example/destination/path"
HOST_PROVISIONER_CONFDIR = "/example/source/path"
config.vm.synced_folder HOST_PROVISIONER_CONFIDIR, GUEST_PROVISIONER_CONFDIR
puppet.options = "--fileserverconfig='#{GUEST_PROVISIONER_CONFDIR}/fileserver.conf'"
Then make sure /example/source/path contains the referenced fileserver.conf file. It should look something like ...
[foo]
path /example/destination/path
allow *
Now, assuming example-file.txt exists in /example/source/path, the following will work in your manifests:
source => "puppet:///foo/example-file.txt",
See:
Puppet configuration reference entry for fileserverconfig
Serving Files From Custom Mount Points