Test DrivenTest Driven
InfrastructureInfrastructure
Angel NúñezAngel Núñez
@snahider@snahider
Agile Developer,Agile Developer,
Consultant & TrainerConsultant & Trainer
InfrastructureInfrastructure
asas
CodeCode
Desafíos deDesafíos de
Operaciones e InfrastructuraOperaciones e Infrastructura
Alta disponibilidad.
Respuesta rápida a petición de infraestructura.
Evitar 'Configuration Drifts'.
Alta confianza al realizar cambios.
Auditoría, versionamiento y seguimiento a los cambios.
Scripts y Virtualización noScripts y Virtualización no
son suficientes.son suficientes.
¿Qué es¿Qué es
Infrastructure as Code?Infrastructure as Code?
Significa escribir código
(usualmente utilizando un lenguaje de alto nivel)
para aprovisionar la infraestructura
(proveer todo lo necesario para su funcionamiento)
utilizando buenas prácticas de desarrollo de software
(prácticas que ya se utilizan en el desarrollo de aplicaciones).
Aparecen las HerramientasAparecen las Herramientas
PuppetPuppet ChefChef
package { 'apache2':
ensure => installed,
}
service { 'apache2':
ensure => running,
require => Package['apache2'],
}
file { '/var/www/html/index.html':
content => '<html>hello world</html>',
owner => 'root',
mode => '640',
ensure => present,
}
package 'apache2' do
action :install
end
service 'apache2' do
action [:enable, :start]
end
file '/var/www/html/index.html' do
content '<html>hello world</html>'
owner 'root'
mode '640'
action :create
end
Características: Abstracción e Idempotencia
¿Cómo es el código¿Cómo es el código
de infraestructura?de infraestructura?
Nuestro ContextoNuestro Contexto
Nuestra empresa a invertido en infraestructura como
código para manejar diversos servidores.
El área de desarrollo está compuesta por 4 divisiones
de productos, cada división trabaja con su propio
ambiente de IC utilizando Jenkins.
Gestionamos los servidores donde se encuentra
Jenkins a través de un módulo de Puppet.
Módulo de JenkinsMódulo de Jenkins
class myjenkins(
$plugins = undef
){
include jenkins
include myjenkins::default_plugins
if ($plugins){
jenkins::plugin { $plugins: }
}
}
class myjenkins::default_plugins{
$default_plugins = ['greenballs']
jenkins::plugin{$default_plugins:}
}
El códigoEl código
Cómo se utilizaCómo se utiliza
node 'ciserver'{
class {'myjenkins':
plugins => ['chucknorris','htmlpublisher']
}
include 'sonar'
}
ProbandoProbando
Infrastructure CodeInfrastructure Code
Unit TestUnit Test
Probar unitariamente el código sin
provisionar (alterar) un nodo real.
Integration TestsIntegration Tests
Verificar que el código provisiona
un nodo real de la manera
esperada.
Tipos de PruebasTipos de Pruebas
(Chef) Simular una ejecución y verificar
si la llamada a un recurso se ha
realizado.
(Puppet) Generar el catálogo y verificar
si un recurso se encuentra presente.
UnitUnit
TestingTesting
RSpec-PuppetRSpec-Puppet
https://github.com/rodjek/rspec-puppet
HerramientaHerramienta
TestsTests
# manifests/init.pp
class myjenkins(
$plugins = undef
){
include jenkins
if ($plugins){
jenkins::plugin { $plugins: }
}
}
# spec/classes/jenkins_spec.rb
describe 'myjenkins' do
context 'the following should be in the catalog' do
it { should contain_class('jenkins')}
end
context 'with plugins' do
let(:params){
{
:plugins => ['htmlpublisher']
}
}
it { should contain_jenkins__plugin('htmlpublisher')}
end
end
ProducciónProducción
Unit TestsUnit Tests
MockMock
# spec/spec_helper.rb
RSpec.configure do |c|
c.default_facts = {
:operatingsystem => 'Ubuntu',
:operatingsystemrelease => '14.04',
:osfamily => 'Debian',
:path => '/usr/local/bin/'
}
end
Unit TestsUnit Tests
IntegrationIntegration
TestingTesting
Desafíos al RealizarDesafíos al Realizar
Integration TestingIntegration Testing
Crear ambientes de pruebas
de manera fácil y repetible.
Interrogar el estado real del servidor.
Un Test Harness que combine lo anterior.
VagrantVagrant
https://www.vagrantup.com/
ServerspecServerspec
http://serverspec.org/
BeakerBeaker
https://github.com/puppetlabs/beaker
PruebaPrueba
# spec/acceptance/jenkins_spec.rb
describe 'jenkins class' do
it 'should work with no errors' do
pp = "include myjenkins"
# Run it twice and test for idempotency
expect(apply_manifest(pp).exit_code).to eq(0)
expect(apply_manifest(pp).exit_code).to eq(0)
end
#Serverspec
describe service('jenkins') do
it { should be_enabled }
end
end
# spec/acceptance/nodesets/default.yml
HOSTS:
ubuntu-1404-x86:
roles:
- masterless
platform: ubuntu-1404-x86_64
hypervisor: vagrant
box: ubuntu14.04-x86
Ambiente de PruebaAmbiente de Prueba
Integration TestsIntegration Tests
Configuración delConfiguración del
AmbienteAmbiente
# spec/spec_helper_acceptance.rb
RSpec.configure do |c|
# Configure all nodes in nodeset
c.before :suite do
hosts.each do |host|
# Install this module
copy_module_to(host, :source => module_root,
:module_name => 'myjenkins')
# copies all the module dependencies
rsync_to(host ,fixture_modules, '/etc/puppet/modules/')
end
end
end
Test DrivenTest Driven
InfrastructureInfrastructure
El CicloEl Ciclo
Test Driven InfrastructureTest Driven Infrastructure
Integration TestIntegration Test Unit TestUnit Test
El CasoEl Caso
Varios equipos tienen la iniciativa de empezar a
trabajar con Git.
Como encargados de gestionar la infraestructura
necesitamos soportar Git en los ambientes de
Integración Continua.
Para eso vamos a extender el módulo de Jenkins
para que incluya el Plugin de git por defecto y
también instale Git en el sistema.
Let's Code!Let's Code!
ReflexionesReflexiones
¿A nivel Unitario estamos diseñando?
¿Escribimos una prueba por cada recurso?
¿Hay practicas que no se trasladan directamente
desde software a infraestructura?
Porqué CD y DevopsPorqué CD y Devops
necesitannecesitan
Infrastructure as CodeInfrastructure as Code
Infrastructure as Code es un habilitador:
Permite agregar la infraestructura al pipeline de
Continuous Delivery.
Permite que Operaciones pueda utilizar prácticas
ágiles para gestionar la infraestructura.
Rompe barreras entre Dev y OPS.
PreguntasPreguntas
ReferenciasReferencias
Presentación (código y slides):
https://github.com/snahider/test-driven-infrastructure

Test Driven Infrastructure