Lesson 12: Configuration Management¶
Note
starting off with cs312 content
Large site management¶
- Configuration Management
- Automation
- Centralized
- Standardization
- History
Note
- Automating most of what you do
- Scaling the configuration management is key
- Centralized so that a team can work together
- History via SCM (source control management)
What config management does¶
- Verify permissions for security/mgmt purposes
- Distribute config files and scripts
- Control batch jobs
- Ensure packages are up to date
- Look for file changes
Note
Ensures that critical configs always are set like you want. No mucking around by a bad admin
Configuration Management¶
- System-wide settings
- sshd, ntp, ldap, etc
- Group settings
- Web, email, database
Standardize settings globally
Easy to troubleshoot
CF Management Tools¶
- CFEngine
- Mature, widely used
- Puppet
- Getting mature, different concept
- Chef
- Very new
Note
Different concepts Feature set different between them Each have their own issues
Declarative Configuration¶
- We ‘declare’ the desired state of the system
- Puppet does the necessary work to make the system match our declaration
- We can save these declarations in a repository, just like code
Puppet Resources¶
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
Resources Have Attributes¶
# 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 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',
}
Pull the Strings¶
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
Declarations Are Idempotent¶
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
Packages and Services¶
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”
Puppet Config¶
Where does Puppet keep its configuration files?
Note
the audience really ought to know where to start looking by this point
/etc/puppet¶
$ ls /etc/puppet
auth.conf modules puppet.conf
- puppet.conf - systemwide configuration
- auth.conf - puppet agent configuration
- modules - we’ll talk about that later
Note
there isn’t much of anything we need to worry about in any of the config files
The Site Manifest¶
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
But First, Nodes¶
- Nodes are defined in the site manifest
- A node is a single machine, identified by its FQDN (Fully-Qualified Domain Name).
- You can define many nodes.
- You can add declarations to a node definition.
- A special ‘default’ node will be used if a node’s name can’t be found.
We will put our configurations in the default node for now.
Note
a node can inherit from another node, but this is discouraged
An Example Site Manifest¶
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.
The Master and the Agent¶
Puppet uses a Master/Agent architecture.
- The Master reads the ‘site.pp‘ and listens for an Agent to contact it.
- Agents run on nodes, they contact the master to get their configuration
- Master and Agent can be on the same machine.
- When they are on different machines, they need an SSL certificate to authenticate
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¶
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.
Modules¶
We can keep adding configurations to site.pp, but it’s going to get long and messy. Let’s use modules instead.
- Modules are classes
- Modules encapsulate a set of related configurations
- Modules make it easy to apply configurations to many nodes
- Community created modules already exist for almost everything
Note
community or puppetlabs modules vary in quality, always read the docs thoroughly
Module Structure¶
/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
The Bootcamp Apache Module¶
# 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.
Site.pp Modularized¶
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)
Community Modules¶
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.
The Bootcamp Mysql Module¶
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.
Databases, Users, and Grants¶
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.
Test It Out¶
$ puppet agent --test --verbose