CD?
"Continuous Delivery" or "Continuous Deployment"?
CD?
"Delivery": Delivering artifact for consumption
CD?
"Deployment": Deploy a delivered artifact
CD?
Upstream projects Deliver
CD?
Consumers (like OPNFV) Deploy
CD?
"Continuous": Project-specific
Per-[patch, commit, build-able artifact, day, semver bump...]
OPNFV
Open Platform for Network Function Virtualization
OPNFV
Integrates SDN/NFV projects
(new type of project)
OPNFV
Installer, test and development projects
OPNFV
Installer projects: Deploy *everything*
OPNFV
Installers: Apex, Compass, Fuel, Joid
OPNFV
Deployments are configured into "scenarios"
OPNFV
Virtual+CentOS+NSH OVS+ODL OVSDB/SFC/GBP+OpenStack
OPNFV
Bare Metal+CentOS+ODL cluster+OpenStack
OPNFV
Virtual+Ubuntu+ODL BGPVPN+OpenStack
OPNFV
Installer projects -> test projects
OPNFV
Test projects: CI against each installer scenario
OPNFV
Test projects: Functest, StorPerf, VSPerf, CPerf...
OPNFV
Test+Installer Projects -> Development Projects
OPNFV
Development projects: Improve upstream
OPNFV
"Improve upstream" <- The important part!
NEW REQ: ARTIFACTS
Modern deployments require complex release artifacts
NEW REQ: ARTIFACTS
Tarballs and hope are not enough
NEW REQ: ARTIFACTS
Upstream must provide well-defined knobs for OPNFV's config
NEW REQ: ARTIFACTS
OPNFV minimum: Install via config management tool
(Puppet, Ansible)
NEW REQ: ARTIFACTS
OPNFV installers use ~Puppet for automated installs
NEW REQ: ARTIFACTS
Config tools typically build on packages
(RPM, .deb)
NEW REQ: ARTIFACTS
Config mgmt tools can be used to build pre-configured images
(Vagrant base boxes, Docker images)
NEW REQ: ARTIFACTS
Affects all projects consumed by OPNFV
(ODL, ONOS, OpenContrail, OVS, DPDK...)
Puppet
Well-developed API
Puppet
We work to make contributing easy.
Puppet
Community: Ubuntu support
Puppet
Supports tarball-based installs
Puppet
class { 'opendaylight':
install_method => 'tarball',
tarball_url => '<URL to your custom tarball>',
unitfile_url => '<URL to your custom unitfile>',
}
Puppet
Soon: Tarballs -> .deb packages
PUPPET
rspec-puppet
(100% coverage, not worth discussion)
Puppet
Deploy against real VMs
Puppet
Verify resulting state
Puppet
Repeat for various configs
Puppet
At a high level...
Puppet
Bringing machine 'centos-7' up with 'virtualbox' provider...
centos-7 12:45:09$ yum install -y puppet
Puppet
centos-7 12:45:46$ puppet apply <test manifest>
Puppet
centos-7 12:49:37$ /bin/sh -c systemctl\ is-active\ opendaylight
active
centos-7 executed in 0.04 seconds
should be running
Puppet
centos-7 12:49:37$ /bin/sh -c id\ odl
uid=1001(odl) gid=1001(odl) groups=1001(odl)
centos-7 executed in 0.04 seconds
should exist
Puppet
centos-7 executed in 0.05 seconds
should match /^featuresBoot=standard,ssh/
Puppet
Finished in 5 minutes 22 seconds (files took 1 minute 10.87 seconds to load)
132 examples, 0 failures
Puppet
Beaker is pretty great
Puppet
Example: Vagrant provisioner
Puppet
At a high level...
Puppet
# Box that installs ODL via Puppet RPM method on CentOS 7
config.vm.define "cent7_pup_rpm" do |cent7_pup_rpm|
# Build Vagrant box based on CentOS 7
cent7_pup_rpm.vm.box = "centos/7"
# Add EPEL repo for access to Puppet et al
cent7_pup_rpm.vm.provision "shell", inline: "yum install -y epel-release"
# Install Puppet
cent7_pup_rpm.vm.provision "shell", inline: "yum install -y puppet"
# Install OpenDaylight using its Puppet module
cent7_pup_rpm.vm.provision "puppet" do |puppet|
puppet.module_path = ["modules"]
puppet.manifest_file = "odl_install.pp"
end
end
Puppet
puppet.manifest_file = "odl_install.pp"
Puppet
[~/vagrant-opendaylight]$ cat manifests/odl_install.pp
class { 'opendaylight':
extra_features => ['odl-ovsdb-sfc'],
}
Puppet
[~/vagrant-opendaylight]$ vagrant up cent7_pup_rpm
Puppet
ODL installed
Notice: /Stage[main]/Opendaylight::Install/Yumrepo[opendaylight]/ensure: created
Notice: /Stage[main]/Opendaylight::Install/Package[opendaylight]/ensure: created
Puppet
Features configured
/Stage[main]/Opendaylight::Config/File[org.apache.karaf.features.cfg]/content: content changed '<hash>' to '<different hash>'
Puppet
[~/vagrant-opendaylight]$ vagrant ssh cent7_pup_rpm
[vagrant@localhost ~]$
Puppet
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Puppet
[vagrant@localhost ~]$ ssh -p 8101 karaf@localhost
# password "karaf"
Puppet
opendaylight-user@root>feature:list | grep odl-ovsdb-sfc
odl-ovsdb-sfc | 1.2.1-Beryllium | x | odl-ovsdb-sfc-1.2.1-Beryllium <snip>
Ansible
[~/ansible-opendaylight]$ cat tasks/main.yml
---
- include: install_odl.yml
- include: configure_karaf_features.yml
- include: configure_nb_rest_port.yml
- include: open_nb_rest_port.yml
- include: start_odl.yml
Ansible
- name: Start ODL systemd service
service:
name=opendaylight
enabled=yes
state=started
Ansible
- name: Configure ODL Karaf features
template:
src=org.apache.karaf.features.cfg
dest=/opt/opendaylight/etc/
owner=odl
group=odl
notify:
- Stop ODL
- Cleanup Karaf
- Start ODL
Ansible
[~/ansible-opendaylight]$ wc -l **/*.yml
<snip>
203 total
Ansible
Rejects Puppet's style of testing
“don’t unit test your playbook"
“Ansible believes you should not need another framework to validate basic things of your infrastructure”
Ansible
So no rspec-puppet or Beaker
Ansible
Fail fast and clearly
Ansible
Focus on the deployment logic
Ansible
Example: Vagrant provisioner
Ansible
At a high level...
Ansible
# Box that installs ODL via its Ansible role on CentOS 7
config.vm.define "cent7_ansible" do |cent7_ansible|
# Build Vagrant box based on CentOS 7
cent7_ansible.vm.box = "centos/7"
# Install ODL using the Ansible provisioner
cent7_ansible.vm.provision "ansible" do |ansible|
# Path to Ansible playbook that installs ODL using ODL's Ansible role
ansible.playbook = "provisioning/playbook.yml"
end
end
Ansible
ansible.playbook = "provisioning/playbook.yml"
ansible
Provision the box
Ansible
[~/vagrant-opendaylight]$ vagrant up cent7_ansible
ansible
At a high level...
Ansible
TASK: [opendaylight | Add ODL yum repo] **********************************
changed: [cent7_ansible]
TASK: [opendaylight | Install ODL via RPM repo] **************************
changed: [cent7_ansible]
Ansible
TASK: [opendaylight | Check if FirewallD service is running] *************
ok: [cent7_ansible]
TASK: [opendaylight | Open ODL NB REST port via FirewallD] ***************
skipping: [cent7_ansible]
Ansible
TASK: [opendaylight | Start ODL systemd service] *************************
changed: [cent7_ansible]
Ansible
[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible
[vagrant@localhost ~]$
Ansible
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Ansible
Example: Config change
Ansible
[~/vagrant-opendaylight]$ cat provisioning/playbook.yml
---
- hosts: all
sudo: yes
roles:
- role: opendaylight
extra_features: ['odl-ovsdb-sfc']
Ansible
[~/vagrant-opendaylight]$ vagrant provision cent7_ansible
ansible
At a high level...
Ansible
TASK: [opendaylight | Configure ODL Karaf features] **********************
changed: [cent7_ansible]
Ansible
NOTIFIED: [opendaylight | Stop ODL] **************************************
changed: [cent7_ansible]
NOTIFIED: [opendaylight | Cleanup Karaf] *********************************
changed: [cent7_ansible]
NOTIFIED: [opendaylight | Start ODL] *************************************
changed: [cent7_ansible]
Ansible
[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible
Ansible
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Ansible
[vagrant@localhost ~]$ /vagrant/scripts/connect.sh
Ansible
opendaylight-user@root>feature:list | grep odl-ovsdb-sfc
odl-ovsdb-sfc | 1.2.1-Beryllium | x | odl-ovsdb-sfc-1.2.1-Beryllium <snip>