Lesson 12: Configuration Management
Note
starting off with cs312 content
Note
starting off with cs312 content
Note
Note
Ensures that critical configs always are set like you want. No mucking around by a bad admin
Standardize settings globally
Easy to troubleshoot
Note
Different concepts Feature set different between them Each have their own issues
Let's install puppet
$ yum install puppet
Puppet knows about "resources" on the system
$ puppet describe -l
Look at all those things Puppet can manage out of the box. We're most interested in these:
file - Manages files, including their content, owner ...
group - Manage groups
package - Manage packages
service - Manage running services
user - Manage users
# let's look at the vagrant user
$ sudo puppet resource user vagrant
user { 'vagrant':
ensure => 'present',
gid => '500',
groups => ['wheel'],
home => '/home/vagrant',
password => '$1$aDsSD/Uu$.tXG5wN.TSit1AP5ZyphB0',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '500',
}
We can declare a value for any of those attributes, and Puppet will make it happen.
Note
the password is a password hash, as appears in /etc/shadow - don't put passwords in puppet manifests!
Puppet keeps its declarations in manifest files. We can write a manifest to create a user:
$ sudo su -
$ vim users.pp
user {'yournamehere':
ensure => 'present',
home => '/home/yournamehere',
groups => ['wheel', 'vagrant'],
shell => '/bin/tcsh',
}
Lets run our manifest.
> puppet apply user.pp
Notice: Compiled catalog for devops-bootcamp.osuosl.org in
environment production in 0.12 seconds
Notice: /Stage[main]/Main/User[yournamehere]/ensure: created
Notice: Finished catalog run in 0.13 seconds
Note
we are using stand-alone mode, manually running an individual manifest
Lets run our manifest again.
> puppet apply user.pp
Notice: Compiled catalog for devops-bootcamp.osuosl.org in
environment production in 0.12 seconds
Notice: Finished catalog run in 0.02 seconds
The state of the system is already what we declared it should be, so applying the manifest again doesn't change anything.
Note
idempotency is important, the puppet master daemon will run periodically, and it is important that running the same commands over and over does not have cumulative effects
We can declare that our system should have certain things installed and running.
apache.pp:
package{'httpd':
ensure => 'present'
}
service{'httpd':
ensure => 'running',
enable => 'true',
require => Package['httpd'],
}
Note
The 'service' block makes sure that the httpd service is started, and that it is enabled, the 'require' directive tells the service that it must wait until the package 'httpd' is processed. Services are anything you would start with "service x start" and packages anything you would install with "yum install x"
Where does Puppet keep its configuration files?
Note
the audience really ought to know where to start looking by this point
$ ls /etc/puppet
auth.conf modules puppet.conf
Note
there isn't much of anything we need to worry about in any of the config files
We want to move beyond running individual manifests on the command line. '/etc/puppet/manifests/site.pp' is the place to put your site's configuration.
$ mkdir /etc/puppet/manifests
$ vim /etc/puppet/manifests/site.pp
We will put our configurations in the default node for now.
Note
a node can inherit from another node, but this is discouraged
node default {
file {'/etc/issue':
path => '/etc/issue',
mode => 644,
ensure => present,
content => "Welcome to the DevOps Bootcamp VM.\n",
}
package{'httpd':
ensure => 'present'
}
service{'httpd':
ensure => 'running',
enable => 'true',
require => Package['httpd'],
}
}
Note
have we talked about /etc/issue? The file resource lets you declare the filename, ownership, and contents. You can also have it copy files from the module onto the node instead of manually inserting content here.
Puppet uses a Master/Agent architecture.
Run the master on your vm:
$ puppet master
Note
the master will background by default and log to syslog, but you can run it in the foreground with --no-daemonize and get extra logging on stdout with --verbose
The agent will look for its master on the host 'puppet' by default. Lets add the hostname 'puppet' to our local host definition in /etc/hosts, so it will look on the local machine.
$ vim /etc/hosts
127.0.0.1 devops-bootcamp.osuosl.org devops-bootcamp localhost
localhost.localdomain localhost4 localhost4.localdomain4 puppet
^^^^^^
Now run the agent in test mode:
$ puppet agent --test --verbose
Note
the agent will also background by default, the --test flag prevents that and shows us what is going on. In a production environment, the master and agent would always be running in the background, usually started as services on boot.
We can keep adding configurations to site.pp, but it's going to get long and messy. Let's use modules instead.
Note
community or puppetlabs modules vary in quality, always read the docs thoroughly
/etc/puppet/modules/
modulename/
files/
some_file
manifests/
init.pp
some_other_manifest.pp
Note
that files directory is served to the puppet agent like a fileserver, file resources can declare their source attribute like "puppet:///modules/module_name/some_file" and the file will be copied into place
# Let's create a module for our Apache configuration.
$ cd /etc/puppet/modules
$ mkdir bootcamp_apache
$ mkdir bootcamp_apache/manifests
$ vim bootcamp_apache/manifests/init.pp
class bootcamp_apache {
package{'httpd':
ensure => 'present'
}
package{'mod_wsgi':
ensure => 'present'
}
service{'httpd':
ensure => 'running',
enable => 'true',
require => Package['httpd'],
}
}
Note
it is good practice to namespace the class name of your modules, so instead of just 'apache', we use bootcamp_apache, which won't collide with any other apache related module.
node default {
file {'/etc/issue':
path => '/etc/issue',
mode => 644,
ensure => present,
content => "Welcome to the DevOps Bootcamp VM.\n",
}
include bootcamp_apache
}
Note
the include statement assumes a module located in modules/ under the pupper config dir. The name is the class name of the the module, which is not necessarily the directory name the module is stored under (but it is much easier to name them the same)
We need MySql installed for our SystemView app, as well as a database, user, and permissions. We could do all that with package, service and file resources, but there is a better way, the puppetlabs-mysql module.
https://github.com/puppetlabs/puppetlabs-mysql
(It's in Git, how convenient!)
$ cd /etc/puppet/modules/
# We'll clone into a directory named mysql, because that's the module name
$ git clone https://github.com/puppetlabs/puppetlabs-mysql.git mysql
We can include this module's class into our site manifest or our own modules.
We want to create a database and users, so lets make a module and not clutter up the site.pp
$ cd /etc/puppet/modules
$ mkdir bootcamp_mysql
$ mkdir bootcamp_mysql/manifests
$ vim bootcamp_mysql/manifests/init.pp
class bootcamp_mysql {
class { '::mysql::server' }
}
::mysql::server causes Puppet to install MySql and makes available many methods for managing MySql.
Note
Calling the 'mysql' class essentially includes that module, which includes a package declaration insuring mysql is installed. It is easy to explore the module files and see what is in it.
class bootcamp_mysql {
class { '::mysql::server' }
mysql_database { 'systemview':
ensure => 'present',
charset => 'utf8',
collate => 'utf8_swedish_ci',
}
mysql_user { 'vagrant@localhost':
ensure => 'present',
}
mysql_grant { 'vagrant@localhost/systemview.*':
ensure => 'present',
options => ['GRANT'],
privileges => ['ALL'],
table => 'systemview.*',
user => 'vagrant@localhost',
}
}
Note
the mysql module has a lot of stuff in it, there isn't time to get into it all.
$ puppet agent --test --verbose