Вы находитесь на странице: 1из 26

Continuous deployment with Jenkins and Salt

LinuxCon CloudOpen ContainerCon


North America 2015, Seattle
Anirban Saha
About me
Techie…
Traveller…
Thinker…

Author of ‘Salt Cookbook’


Deployment
Should be…

• Simple
• Stable
• Fast (good to have…)
• Reliable
• One click
Problems faced
• Code distribution
• Additional tasks (commands, migrations)
• Latency
• Parallel execution
• Batch deployments
• Ensuring uptime
Methods available
Deployment

Configuration management tools :

• Puppet, Chef, Ansible, Salt

Remote execution tools:

• SSH, Parallel SSH, Rundeck

Packages:

• Code packaged as RPM or DEB files


Code storage
• GIT server (Github, Gitlab, Bitbucket, etc.)

• Object storage (Amazon S3, Swift, etc.)

• Package repositories (YUM/Debian)

• Configuration management repositories

• File servers managed manually


Problems
Deployment:
• Remote execution tools :
• Time consuming (over SSH)
• Need to maintain inventory of hosts

Code storage:
• GIT repositories:
• Usually centrally located, latency when deployed from GIT
• Package repositories (RPM/DEB):
• Problems in simultaneously updating repo metadata

Rollback:
• Version manipulation is a problem with most configuration
management and remote execution tools
Salt
Provides…

• Agent based communication


• Fast execution
• Orchestration
• Batch execution
• Strong Integration with providers and
services
Salt features
Targeting deployment nodes :

• By hostname
• ‘myappweb*’

• By specific grains
• -G ‘node_type:webserver’

• By nodegroups
• -N webgroup
Salt features
Task dependencies :

• Salt requisites to make tasks dependent on each other

get_archive:
module.run:
.
.
deploy_app:
module.run:
.
.
- require:
- module: get_archive
Salt features
Orchestration :

webgrp2_deploy:
salt.state:
- tgt: ' webgrp2'
- tgt_type: nodegroup
- sls:
- webserver.deploy
- require:
- salt: webgrp1_deploy

webgrp1_deploy:
salt.state:
- tgt: 'webgrp1'
- tgt_type: nodegroup
- sls:
- webserver.deploy
Salt features
Batch Execution :

• By number of hosts
• --batch-size 5
• Executes on 5 hosts at a time

• By percentage of hosts
• --batch-size 25%
• Executes on 25% of total target
hosts at a time
Salt features
Salt API:
# curl -H "Accept: application/json"
-d secretkey= "mysupersecretkey"
-k https://10.0.0.2:8080/hook/deploy

{"success": true}
Tools
To be used…

• GIT for code repository


• Jenkins for CI
• Ant for build and tasks
• Amazon S3 for code archive storage
• Salt for deployment
• Shell scripts (good old bash) for
additional tasks
Salt deployment methods

• Salt hosted on the Jenkins server.


Jenkins calls Salt binary

• Salt hosted independently.


Jenkins calls Salt via SSH

• Jenkins calls Salt via Salt API


Objective
Steps
• salt-cloud used to launch instances

• Post install actions used to synchronize EC2 grains

• Salt reactor used to run states on new instances ,


perform deployment and register with load balancer

• Jenkins build job used to build new code, create tags


and push new deployment ready archive to Amazon
S3

• Jenkins deploy job used to fetch new code version


and deploy code on target servers
Steps explained
• Salt cloud is used to spawn instances
• Following parameter is provided in the profile to push custom EC2 grains,
• sync_after_install: grains

• The node is registered and deregistered from the load balancer with the
following module definition,

register:
module.run:
- name: boto_elb.register_instances
- m_name: mywebapp
- instances:
- {{ grains['ec2']['instance_id'] }}

• Here ['ec2']['instance_id'] is one of the custom grains pushed to the node


Steps explained
Fetching archive:

Salt s3 execution module used to get code archive from


Amazon S3

fetch_app_archive:
module.run:
- name: s3.get
- bucket: mywebapp-us
- path: mywebapp-{{ app_version }}.tar
- local_file: /tmp/mywebapp-{{ app_version }}.tar
Steps explained
Setting App version grain:

After every deploy, a grain is set to record the


app version deployed for tracking,

app_version:
grains.present:
- value: {{ app_version }}
- require:
- cmd: deploy_app
Steps explained
Deployment based on App version:

At every deploy, it is checked if the version to


be deployed is already on the node using the
app_version grain,

{% if grains['app_version'] != app_version %}
deregister:
fetch_app_archive:
deploy_app:
register:
{% endif %}
Lets do it then !!!
Demo repository
Get the demo repository at the
following location,

https://github.com/rosesnthornz/
cloudopen-na-2015
Questions ?
Contact
Email :
sahaanirban1988@gmail.com

Twitter : @rosesnthornz
Thank You !!!

Вам также может понравиться