Ansistrano Deployement
Deploy PHP Apps with Ansistrano
Install Ansible
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
In /etc/ansible/ansible.cfg
[defaults]
host_key_checking = false
Install Ansistrano
$ ansible-galaxy install carlosbuenosvinos.ansistrano-deploy carlosbuenosvinos.ansistrano-rollback
Update If you want to update the role, you need to pass –force parameter when installing. Please, check the following command:
$ ansible-galaxy install –force carlosbuenosvinos.ansistrano-deploy carlosbuenosvinos.ansistrano-rollback
Ansible repository
You could organize your deployment repository by company or by type of project. I call it “ansible” for example, with directory structure :
apps/
base/
files/
README.md
Usage
Install your project (“ansible” for example) from git in the user “deploy” home directory
Create the public key for the “deploy” user
$ ssh-keygen -t rsa
$ cp -v ~/.ssh/id_rsa.pub ~/ansible/files/authorized_keys.deploy.pub
I have created to playbook to init remote host
- base/user-deploy.yml : Create user deploy with permission
- base/vhosts.yml : Create
On each host create the user “deploy”
$ ansible-playbook -i {inventory} base/user-deploy.yml –become -k –ask-become-pass –user={first user create on install}
---
# User Deploy
- name: Prepare and configure user "deploy"
hosts: all
become: yes
tasks:
- name: Add deploy user
user: name=deploy comment="Deploy User" groups=adm,sudo,www-data shell=/bin/bash
- name: Adding authorized key to deploy user
authorized_key: user=deploy key=""
with_file:
- ../files/authorized_keys.deploy.pub
- name: Ensure /etc/sudoers.d is scanned by sudo
# A mistake use pkexec visudo
action: lineinfile dest=/etc/sudoers regexp="#includedir\s+/etc/sudoers.d" line="#includedir /etc/sudoers.d" validate="visudo -cf %s"
- name: Add deploy user to the sudoers
action: 'lineinfile dest=/etc/sudoers.d/deploy state=present create=yes regexp="deploy .*" line="deploy ALL=(ALL) NOPASSWD: ALL" validate="visudo -cf %s"'
- name: Ensure /etc/sudoers.d/deploy file has correct permissions
action: file path=/etc/sudoers.d/deploy mode=0440 state=file owner=root group=root
Check main vhost
$ ansible-playbook -i {inventory} base/vhost.yml
---
# Vhost
- hosts: all
become: yes
tasks:
- name: Create and check vhost directory perms
file: path=/home/vhosts state=directory mode="u=rwx,g=rwx,o=rx" owner=www-data group=www-data
Filter to execute only on one host
$ ansible-playbook -i {inventory} -l 192.168.0.0 playbook.yml
Manage a project to deploy
We want to make progressive deployment, so we have to define how to work. With standard git branch :
- master : production
- develop : staging
Following are the commands to execute a deployement
Deploying
$ ansible-playbook -i hosts -e “ansistrano_release_version=
date -u +%Y%m%d%H%M%SZ
” deploy.yml
Rolling back
$ ansible-playbook -i hosts rollback.yml
Now go read the documentation of Ansistrano to see all the step in the workflow.
-- /home/vhosts/my-app.com
|-- current -> /home/vhosts/my-app.com/releases/20100512131539
|-- releases
| |-- 20100512131539
| |-- 20100509150741
| |-- 20100509145325
|-- shared
You have to make some operation locally and remotely.
Locally :
- Clone your project
- Install dependencies
- … and all other things
Remotely :
- Files are automatically sent (via rsync) in your remote place
- Clean temporary files and warmup cache
Sample with my web app
/home/deploy/ansible/apps/my-app.com
|-- hosts-prod
|-- deploy.yml
|-- etc/
|-- config/
|-- tasks
| |-- before-code-update.yml
| |-- after-code-update.yml
| |-- before-symlink.yml
| |-- after-symlink.yml
| |-- before-cleanup.yml
| |-- after-cleanup.yml
- hosts-prod : contains your production server definition
- deploy.yml : template of ansistrano
- etc/ : specific server config files to be place in your remote server
- config/ : environment files for your project (secret information is store here)
- tasks/ : specific tasks
All these files could be specific for staging.