-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e807ae9
Showing
13 changed files
with
315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Ansible Deployment Playbook | ||
|
||
An ansible playbook for deploying a WordPress site from a git repository. | ||
|
||
This is currently a proof of concept and likely isn't generic enough to work | ||
for most deployment processes. Feel free to fork it and adapt to your needs. | ||
|
||
We're using [Composer to manage the site stack](http://composer.rarst.net/recipe/site-stack) along with a [SatisPress](https://github.com/blazersix/satispress) instance to manage private packages. Only custom code is stored in site repository. | ||
|
||
The repository and node modules are cached in a workspace to speed up subsequent deployments. | ||
|
||
|
||
## Getting Started | ||
|
||
Install [Ansible](http://docs.ansible.com/intro_installation.html) then run the following commands: | ||
|
||
```sh | ||
# Clone this repository. | ||
git clone [email protected]:cedaro/ansible-deploy.git | ||
|
||
# Change to the cloned repository | ||
cd ansible-deploy | ||
|
||
# Run the deploy playbook using the testing inventory | ||
ansible-playbook -i testing deploy.yml | ||
``` | ||
|
||
Running those commands will pull down an [example website](https://github.com/cedaro/website-example) and deploy it to your local machine at `/tmp/ansible-deploy`. | ||
|
||
|
||
## Next Steps | ||
|
||
* Create your own inventory using `group_vars/testing` and `roles/deploy/defaults/main.yml` for guidance. | ||
* Read through the tasks in `roles/deploy/tasks` to see what tasks are run. | ||
|
||
|
||
## Slack Integration | ||
|
||
The `slack-command-handler.php` file serves as a quick demonstration for using a [Slack slash command](https://api.slack.com/slash-commands) to call an Ansible playbook. The handler should be placed in a web-accessible location. | ||
|
||
After registering the command with Slack, a deployment can be kicked off from any channel with a command similar to the following: | ||
|
||
``` | ||
/deploy production master | ||
``` | ||
|
||
|
||
## Resources | ||
|
||
* [npm without sudo](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md) | ||
|
||
|
||
## To Do | ||
|
||
* Deploy a specific commit, branch, or tag (should already be possible with `--extra-vars`) | ||
* Implement a rollback method | ||
* Clean up old releases | ||
* [Official deploy helper module](https://github.com/ansible/ansible-modules-extras/pull/110) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
- name: Deploy a repository | ||
hosts: webservers | ||
|
||
pre_tasks: | ||
- slack: | ||
token: "{{ slack_token }}" | ||
msg: "Deploying `{{ branch }}` to {{ inventory_hostname }}..." | ||
when: slack_token is defined | ||
|
||
- set_fact: | ||
releases_path: "{{ deploy_to }}/releases" | ||
release_directory: "{{ lookup('pipe', 'date -u +%Y%m%d%H%M%S') }}" | ||
|
||
- set_fact: | ||
build_path: "{{ workspace }}/build-{{ release_directory }}" | ||
cache_path: "{{ workspace }}/cache" | ||
release_path: "{{ releases_path }}/{{ release_directory }}" | ||
|
||
roles: | ||
- { role: deploy } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
## | ||
# The git repository and branch to deploy. | ||
## | ||
|
||
repository: https://github.com/cedaro/example-website.git | ||
branch: master | ||
|
||
|
||
## | ||
# Path where the repository is cached and the application is built. | ||
# | ||
# Creates the following paths: | ||
# | ||
# Repository cache: {{ workspace }}/cache | ||
# Release build: {{ workspace }}/build-20150709100000 | ||
## | ||
|
||
workspace: /tmp/ansible-deploy/workspace | ||
|
||
|
||
## | ||
# Path where the application should be deployed. | ||
# | ||
# Creates the following paths: | ||
# | ||
# Active version: {{ deploy_to }}/current | ||
# All releases: {{ deploy_to }}/releases | ||
# Deployed release: {{ deploy_to }}/releases/20150709100000 | ||
# Log file: {{ deploy_to }}/deploy.log | ||
## | ||
|
||
deploy_to: /tmp/ansible-deploy | ||
|
||
## | ||
# A list of files to exclude from the deployment. | ||
## | ||
|
||
excludes: | ||
- .editorconfig | ||
- .git | ||
- .gitignore | ||
- composer.json | ||
- composer.lock | ||
- config | ||
- Gruntfile.js | ||
- node_modules | ||
- package.json | ||
- README.md | ||
- wordpress/wp-content | ||
|
||
|
||
## | ||
# Add a Slack Incoming Webhook token to send notifications when a deploy begins | ||
# and finishes. | ||
# | ||
# https://api.slack.com/incoming-webhooks | ||
## | ||
|
||
#slack_token: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
respository: | ||
branch: master | ||
|
||
workspace: /tmp/ansible-deploy/workspace | ||
deploy_to: /tmp/ansible-deploy/deploy_to | ||
|
||
composer_no_dev: yes | ||
grunt_path: grunt | ||
grunt_task: "" | ||
slack_token: "" | ||
|
||
excludes: [] | ||
symlinks: [] | ||
|
||
default_symlinks: | ||
- src: shared/object-cache.php | ||
dest: content/object-cache.php | ||
- src: shared/blogs.dir | ||
dest: content/blogs.dir | ||
- src: shared/cache | ||
dest: content/cache | ||
- src: shared/uploads | ||
dest: content/uploads |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
--- | ||
- name: Clone the repository | ||
git: | ||
repo="{{ repository }}" | ||
dest="{{ cache_path }}" | ||
accept_hostkey=yes | ||
version={{ branch }} | ||
force=yes | ||
register: git_clone_result | ||
|
||
- name: Install npm dependencies | ||
npm: | ||
path="{{ cache_path }}" | ||
production=yes | ||
|
||
- name: Create the build directory | ||
file: path="{{ build_path }}" state=directory | ||
|
||
- name: Copy the project to the build directory | ||
synchronize: | ||
src="{{ cache_path }}/" | ||
dest="{{ build_path }}/" | ||
rsync_opts=--exclude=.git | ||
delegate_to: "{{ inventory_hostname }}" | ||
|
||
- name: Install Composer dependencies | ||
composer: | ||
command=install | ||
working_dir="{{ build_path }}" | ||
no_dev={{ composer_no_dev }} | ||
optimize_autoloader=yes | ||
|
||
- name: Run Grunt build task | ||
command: "{{ grunt_path }} {{ grunt_task }}" | ||
args: | ||
chdir: "{{ build_path }}" | ||
when: grunt_task != "" | ||
|
||
- name: Remove excluded files | ||
file: path="{{ build_path }}/{{ item }}" state=absent | ||
with_items: excludes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
- name: Move the build directory to the release path | ||
command: "mv {{ build_path }} {{ release_path }}" | ||
|
||
- name: Make it live | ||
file: | ||
src="{{ release_path }}" | ||
path="{{ deploy_to }}/current" | ||
state=link |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
- name: Log the deployment | ||
lineinfile: | ||
dest="{{ deploy_to}}/deploy.log" | ||
line="{{ ansible_date_time.iso8601 }} - Deployed {{ branch }} (commit {{ git_clone_result.after }}) to {{ release_path }} on {{ inventory_hostname }}" | ||
create=yes | ||
|
||
- slack: | ||
token: "{{ slack_token }}" | ||
msg: "Finished deploying `{{ branch }}` to {{ inventory_hostname }}." | ||
when: slack_token != "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
- include: setup.yml | ||
- include: build.yml | ||
- include: shared.yml | ||
- include: deploy.yml | ||
- include: log.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
- name: Ensure the workspace exists | ||
file: path="{{ workspace }}" state=directory | ||
|
||
- name: Ensure the releases directory exists | ||
file: path="{{ releases_path }}" state=directory | ||
|
||
- name: Ensure the shared directory exists | ||
file: path="{{ deploy_to }}/shared" state=directory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
- name: Check for wp-config.php in shared directory | ||
stat: path="{{ deploy_to }}/shared/wp-config.php" | ||
register: config_stat | ||
|
||
- name: Copy wp-config.php to the build directory | ||
synchronize: | ||
src="{{ deploy_to }}/shared/wp-config.php" | ||
dest="{{ build_path }}/wp-config.php" | ||
delegate_to: "{{ inventory_hostname }}" | ||
when: config_stat.stat.exists | ||
|
||
- name: Check for shared files and directories | ||
stat: path="{{ deploy_to }}/{{ item.src }}" | ||
register: shared_stat | ||
with_items: default_symlinks | union(symlinks) | ||
|
||
- name: Create shared symlinks | ||
file: | ||
src="{{ deploy_to }}/{{ item.item.src }}" | ||
path="{{ build_path }}/{{ item.item.dest }}" | ||
state=link | ||
when: item.stat.exists | ||
with_items: shared_stat.results |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
/** | ||
* Slack slash command handler. | ||
* | ||
* Receives a payload from a slash command and calls an Ansible playbook. This | ||
* should be placed in a web-accessible location and registered with Slack. | ||
* | ||
* @link https://api.slack.com/slash-commands | ||
*/ | ||
|
||
define( 'SLACK_TOKEN', '' ); | ||
define( 'ANSIBLE_INVENTORY_PATH', '/srv/www/ansible' ); | ||
define( 'ANSIBLE_PLAYBOOK_PATH', '/srv/www/ansible' ); | ||
|
||
// Ensure this is a POST request with a valid token. | ||
if ( empty( $_POST['token'] ) || SLACK_TOKEN !== $_POST['token'] ) { | ||
exit( 1 ); | ||
} | ||
|
||
// @todo Consider validating users here. | ||
|
||
list( $environment, $branch ) = explode( ' ', $_POST['text'] ); | ||
|
||
// Validate the environment. | ||
$environments = array( 'production', 'staging' ); | ||
if ( ! in_array( $environment, $environments ) ) { | ||
exit( 'Invalid environment. Choose `production` or `staging`.' ); | ||
} | ||
|
||
// Sanitize the branch to deploy. | ||
if ( 'production' === $environment ) { | ||
$branch = 'production'; | ||
} elseif ( empty( $branch ) ) { | ||
$branch = 'staging'; | ||
} | ||
|
||
// Connection details are managed in Ansible inventory. | ||
$command = sprintf( | ||
'sudo -H -u deploy /usr/bin/ansible-playbook -i %1$s/%2$s%3$s %4$s/deploy.yml', | ||
rtrim( ANSIBLE_INVENTORY_PATH, '/' ) | ||
$environment, | ||
'staging' === $environment ? ' -c local' : '', | ||
rtrim( ANSIBLE_PLAYBOOK_PATH, '/' ) | ||
); | ||
|
||
set_time_limit( 0 ); | ||
exec( escapeshellcmd( $command ), $output ); | ||
exit( 0 ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[webservers] | ||
localhost ansible_connection=local | ||
|
||
[testing:children] | ||
webservers |