Instantly share code, notes, and snippets.

Embed
What would you like to do?
---
- name: Deploy new site release
user: deployer
hosts: all
tasks:
- name: Fetch repo updates
git: >
repo=git@github.com:my/repo.git
dest="{{ git_cache_path }}"
version=master
accept_hostkey=yes
- name: Get release timestamp
command: date +%Y%m%d%H%M%S
register: timestamp
- name: Name release directory
command: echo "{{ releases_dir }}/{{ timestamp.stdout }}"
register: release_path
- name: Create release directory
file: >
state=directory
owner=deployer
group=wheel
recurse=yes
path={{ release_path.stdout }}
- name: Cop release
command: rsync -avz -avz --exclude-from '{{ git_cache_path }}/.slugignore' {{ git_cache_path }}/ {{ release_path.stdout }}
- name: Update app version
file: >
state=link
path=/var/apps/cis_env/cis
src={{ release_path.stdout }}
- name: Link uploads folder
file:
state=link
path="{{ release_path.stdout }}/app/assets/uploads"
src={{ uploads_dir }}
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
# general config
set :application, "myapp"
set :valid_environments, ["staging","production"]
set :user, "deployer"
# git config
set :scm, :git
set :repository, "git@github.com:my/repo.git"
set :branch, "master"
set :deploy_via, :remote_cache
default_run_options[:pty] = true
# set :use_sudo, true
# ssh_options[:forward_agent] = true
set :current_dir, "myapp"
namespace :deploy do
desc "Sets up basic directory structure on target server"
task :setup, :except => { :no_release => true } do
dirs = [deploy_to, releases_path, shared_path]
dirs += shared_children.map { |d| File.join(shared_path, d) }
run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
end
desc <<-DESC
Updates the symlink to the most recently deployed version. Capistrano works \
by putting each new release of your application in its own directory. When \
you deploy a new version, this task's job is to update the `current' symlink \
to point at the new version. You will rarely need to call this task \
directly; instead, use the `deploy' task (which performs a complete \
deploy, including `restart') or the 'update' task (which does everything \
except `restart').
DESC
task :create_symlink, :except => { :no_release => true } do
on_rollback do
if previous_release
run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
else
logger.important "no previous release to rollback to, rollback of symlink skipped"
end
end
# delete the old and create a new symlink to the latest release
run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
# delete the uploads directory out of the new codebase if it exists. then symlink the uploads directory to there.
# run "rm -rf #{latest_release}/app/assets/uploads && ln -s #{deploy_to}/shared/uploads #{latest_release}/app/assets/uploads"
run "ln -s #{deploy_to}/shared/uploads #{latest_release}/app/assets/uploads"
end
desc <<-DESC
Restarts your application.
By default, this will be invoked via sudo as the 'app' user. If
you are in an environment where you can't use sudo, set
the :use_sudo variable to false:
set :use_sudo, false
DESC
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{sudo} chown -R www-data:www-data /var/apps/myapp/shared/uploads/"
run "#{sudo} /etc/init.d/apache2 reload"
end
desc <<-DESC
[internal] Touches up the released code. This is called by update_code \
after the basic deploy finishes.
This task will make the release group-writable (if the :group_writable \
variable is set to true, which is the default). It will then change \
ownership of the release and the symlink that was created if the owners \
variable exists.
DESC
task :finalize_update, :except => { :no_release => true } do
# run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
run "#{sudo} chown -R #{owners} #{current_path}" if exists?("owners")
run "#{sudo} chown -R #{owners} #{latest_release}" if exists?("owners")
end
end

Project: Django site for which original deployment was scripted with Capistrano. Updating the site and using Ansible to wrangle the server configurations. Why not deploy with it too?

Observed that for similar "Capistrano style" deployments, Capistrano is typically much faster at executing a deployment.

I've noticed a similar discrepancy between Fabric and Capistrano and suspect it comes down to the model of executing discrete commands (Ansible and Fabric) vs. bundling shell commands (Capistrano). This is based on observed output of Capistrano and my understanding of how Ansible and Fabric execute commands, which I do not assert to be authoritative!

Using Capistrano v2.15.4 and Ansible 1.5.4. Ran from my computer over my home network with Verizon FiOS. Target server is a small testing server on Rackspace:

Ansible total time: 1:50.44 total (43.821 total from a Digital Ocean instance) Capistrano total time: 16.951 total

The Ansible deployment playbook was written to try to follow the Capistrano steps as closely as possible (difference in using rsync vs. Capistrano's cp, however).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment