Skip to content

Instantly share code, notes, and snippets.

@addamh
Forked from bennylope/ansible.yml
Created July 17, 2014 19:23
Show Gist options
  • Save addamh/bd113416c957b10c1c51 to your computer and use it in GitHub Desktop.
Save addamh/bd113416c957b10c1c51 to your computer and use it in GitHub Desktop.

Revisions

  1. @bennylope bennylope created this gist Apr 30, 2014.
    44 changes: 44 additions & 0 deletions ansible.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    ---
    - name: Deploy new site release
    user: deployer
    hosts: all

    tasks:

    - name: Fetch repo updates
    git: >
    [email protected]: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 }}
    94 changes: 94 additions & 0 deletions capistrano.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,94 @@
    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, "[email protected]: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
    12 changes: 12 additions & 0 deletions comments.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    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).