file_line – the scalpel

In this exercise, we'll be using a Puppet file resource to build a file, but only if it's not already present in the system. Then, we'll use file lines to insert values we want into the file, which are collected from exported resources across all systems.

The following sample uses puppetlabs-stdlib (for more information visit https://forge.puppet.com/puppetlabs/stdlib) from the Puppet Forge. stdlib contains a large number of functions to use in manifests, as well as the resource file_linefile_line allows a line to be individually managed inside of a file, and can also be used to provide regex matching when you want to use it as a find-and-replace to the unmanaged file. If targeting INI files, consider using puppetlabs-inifile instead.(For more information visit  https://forge.puppet.com/puppetlabs/inifile).

In this example, we will first build a file called /tmp/scalpel.conf. We'll ensure that this file is present and has ownership by root. We will set the replace flag to alert Puppet not to replace the content of this file if it's already present on the system, ensuring that any content already found in this file is not overwritten. A default will be provided by the content line if the file is not currently on the system. We'll then build an exported file_line to simulate a line of configuration with a match statement to ensure that we replace misconfigured lines rather than create new ones. Finally, we'll realize all of these resources on every node that this is classified on:

class files::scalpel {

$arch = fact('os.architecture')
file {'/tmp/scalpel.conf':
ensure => file,
owner => 'root',
group => 'root',
content => 'This file is editable, with individually managed settings!',
replace => false,
}
@@file_line {"$::fqdn - setting":
path => '/tmp/scalpel.conf',
line => "${::fqdn}: $arch - ${::kernel} - Virtual: ${::is_virtual}",
match => "^${::fqdn}:",
require => File['/tmp/scalpel.conf'],
tag => 'scalpel',
}
File_line <<| tag == 'scalpel' |>>
}

The scalpel configuration file is designed to be used on each machine in the infrastructure, so it is also placed outside of a node definition in the site.pp:

include profile::etchosts

include files::scalpel

node 'haproxy' {
include profile::loadbalancer
}

node 'appserver' {
include profile::balancermember
class {'profile::appserver': db_pass => 'suP3rP@ssw0rd!' }
}

node 'mysql' {
include profile::appserver::database
}

# Provided so nodes don't fail to classify anything
node default { }

Finally, our node picks up the configuration change, and creates the file. Notice that the file is created, and then the file lines are inserted thanks to the require parameter we used in our exported file_line resource:

[root@haproxy vagrant]# puppet agent -t
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Info: Caching catalog for haproxy
Info: Applying configuration version '1529041736'
Notice: /Stage[main]/Files::Scalpel/File[/tmp/scalpel.conf]/ensure: defined content as '{md5}2d3ebc675ea9c8c43677c9513f820db0'
Notice: /Stage[main]/Files::Scalpel/File_line[haproxy - setting]/ensure: created
Notice: /Stage[main]/Files::Scalpel/File_line[mysql - setting]/ensure: created
Notice: /Stage[main]/Files::Scalpel/File_line[appserver - setting]/ensure: created
Notice: /Stage[main]/Files::Scalpel/File_line[pe-puppet-master - setting]/ensure: created
Notice: Applied catalog in 0.18 seconds

# /tmp/scalpel.conf
This file is editable, with individually managed settings!
haproxy: x86_64 - Linux - Virtual: true
mysql: x86_64 - Linux - Virtual: true
appserver: x86_64 - Linux - Virtual: true
pe-puppet-master: x86_64 - Linux - Virtual: true

Unlike our concat example, this file remains editable outside of Puppet, except for the individual lines managed by the manifest. In the following sample, I've edited the file to have comments at the top and changed the haproxy's virtual setting to false:

# Our comments now stay in this file, because we're not managing
# The whole file, just individual lines. This methodology can
# come in useful once in a great while. This is still configuration
# drift, so make sure to use it sparingly!
This file is editable, with individually managed settings!
haproxy: x86_64 - Linux - Virtual: false
mysql: x86_64 - Linux - Virtual: true
appserver: x86_64 - Linux - Virtual: true
pe-puppet-master: x86_64 - Linux - Virtual: true

When the agent is run again, the haproxy line is corrected, but our comments stay at the top of the file. Users could even add their own configuration lines to this file, and as long as that configuration is not reported by Puppet exported resources, it would remain in the configuration file:

[root@haproxy vagrant]# puppet agent -t
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Loading facts
Info: Caching catalog for haproxy
Info: Applying configuration version '1529042980'
Notice: /Stage[main]/Files::Scalpel/File_line[haproxy - setting]/ensure:
created

Notice: Applied catalog in 0.15 seconds

# Our comments now stay in this file, because we're not managing
# The whole file, just individual lines. This methodology can
# come in useful once in a great while. This is still configuration
# drift, so make sure to use it sparingly!

This file is editable, with individually managed settings!
haproxy: x86_64 - Linux - Virtual: true
mysql: x86_64 - Linux - Virtual: true
appserver: x86_64 - Linux - Virtual: true
pe-puppet-master: x86_64 - Linux - Virtual: true

This methodology does allow for a lot of configuration drift in an infrastructure. If your team is acting to provide controlled self-service resources, this is an effective way to allow your customers to modify configuration files, except for settings specifically managed by your infrastructure team.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.23.130