Background
- Always been in Ops or Support
- Until recently, I have never really worked closely with developers
- I have been doing Puppet since 2008 (v 0.24.7)
- First looked at testing Puppet modules about a year ago
Outline
- Why Testing
- What is Testing
- What to Test
- Next Steps
What I Thought?
- Help catch mistakes
- Test that things work
Why Didn't I Start Writing Tests Regularly?
- I was basically reimplementing my manifests in rspec
- No guidance on what to test and why to test
- Wait a sec, you mean it doesn't actually test if it works?
- Didn't understand the types of tests
So Then Why Are We Here?
- Testing configuration beyond just the manifests
- Manifests are getting more complicated
- Knowing that integration testing is coming
- Makes writing Puppet code more fun
Types of Tests
- Syntax Checking
- Linting
- Unit Tests
- Integration Tests
Syntax Checking
- Something a lot of us have done for a while
- Important, but doesn't do much
Linting
- puppet-lint and food critic
- Makes reading manifests and code easier
- Reminds you to do things like documentation
Unit Tests
- rspec-puppet
- Multiple tools in Chef
- Test the code returns the things that are expected
- In Puppet, testing the catalog
- Get syntax checking for free
Integration Tests
- Does the catalog actually apply or the run converge?
- Did it actually work?
It Is Driving Development, Right?
- Before you start writing config mgmt code
- After you found a problem in dev/prod
- As you go
Basic Stuff
- Are the packages getting marked for install?
- Is the config file getting put in the right place for this platform?
- Is the service being started?
Puppet Code
package {'httpd':
ensure => installed
}
rspec-puppet
it { should contain_package('httpd').with_ensure('installed') }
Important Config Elements
- Is the Include directive in the apache config?
- How about that Rewrite rule?
- Are the search domains in the right order?
- Are we setting the right options for SOLR?
Puppet Code
file {'/etc/ssh/sshd_config':
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
content => template('ssh/etc/ssh/sshd_config.erb')
}
rspec-puppet
it do
should contain_file('/etc/ssh/sshd_config') \
.with_mode('0644') \
.with_owner('root')
end
Let's Try That Again
it "Enable GSSAPI" do
should contain_file('/etc/ssh/sshd_config') \
.with_content(/^GSSAPIAuthentication yes/)
end
it "Enable X11 Forwarding" do
should contain_file('/etc/ssh/sshd_config') \
.with_content(/^X11Forwarding yes/)
end
Security Considerations
- Is logging enabled?
- Are we disabling display_errors in PHP?
rspec-puppet
it "Disable root login via ssh" do
should contain_file('/etc/ssh/sshd_config') \
.with_content(/^PermitRootLogin no/)
end
Environment Differences
- Is caching on in prod but off in dev?
- Is debug on in dev but off in prod?
Show me on the doll where the config touched you...
- A place to document those silly config changes and test them
- Make sure the same mistake doesn't happen twice
rspec-puppet
it "Stop fucking alerting that ssh is down" do
should contain_file('/etc/ssh/sshd_config') \
.with_content(/^MaxStartups 40/)
end
Next Steps
- Automation via Continuous Integration
- Integration testing (Test Kitchen)
- Nagios/Monitoring Integration
Resources
Talks
Puppet
Chef