inspec

skynet testing

ow.ly/XPkvT

$> whoami

Dominik Richter

Product Manager at Chef

inspec

inspec is

infrastructure testing

works with Chef, Puppet, Ansible, Salt, CFEngine, Bash

Create a check
						
describe service('sshd') do
  it { should be_running }
end
						
					
Test a target

.

Finished in 0.01858 seconds (files took 1.83 seconds to load)
1 example, 0 failures
					

Why infrastructure testing?

Code breaks

normal accident theory

Why infrastructure testing?

Reduce the number of defects

Why infrastructure testing?

Security and Compliance testing

Referece: InSpec, or How to translate compliance spreadsheets into code - Michael Goetz

What is special about inspec?

1. Test any target

2. Be expressive

1 Test any target

What do you run these days?

  • Bare-metal / VMs / Containers
  • Linux / Windows / other / legacy

Reference: Cross-platform Infrastructure testing with Microsoft Azure, Test Kitchen and InSpec - Stuart Preston

Tiny HowTo


gem install inspec
					

git clone http://github.com/chef/inspec.git
					

Tiny HowTo


inspec
					

Commands:
  inspec archive PATH    # archive a profile to tar.gz (default) or zip
  inspec check PATH      # verify all tests at the specified PATH
  inspec detect          # detect the target OS
  inspec exec PATHS      # run all test files at the specified PATH.
  inspec help [COMMAND]  # Describe available commands or one specific command
  inspec json PATH       # read all tests in PATH and generate a JSON summary
  inspec shell           # open an interactive debugging shell
  inspec version         # prints the version of this tool
					

Tiny HowTo


inspec exec test.rb
					

.

Finished in 0.00228 seconds (files took 1.95 seconds to load)
1 example, 0 failures





					

Tiny HowTo


inspec exec test.rb
					

inspec exec /path/to/profile
					

inspec exec github.com/chef/some-profile.git
					

Test your local node


inspec exec test.rb
					

 

Test remote via SSH


inspec exec test.rb -i vagrant.key -t ssh://root@172.17.0.1:11022
					

no Ruby / agent on the node

Test remote via WinRM


inspec exec test.rb -t winrm://Admin@192.168.1.2 --password super
					

no Ruby / agent on the node

Test Docker Container


inspec exec test.rb -t docker://3cc8837bb6a8
					

no SSH / agent on the container

Anatomy of a container test


describe package('wget') do
  it { should be_installed }
end

describe file('/fetch-all.sh') do
  it { should be_file }
  its('owner') { should eq 'root' }
  its('mode') { should eq 0640 }
end
					

Anatomy of a container test


inspec exec dtest.rb -t docker://f02e                                                                                              x1 8h44m master[d140c6a]
					

....

Finished in 0.1537 seconds (files took 1.77 seconds to load)
4 examples, 0 failures
					
execution tree

Run via test-kitchen

kitchen-inspec

Anatomy of a Solaris test


describe os do
  it { should be_solaris }
end

describe package('network/ssh') do
  it { should be_installed }
end

describe service('/network/ssh') do
  it { should be_running }
end
					

2 Be expressive


describe file('/etc/ssh/sshd_config') do
  its(:content) { should match /Protocol 2/ }
end
					

describe sshd_config do
  its('Protocol') { should cmp 2 }
end
					

Available resources

apache_conf apache apt auditd_conf auditd_rules audit_policy bond bridge command csv directory etc_group file gem group host inetd_conf ini interface iptables json kernel_module kernel_parameter limits_conf login_def mount mysql_conf mysql mysql_session npm ntp_conf oneget os_env os package parse_config passwd pip port postgres_conf postgres postgres_session processes registry_key script security_policy service ssh_conf user windows_feature yaml yum

Custom resources


.
├── controls
│   └── test.rb
├── inspec.yml
└── libraries
    └── gordon.rb
					

class Tiny < Inspec.resource(1)
  name 'tiny'
end
					

describe tiny do
  # I exist!
  # Can't do anything yet...
end
					

class Gordon < Inspec.resource(1)
  name 'gordon'

  def content
    'signal me'
  end
end
					

describe gordon do
  its('content') { should eq 'signal me' }
end
					

class Gordon < Inspec.resource(1)
  name 'gordon'

  def content
    inspec.file('/etc/gordon/gordon.yaml').content
  end
end
					

describe gordon do
  its('content') { should eq 'hello: world' }
end
					
execution tree

class Gordon < Inspec.resource(1)
  name 'gordon'

  def params
    inspec.yaml('/etc/gordon/gordon.yaml').params
  end
end
					

describe gordon.params['hello'] do
  it { should eq 'world' }
end
					

The way forward - 1.0 March

  • Dependency resolution
  • Resource packs
  • Attributes
  • Plugins

Join InSpec

github.com/chef/inspec

Thank you

ow.ly/XPkvT