SlideShare a Scribd company logo
1 of 41
Download to read offline
Itamar Hassin April 2015
INFRASTRUCTURE
DEVELOPMENT USING
CUCUMBER, SEVERSPEC & ANSIBLE
THE GOAL
•Avoid snowflakes
•Fail fast (offline!) and cycle quickly
•Be able to sustain infrastructure as it expands
•Support apps and heterogeneous environments
•Optimise SA’s time (reduce manualVDDs)
•Time To Rebuild < Time To Fix
IAC, BDD, MDD
•Infrastructure As Code
•Behaviour-Driven Development
•Monitor-Driven Development
A way by which we can define, provision, and
configure hardware andVirtual Machines to suite
our needs
INFRASTRUCTURE AS CODE
An activity whereby a feature’s behaviour is described
prior to its implementation
BEHAVIOUR DRIVEN DEVELOPMENT
MONITOR DRIVEN DEVELOPMENT
• Write production monitors based on desired result
• Implement enough infrastructure to satisfy the
monitor
• Refactor
• Repeat
OURTOOLBOX
MDD Provisioning BDD IAC
ServerSpec Vagrant Cucumber Ansible
SERVERSPEC
With Serverspec, you can write tests for checking
your servers are configured correctly.
VAGRANT
Vagrant is a computer software for creating and
configuring virtual development environments.
CUCUMBER
Simple, human collaboration
ANSIBLE
Ansible is a radically simple IT automation engine
that automates cloud provisioning, configuration
management, application deployment, intra-service
orchestration, and many other IT needs.
SALLY & LEO AT WORK
Danielle: I want a web server.
Sally: Sure, boss.
Danielle: We’re a silo-ed org.
Sally: Sure, boss.
Danielle: The Admins need specs.
Sally: Sure, boss.
Sally: Leo, let’s pair.
WORKFLOW
How Sally and Leo go about setting up a web server
in such a way that it
•Is automated
•Is repeatable and measurable
•Assures environments for consistent development
testing
SALLY WRITES SPECS

(IN A WORD DOC)
Feature:

As a Webmaster (yeah baby!) I need a webserver to be
running so that I may master it.



Background:

Given my server is available

And I provision it



Scenario:

When I get access to it

Then I expect it to have apache running
THEY USE BDD
$ cucumber
No such file or directory @ rb_sysopen - features. Please
create a features directory to get started. (Errno::ENOENT)
MAKE FEATURES DIRECTORY
$ mkdir features
CUCUMBER IS SET UP
$ cucumber
0 scenarios
0 steps
0m0.000s
PASTE FEATURE

(FROM WORD DOC)
Feature:

As a Webmaster (yeah baby!) I need a webserver to be running
so that I may master it.



Background:

Given my server is available

And I provision it



Scenario:

When I get access to it

Then I expect it to have apache running
MISSING STEPS
$ cucumber
Feature:
As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it.
Background: # features/httpd.feature:4
Given my server is available # features/httpd.feature:5
And I provision it # features/httpd.feature:6
Scenario: # features/httpd.feature:8
When I get access to it # features/httpd.feature:9
Then I expect it to have apache running # features/httpd.feature:10
1 scenario (1 undefined)
4 steps (4 undefined)
0m0.002s
You can implement step definitions for undefined steps with these snippets:
Given(/^my server is available$/) do
pending # express the regexp above with the code you wish you had
end
When(/^I provision it$/) do
pending # express the regexp above with the code you wish you had
end
WORKFLOW
At this stage, the high-level functional requirement
needs more specification, so they MDD the server
THEY WRITE A MONITOR
describe package('apache2') do
it { should be_installed }
end
describe service('apache2') do
it { should be_enabled }
it { should be_running }
end
describe port(80) do
it { should be_listening }
end
describe file('/etc/apache2/sites-enabled/000-default.conf') do
it { should be_file }
it { should contain "example.com" }
end
MISSINGVAGRANT
A Vagrant environment or target machine is required
to run this
command.
Run `vagrant init` to create a new Vagrant
environment.
Or, get an ID of a target machine from `vagrant
global-status` to run
this command on.
THEY CREATE AVAGRANTFILE
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "Ubuntu 14.04"
config.vm.define "webserver"
config.vm.hostname = "webserver"
config.vm.network "private_network", ip: "33.33.33.33"
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "1024"]
end
end
THEY RUN MONITOR AGAIN
$ rake spec
ruby -S rspec spec/webserver/httpd_spec.rb
FFFFFF
Failures:
1) Package "apache2" should be installed
Failure/Error: it { should be_installed }
sudo dpkg-query -f '${Status}' -W apache2 | grep -E '^(install|hold)
ok installed$'
expected Package "apache2" to be installed
# ./spec/webserver/httpd_spec.rb:4:in `block (2 levels) in <top
(required)>'
2) Service "apache2" should be enabled
Failure/Error: it { should be_enabled }
sudo ls /etc/rc3.d/ | grep -- '^S..apache2' || sudo grep 'start
on' /etc/init/apache2.conf
expected Service "apache2" to be enabled
# ./spec/webserver/httpd_spec.rb:8:in `block (2 levels) in <top
(required)>'
THEY PROVISION AVM
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "Ubuntu 14.04"
config.vm.define "webserver"
config.vm.hostname = "webserver"
config.vm.network "private_network", ip: "33.33.33.33"
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "1024"]
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
ansible.inventory_path = "inventory.ini"
ansible.sudo = true
end
end
THEY RUN MONITOR
$ rake spec
ruby -S rspec spec/webserver/httpd_spec.rb
There are errors in the configuration of this machine.
Please fix
the following errors and try again:
ansible provisioner:
* `playbook` for the Ansible provisioner does not exist on
the host system: playbook.yml
......
Finished in 3.51 seconds
6 examples, 0 failures
THEY WRITE PLAYBOOK
---
- hosts: all
user: vagrant
sudo: true
roles:
- common
- apache
COMMON ROLE EXAMPLE
- name: Update apt cache if needed

apt: update_cache=yes cache_valid_time=3600



- name: Upgrade OS

apt: upgrade=dist force=yes



- name: Install needed packages

apt: pkg={{item}} state=installed

with_items:

- cron

- logrotate

- curl

- git

- update-motd



- name: Create the deploy user

user: name={{user}} comment="deploy user" generate_ssh_key=yes
ssh_key_bits=2048 state=present password={{password}} shell=/bin/bash



- name: Set {{user}} as sudoer

lineinfile: dest=/etc/sudoers line="{{user}} ALL=(ALL) NOPASSWD ":" ALL"



- name: remove ubuntu's user

user: name=ubuntu state=absent remove=yes
THEY WRITE INVENTORY
[webserver]
33.33.33.33
THEY RUNVAGRANT
$ vagrant provision webserver
==> webserver: Running provisioner: ansible...
PLAY [webserver] **************************************************************
GATHERING FACTS ***************************************************************
ok: [webserver]
TASK: [kamaln7.swapfile | Create swapfile] ************************************
changed: [webserver]
TASK: [common | Update apt cache if needed] ***********************************
ok: [webserver]
TASK: [common | Upgrade OS] ***************************************************
ok: [webserver]
TASK: [common | Install needed packages] **************************************
ok: [webserver] => (item=cron,logrotate,curl,git,update-motd)
TASK: [common | Create the deploy user] ***************************************
ok: [webserver]
WORKFLOW
At this stage,Vagrant and Ansible scripts provision and
configure the server, so all that’s left is to tie that to
the suspended Cucumber spec
STEP IMPLEMENTATION FOR CUCUMBER
Given(/^my server is available$/) do

output=`vagrant reload`

end



And(/^I provision it$/) do

output=`vagrant provision`

end



When(/^I get access to it$/) do

run_remote("ls")

end



Then(/^I expect it to have apache running$/) do

run_remote("ps asx | grep apache")

end



def run_remote(command)

Net::SSH.start("33.33.33.33", "vagrant", :password => "vagrant") do |ssh|

result = ssh.exec!(command)

end

end
GOODTIMES
LEO RUNSTHE MONITOR
$ rake spec
ruby -S rspec spec/webserver/httpd_spec.rb
......
Finished in 3.73 seconds
6 examples, 0 failures
SALLY RUNS CUCUMBER
$ cucumber
Feature:
As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it.
Background: # features/httpd.feature:4
Given my server is available # features/steps/httpd_steps.rb:3
And I provision it # features/steps/httpd_steps.rb:8
Scenario: # features/httpd.feature:8
When I get access to it # features/steps/httpd_steps.rb:12
Then I expect it to have apache running
1 scenario (1 passed)
4 steps (4 passed)
$ rake spec
ruby -S rspec spec/webserver/httpd_spec.rb
......
Finished in 3.73 seconds
6 examples, 0 failures
LEO RUNSTHE MONITOR
$ cucumber
Feature:
As a Webmaster (yeah baby!) I need a webserver to be running so
that I may master it.
Background: # features/httpd.feature:4
Given my server is available # features/steps/httpd_steps.rb:3
And I provision it # features/steps/httpd_steps.rb:8
Scenario: # features/httpd.feature:8
When I get access to it # features/steps/httpd_steps.rb:12
Then I expect it to have apache running
1 scenario (1 passed)
4 steps (4 passed)
0m8.433s
SALLY RUNS CUCUMBER
DANIELLE SEES APACHE RUN
AUTOMATION
• Commit the Cucumber and ServerSpec source
code to git
• Add a Jenkins task to run the scripts as part of the
integration test suite
• Add ServerSpec as a monitor in all environments
to ensure server configuration immutability
SOURCE CONTROL
SCaaCC
• Infrastructure code is part of the app code
• Developers and SysAdmins share code using git
for modifications.
• HugOps can use master
• Others can use branching or forking
XP PRACTICES
• SysAdmins are part of the development team
• Participate in standups, part of a story/task
cards
• Participate in pairing sessions
• Empathise
REFERENCES
TheVisible Ops Handbook
James White's manifesto
DevOps Conferences
Ansible
Cucumber
ServerSpec
THANKYOU!
@itababy
www.in-context.com

More Related Content

What's hot

Infrastructure = Code
Infrastructure = CodeInfrastructure = Code
Infrastructure = CodeGeorg Sorst
 
Introduction to Ansible (Pycon7 2016)
Introduction to Ansible (Pycon7 2016)Introduction to Ansible (Pycon7 2016)
Introduction to Ansible (Pycon7 2016)Ivan Rossi
 
Ansible module development 101
Ansible module development 101Ansible module development 101
Ansible module development 101yfauser
 
How Ansible Makes Automation Easy
How Ansible Makes Automation EasyHow Ansible Makes Automation Easy
How Ansible Makes Automation EasyPeter Sankauskas
 
Network Automation with Ansible
Network Automation with AnsibleNetwork Automation with Ansible
Network Automation with AnsibleAnas
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with AnsibleAhmed AbouZaid
 
Testing Ansible with Jenkins and Docker
Testing Ansible with Jenkins and DockerTesting Ansible with Jenkins and Docker
Testing Ansible with Jenkins and DockerDennis Rowe
 
Ansible Automation to Rule Them All
Ansible Automation to Rule Them AllAnsible Automation to Rule Them All
Ansible Automation to Rule Them AllTim Fairweather
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentationSuresh Kumar
 
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12Keith Resar
 
Go Faster with Ansible (PHP meetup)
Go Faster with Ansible (PHP meetup)Go Faster with Ansible (PHP meetup)
Go Faster with Ansible (PHP meetup)Richard Donkin
 
DevOps, A brief introduction to Vagrant & Ansible
DevOps, A brief introduction to Vagrant & AnsibleDevOps, A brief introduction to Vagrant & Ansible
DevOps, A brief introduction to Vagrant & AnsibleArnaud LEMAIRE
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentationJohn Lynch
 
Ansible roles done right
Ansible roles done rightAnsible roles done right
Ansible roles done rightDan Vaida
 
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsChasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsTomas Doran
 
Ansible + WordPress
Ansible + WordPressAnsible + WordPress
Ansible + WordPressAlan Lok
 
Infrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & AnsibleInfrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & Ansiblewajrcs
 
DevOps for Humans - Ansible for Drupal Deployment Victory!
DevOps for Humans - Ansible for Drupal Deployment Victory!DevOps for Humans - Ansible for Drupal Deployment Victory!
DevOps for Humans - Ansible for Drupal Deployment Victory!Jeff Geerling
 

What's hot (20)

Infrastructure = Code
Infrastructure = CodeInfrastructure = Code
Infrastructure = Code
 
Introduction to Ansible (Pycon7 2016)
Introduction to Ansible (Pycon7 2016)Introduction to Ansible (Pycon7 2016)
Introduction to Ansible (Pycon7 2016)
 
Ansible module development 101
Ansible module development 101Ansible module development 101
Ansible module development 101
 
How Ansible Makes Automation Easy
How Ansible Makes Automation EasyHow Ansible Makes Automation Easy
How Ansible Makes Automation Easy
 
Ansible - A 'crowd' introduction
Ansible - A 'crowd' introductionAnsible - A 'crowd' introduction
Ansible - A 'crowd' introduction
 
Network Automation with Ansible
Network Automation with AnsibleNetwork Automation with Ansible
Network Automation with Ansible
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with Ansible
 
Testing Ansible with Jenkins and Docker
Testing Ansible with Jenkins and DockerTesting Ansible with Jenkins and Docker
Testing Ansible with Jenkins and Docker
 
Ansible Automation to Rule Them All
Ansible Automation to Rule Them AllAnsible Automation to Rule Them All
Ansible Automation to Rule Them All
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentation
 
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
 
Go Faster with Ansible (PHP meetup)
Go Faster with Ansible (PHP meetup)Go Faster with Ansible (PHP meetup)
Go Faster with Ansible (PHP meetup)
 
DevOps, A brief introduction to Vagrant & Ansible
DevOps, A brief introduction to Vagrant & AnsibleDevOps, A brief introduction to Vagrant & Ansible
DevOps, A brief introduction to Vagrant & Ansible
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentation
 
Ansible Crash Course
Ansible Crash CourseAnsible Crash Course
Ansible Crash Course
 
Ansible roles done right
Ansible roles done rightAnsible roles done right
Ansible roles done right
 
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and JenkinsChasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
 
Ansible + WordPress
Ansible + WordPressAnsible + WordPress
Ansible + WordPress
 
Infrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & AnsibleInfrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & Ansible
 
DevOps for Humans - Ansible for Drupal Deployment Victory!
DevOps for Humans - Ansible for Drupal Deployment Victory!DevOps for Humans - Ansible for Drupal Deployment Victory!
DevOps for Humans - Ansible for Drupal Deployment Victory!
 

Similar to infra-as-code

Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetAchieve Internet
 
Continuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierContinuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierCarlos Sanchez
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabricandymccurdy
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Carlos Sanchez
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 
Control your deployments with Capistrano
Control your deployments with CapistranoControl your deployments with Capistrano
Control your deployments with CapistranoRamazan K
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
Wordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionWordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionSysdig
 
Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slidesDocker, Inc.
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.catPablo Godel
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabricandymccurdy
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesLindsay Holmwood
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013grim_radical
 
Postgres the hardway
Postgres the hardwayPostgres the hardway
Postgres the hardwayDave Pitts
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOpsОмские ИТ-субботники
 

Similar to infra-as-code (20)

Cooking with Chef
Cooking with ChefCooking with Chef
Cooking with Chef
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
 
Continuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierContinuous Delivery: The Next Frontier
Continuous Delivery: The Next Frontier
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Control your deployments with Capistrano
Control your deployments with CapistranoControl your deployments with Capistrano
Control your deployments with Capistrano
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
Wordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionWordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccion
 
Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slides
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.cat
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabric
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Docker, c'est bonheur !
Docker, c'est bonheur !Docker, c'est bonheur !
Docker, c'est bonheur !
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
 
Ubic
UbicUbic
Ubic
 
Ubic-public
Ubic-publicUbic-public
Ubic-public
 
Puppet
PuppetPuppet
Puppet
 
Postgres the hardway
Postgres the hardwayPostgres the hardway
Postgres the hardway
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
 

infra-as-code

  • 1. Itamar Hassin April 2015 INFRASTRUCTURE DEVELOPMENT USING CUCUMBER, SEVERSPEC & ANSIBLE
  • 2. THE GOAL •Avoid snowflakes •Fail fast (offline!) and cycle quickly •Be able to sustain infrastructure as it expands •Support apps and heterogeneous environments •Optimise SA’s time (reduce manualVDDs) •Time To Rebuild < Time To Fix
  • 3. IAC, BDD, MDD •Infrastructure As Code •Behaviour-Driven Development •Monitor-Driven Development
  • 4. A way by which we can define, provision, and configure hardware andVirtual Machines to suite our needs INFRASTRUCTURE AS CODE
  • 5. An activity whereby a feature’s behaviour is described prior to its implementation BEHAVIOUR DRIVEN DEVELOPMENT
  • 6. MONITOR DRIVEN DEVELOPMENT • Write production monitors based on desired result • Implement enough infrastructure to satisfy the monitor • Refactor • Repeat
  • 7. OURTOOLBOX MDD Provisioning BDD IAC ServerSpec Vagrant Cucumber Ansible
  • 8. SERVERSPEC With Serverspec, you can write tests for checking your servers are configured correctly.
  • 9. VAGRANT Vagrant is a computer software for creating and configuring virtual development environments.
  • 11. ANSIBLE Ansible is a radically simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.
  • 12. SALLY & LEO AT WORK Danielle: I want a web server. Sally: Sure, boss. Danielle: We’re a silo-ed org. Sally: Sure, boss. Danielle: The Admins need specs. Sally: Sure, boss. Sally: Leo, let’s pair.
  • 13. WORKFLOW How Sally and Leo go about setting up a web server in such a way that it •Is automated •Is repeatable and measurable •Assures environments for consistent development testing
  • 14. SALLY WRITES SPECS
 (IN A WORD DOC) Feature:
 As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it.
 
 Background:
 Given my server is available
 And I provision it
 
 Scenario:
 When I get access to it
 Then I expect it to have apache running
  • 15. THEY USE BDD $ cucumber No such file or directory @ rb_sysopen - features. Please create a features directory to get started. (Errno::ENOENT)
  • 16. MAKE FEATURES DIRECTORY $ mkdir features
  • 17. CUCUMBER IS SET UP $ cucumber 0 scenarios 0 steps 0m0.000s
  • 18. PASTE FEATURE
 (FROM WORD DOC) Feature:
 As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it.
 
 Background:
 Given my server is available
 And I provision it
 
 Scenario:
 When I get access to it
 Then I expect it to have apache running
  • 19. MISSING STEPS $ cucumber Feature: As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it. Background: # features/httpd.feature:4 Given my server is available # features/httpd.feature:5 And I provision it # features/httpd.feature:6 Scenario: # features/httpd.feature:8 When I get access to it # features/httpd.feature:9 Then I expect it to have apache running # features/httpd.feature:10 1 scenario (1 undefined) 4 steps (4 undefined) 0m0.002s You can implement step definitions for undefined steps with these snippets: Given(/^my server is available$/) do pending # express the regexp above with the code you wish you had end When(/^I provision it$/) do pending # express the regexp above with the code you wish you had end
  • 20. WORKFLOW At this stage, the high-level functional requirement needs more specification, so they MDD the server
  • 21. THEY WRITE A MONITOR describe package('apache2') do it { should be_installed } end describe service('apache2') do it { should be_enabled } it { should be_running } end describe port(80) do it { should be_listening } end describe file('/etc/apache2/sites-enabled/000-default.conf') do it { should be_file } it { should contain "example.com" } end
  • 22. MISSINGVAGRANT A Vagrant environment or target machine is required to run this command. Run `vagrant init` to create a new Vagrant environment. Or, get an ID of a target machine from `vagrant global-status` to run this command on.
  • 23. THEY CREATE AVAGRANTFILE Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "Ubuntu 14.04" config.vm.define "webserver" config.vm.hostname = "webserver" config.vm.network "private_network", ip: "33.33.33.33" config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--memory", "1024"] end end
  • 24. THEY RUN MONITOR AGAIN $ rake spec ruby -S rspec spec/webserver/httpd_spec.rb FFFFFF Failures: 1) Package "apache2" should be installed Failure/Error: it { should be_installed } sudo dpkg-query -f '${Status}' -W apache2 | grep -E '^(install|hold) ok installed$' expected Package "apache2" to be installed # ./spec/webserver/httpd_spec.rb:4:in `block (2 levels) in <top (required)>' 2) Service "apache2" should be enabled Failure/Error: it { should be_enabled } sudo ls /etc/rc3.d/ | grep -- '^S..apache2' || sudo grep 'start on' /etc/init/apache2.conf expected Service "apache2" to be enabled # ./spec/webserver/httpd_spec.rb:8:in `block (2 levels) in <top (required)>'
  • 25. THEY PROVISION AVM Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "Ubuntu 14.04" config.vm.define "webserver" config.vm.hostname = "webserver" config.vm.network "private_network", ip: "33.33.33.33" config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--memory", "1024"] end config.vm.provision "ansible" do |ansible| ansible.playbook = "playbook.yml" ansible.inventory_path = "inventory.ini" ansible.sudo = true end end
  • 26. THEY RUN MONITOR $ rake spec ruby -S rspec spec/webserver/httpd_spec.rb There are errors in the configuration of this machine. Please fix the following errors and try again: ansible provisioner: * `playbook` for the Ansible provisioner does not exist on the host system: playbook.yml ...... Finished in 3.51 seconds 6 examples, 0 failures
  • 27. THEY WRITE PLAYBOOK --- - hosts: all user: vagrant sudo: true roles: - common - apache
  • 28. COMMON ROLE EXAMPLE - name: Update apt cache if needed
 apt: update_cache=yes cache_valid_time=3600
 
 - name: Upgrade OS
 apt: upgrade=dist force=yes
 
 - name: Install needed packages
 apt: pkg={{item}} state=installed
 with_items:
 - cron
 - logrotate
 - curl
 - git
 - update-motd
 
 - name: Create the deploy user
 user: name={{user}} comment="deploy user" generate_ssh_key=yes ssh_key_bits=2048 state=present password={{password}} shell=/bin/bash
 
 - name: Set {{user}} as sudoer
 lineinfile: dest=/etc/sudoers line="{{user}} ALL=(ALL) NOPASSWD ":" ALL"
 
 - name: remove ubuntu's user
 user: name=ubuntu state=absent remove=yes
  • 30. THEY RUNVAGRANT $ vagrant provision webserver ==> webserver: Running provisioner: ansible... PLAY [webserver] ************************************************************** GATHERING FACTS *************************************************************** ok: [webserver] TASK: [kamaln7.swapfile | Create swapfile] ************************************ changed: [webserver] TASK: [common | Update apt cache if needed] *********************************** ok: [webserver] TASK: [common | Upgrade OS] *************************************************** ok: [webserver] TASK: [common | Install needed packages] ************************************** ok: [webserver] => (item=cron,logrotate,curl,git,update-motd) TASK: [common | Create the deploy user] *************************************** ok: [webserver]
  • 31. WORKFLOW At this stage,Vagrant and Ansible scripts provision and configure the server, so all that’s left is to tie that to the suspended Cucumber spec
  • 32. STEP IMPLEMENTATION FOR CUCUMBER Given(/^my server is available$/) do
 output=`vagrant reload`
 end
 
 And(/^I provision it$/) do
 output=`vagrant provision`
 end
 
 When(/^I get access to it$/) do
 run_remote("ls")
 end
 
 Then(/^I expect it to have apache running$/) do
 run_remote("ps asx | grep apache")
 end
 
 def run_remote(command)
 Net::SSH.start("33.33.33.33", "vagrant", :password => "vagrant") do |ssh|
 result = ssh.exec!(command)
 end
 end
  • 33. GOODTIMES LEO RUNSTHE MONITOR $ rake spec ruby -S rspec spec/webserver/httpd_spec.rb ...... Finished in 3.73 seconds 6 examples, 0 failures SALLY RUNS CUCUMBER $ cucumber Feature: As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it. Background: # features/httpd.feature:4 Given my server is available # features/steps/httpd_steps.rb:3 And I provision it # features/steps/httpd_steps.rb:8 Scenario: # features/httpd.feature:8 When I get access to it # features/steps/httpd_steps.rb:12 Then I expect it to have apache running 1 scenario (1 passed) 4 steps (4 passed)
  • 34. $ rake spec ruby -S rspec spec/webserver/httpd_spec.rb ...... Finished in 3.73 seconds 6 examples, 0 failures LEO RUNSTHE MONITOR
  • 35. $ cucumber Feature: As a Webmaster (yeah baby!) I need a webserver to be running so that I may master it. Background: # features/httpd.feature:4 Given my server is available # features/steps/httpd_steps.rb:3 And I provision it # features/steps/httpd_steps.rb:8 Scenario: # features/httpd.feature:8 When I get access to it # features/steps/httpd_steps.rb:12 Then I expect it to have apache running 1 scenario (1 passed) 4 steps (4 passed) 0m8.433s SALLY RUNS CUCUMBER
  • 37. AUTOMATION • Commit the Cucumber and ServerSpec source code to git • Add a Jenkins task to run the scripts as part of the integration test suite • Add ServerSpec as a monitor in all environments to ensure server configuration immutability
  • 38. SOURCE CONTROL SCaaCC • Infrastructure code is part of the app code • Developers and SysAdmins share code using git for modifications. • HugOps can use master • Others can use branching or forking
  • 39. XP PRACTICES • SysAdmins are part of the development team • Participate in standups, part of a story/task cards • Participate in pairing sessions • Empathise
  • 40. REFERENCES TheVisible Ops Handbook James White's manifesto DevOps Conferences Ansible Cucumber ServerSpec