to order • 1w to install operating system • 2d to re-install manually / 2h automated virtual servers • 2d to re-install manually / 2h automated docker • 1s to re-install
we still typically install and maintain computers the way the automotive industry built cars in the early 1900s. An individual craftsman manually manipulates a machine into being, and manually maintains it afterwards. The automotive industry discovered first mass production, then mass customisation using standard tooling. The systems administration industry has a long way to go, but is getting there.” — infrastructures.org / 1997 Infrastructure as Code
package "ntpdate" do action :install end end package "ntp" do action :install end template "/etc/ntp.conf" do source "ntp.conf.erb" owner "root" group "root" mode 0644 notifies :restart, "service[ntp]" end service "ntp" do service_name node[:ntp][:service] action [:enable, :start] end
solo.rb -j solo.json Starting Chef Client, version 11.4.0 Compiling Cookbooks... Converging 3 resources Recipe: redis::default * package[redis-server] action upgrade (up to date) * service[redis-server] action nothing (up to date) * template[/etc/redis/redis.conf] action create - update template[/etc/redis/redis.conf] from 81b4f1 to 8a6cec --- /etc/redis/redis.conf 2011-07-27 17:26:50.000000000 +0000 +++ /tmp/chef-rendered-template20130406-2537-f8vlv6 2013-04-06 ... @@ -27,7 +27,7 @@ # If you want you can bind a single interface, if the bind option is not # specified all the interfaces will listen for incoming connections. # -bind 127.0.0.1 +bind 0.0.0.0 # Specify the path for the unix socket that will be used to listen for # incoming connections. There is no default, so Redis will not listen * service[redis-server] action restart - restart service service[redis-server] Chef Client finished, 2 resources updated install package run service configuration + restart
◦ code linting ◦ rubocop - ruby lint ◦ flake8 - python lint ◦ foodcritic - chef ◦ puppet-lint ◦ ansible-lint custom extensions written by your team or community github.com/customink-webops/foodcritic-rules
puppet-lint /etc/puppet/modules foo/manifests/bar.pp - ERROR: trailing whitespace found on line 1 apache/manifests/server.pp - WARNING: variable not enclosed in {} on line 56 ... $ puppet-lint --fix /etc/puppet/modules foo/manifests/bar.pp - FIXED: trailing whitespace found on line 1 apache/manifests/server.pp - FIXED: variable not enclosed in {} on line 56 ...
TestNginx < MiniTest::Chef::TestCase def test_config_file_exist assert File.exist?('/etc/nginx.conf') end def test_succeed assert run_status.success? end end minitest chef handler # Spec Cases describe_recipe 'nginx:configuration' do it 'configures nginx version to 1.4.4' do node[:nginx][:version].should == '1.4.4' end end describe_recipe 'nginx:package' do it 'installs version 1.4.4' do result = assert_sh("nginx -V") assert_includes result, "nginx/1.4.4" end end
chefspec it 'installs apache2' do expect(chef_run).to install_package 'apache' end # rspec-puppet it { should contain_package('httpd').with_ensure('installed') }
can log into team server So that we are more efficient with our time As a technical team We can connect to a shared server to collaborate on client work Scenario: Users can connect to server via ssh key Given a newly bootstrapped server When the technical users recipe is applied Then a user should be able to ssh to the server Scenario: Default shell is bash Given a newly bootstrapped server When the technical users recipe is applied And a user connects to the server via ssh Then their login shell should be "bash" 2 scenarios (2 undefined) 12 steps (7 undefined) 0m0.013s Given /^a newly bootstrapped server$/ do ... When /^the technical users recipe is applied$/ do ... Then /^a user should be able to ssh to the server$/ do When /^a user connects to the server via ssh$/ do ... Then /^their login shell should be "([^"]*)"$/ do |arg1| Given /^with a user's default shell changed to "([^"]*)"$/ do |arg1| ... When /^the user connects to the server via ssh$/ do ... Cucumber blogs.oracle.com/martin/entry/behavior_driven_infrastructure Nov 05, 2009 Martin Englund Scenario: Users can connect to server via ssh key Given a newly bootstrapped server When the technical users recipe is applied Then a user should be able to ssh to the server
Ensure xinetd is not enabled' do it 'does not have xinetd package installed' do expect(package('xinetd')).to_not be_installed expect(package('openbsd-inetd')).to_not be_installed end it 'is not running the xinetd service' do expect(service('xinetd')).to_not be_running expect(service('xinetd')).to_not be_enabled expect(service('openbsd-inetd')).to_not be_running expect(service('openbsd-inetd')).to_not be_enabled end end