project_deploy_module

Project deploy module (deploy_helper)

The included module is the proposed deploy_helper module for ansible-modules-extra

General explanation, starting with an example folder structure for a project:

root: releases: - 20140415234508 - 20140415235146 - 20140416082818

shared:
    - sessions
    - uploads

current: -> releases/20140416082818

The 'releases' folder holds all the available releases. A release is a complete build of the application being deployed. This can be a clone of a repository for example, or a sync of a local folder on your filesystem. Having timestamped folders is one way of having distinct releases, but you could choose your own strategy like git tags or commit hashes.

During a deploy, a new folder should be created in the releases folder and any build steps required should be performed. Once the new build is ready, the deploy procedure is 'finalized' by replacing the 'current' symlink with a link to this build.

The 'shared' folder holds any resource that is shared between releases. Examples of this are web-server session files, or files uploaded by users of your application. It's quite common to have symlinks from a release folder pointing to a shared/subfolder, and creating these links would be automated as part of the build steps.

The 'current' symlink points to one of the releases. Probably the latest one, unless a deploy is in progress. The web-server's root for the project will go through this symlink, so the 'downtime' when switching to a new release is reduced to the time it takes to switch the link.

To distinguish between successful builds and unfinished ones, a file can be placed in the folder of the release that is currently in progress. The existence of this file will mark it as unfinished, and allow an automated procedure to remove it during cleanup.

Typical usage:

- name: Initialize the deploy root and gather facts
  deploy_helper: path=/path/to/root
- name: Clone the project to the new release folder
  git: repo=git://foosball.example.org/path/to/repo.git dest={{ deploy_helper.new_release_path }} version=v1.1.1
- name: Add an unfinished file, to allow cleanup on successful finalize
  file: path={{ deploy_helper.new_release_path }}/{{ deploy_helper.unfinished_filename }} state=touch
- name: Perform some build steps, like running your dependency manager for example
  composer: command=install working_dir={{ deploy_helper.new_release_path }}
- name: Create some folders in the shared folder
  file: path='{{ deploy_helper.shared_path }}/{{ item }}' state=directory
  with_items: ['sessions', 'uploads']
- name: Add symlinks from the new release to the shared folder
  file: path='{{ deploy_helper.new_release_path }}/{{ item.path }}'
        src='{{ deploy_helper.shared_path }}/{{ item.src }}'
        state=link
  with_items:
      - { path: "app/sessions", src: "sessions" }
      - { path: "web/uploads",  src: "uploads" }
- name: Finalize the deploy, removing the unfinished file and switching the symlink
  deploy_helper: path=/path/to/root release={{ deploy_helper.new_release }} state=finalize

Retrieving facts before running a deploy

- name: Run 'state=query' to gather facts without changing anything
  deploy_helper: path=/path/to/root state=query

Remember to set the 'release' parameter when you actually call 'state=present' later

- name: Initialize the deploy root
  deploy_helper: path=/path/to/root release={{ deploy_helper.new_release }} state=present

all paths can be absolute or relative (to the 'path' parameter)

- deploy_helper: path=/path/to/root
                 releases_path=/var/www/project/releases
                 shared_path=/var/www/shared
                 current_path=/var/www/active

Using your own naming strategy for releases (a version tag in this case):

- deploy_helper: path=/path/to/root release=v1.1.1 state=present
- deploy_helper: path=/path/to/root release={{ deploy_helper.new_release }} state=finalize

Using a different unfinished_filename:

- deploy_helper: path=/path/to/root
                 unfinished_filename=README.md
                 release={{ deploy_helper.new_release }}
                 state=finalize

Postponing the cleanup of older builds:

- deploy_helper: path=/path/to/root release={{ deploy_helper.new_release }} state=finalize clean=False
- deploy_helper: path=/path/to/root state=clean

Or running the cleanup ahead of the new deploy

- deploy_helper: path=/path/to/root state=clean
- deploy_helper: path=/path/to/root state=present

Keeping more old releases:

- deploy_helper: path=/path/to/root release={{ deploy_helper.new_release }} state=finalize keep_releases=10

Or, if you use 'clean=false' on finalize:

- deploy_helper: path=/path/to/root state=clean keep_releases=10

Removing the entire project root folder

- deploy_helper: path=/path/to/root state=absent

Debugging the facts returned by the module

- deploy_helper: path=/path/to/root
- debug: var=deploy_helper

License

LGPL

Author Information

Ramon de la Fuente, ramon@delafuente.nl

About

Deploy_helper module for building (Capistrano like) deploy roles

Install
ansible-galaxy install f500/ansible-project_deploy_module
GitHub repository
License
lgpl-3.0
Downloads
6785
Owner
Open source contributions by Future500