This repository uses Ansible and Vagrant to demonstrate how a single build and deployment process can be used to provision and deploy the local, QA, and Production versions of a site.
The minimum requirements to run the VMs and playbooks in this repository are:
Not tested on Windows.
If you're the impatient type, and if you already have the various requirements on your system, here's how to get started:
git clone git@github.com:ctorgalson/deploy-everywhere.git
cd deploy-everywhere && ./quickstart.sh
This will:
- Create a new vault password file for Ansible,
.deploy-vault
, - Create a new Vagrant vm,
dev
, - Sync the contents of
site/docroot
in the repo to the VM, - Create a second Vagrant vm,
prod
, - Provision
dev
using Ansible, - Provision
prod
using Ansible, - Run the command
gulp watch
insite/docroot
.
From scratch, this takes about seven minutes on my venerable 2014 Mac Mini.
You may begin working immediately :)
(To follow all of these steps, you'll need to [fork the repository] first).
-
Clone the repository:
git clone git@github.com:ctorgalson/deploy-everywhere.git
-
Enable
pre-push
githook (optional; see more about what this does below):cd deploy-everywhere && ln -s .githooks/pre-push .git/hooks/pre-push
-
Change to the repo directory and create Ansible vault password file:
cd deploy-everywhere && echo 'deploy-everywhere' > .deploy-vault
-
Boot servers (and auto-provision and deploy
dev
):cd devops && vagrant up
-
Run provisioning and initial deployment to
prod
:ansible-playbook deployment.yml --limit=deploy_prod
-
Get some work done:
-
Checkout a new branch:
git checkout -b newbranch
-
Change to the site directory and start the
gulp watch
task:cd ../site && npx gulp watch
-
Make changes in
site/
, -
Commit changes:
git commit -am 'Committing changes to demo repo.'
-
Run deployment test and push changes to remote repo:
git push origin newbranch
-
-
Deploy changes to
prod
:ansible-playbook deployment.yml --limit=deploy_prod --tags=deploy
The repository includes a Vagrantfile that configures two virtual machines:
- A development server,
dev-01.deploy.local
, and - A production server,
prod-01.deploy.local
.
This server is the local development server. Files from the repository's site/
directory are automatically synchronized to the virtual machine.
This server is provided to illustrate a realistic workflow, including environment variables that differ from those on the local development server. A real project would use a real remote server.
The repository's Vagrantfile
defines both servers, but since prod
is meant to simulate a remote server, we don't use Vagrant to provision it or deploy the application to it. The dev
server, on the other hand, is our local development server, so we can use either Vagrant commands or Ansible commands to interact with it.
We can run the provision play and/or the deployment play on one or both servers:
# Run provision and deployment plays on both hosts.
ansible-playbook deployment.yml
We can also use the ansible-playbook
command's --limit
or --tags
switches.
See hosts.yml to see the host and groups names available.
# Run provision and deployment plays on `dev`.
ansible-playbook deployment.yml --limit=deploy_dev
# Run provision and deployment plays on `prod`.
ansible-playbook deployment.yml --limit=deploy_prod
See deployment.yml to see the available plays and tags.
# Run provision play only both hosts.
ansible-playbook deployment.yml --tags=provision
# Run deploy play only on both hosts.
ansible-playbook deployment.yml --tags=deploy
It's also possible to use Vagrant commands to run ansible-playbook
commands against the dev
host by setting enviroment variables and then running vagrant up
or vagrant provision
. The Vagrantfile
makes use of two environment variables:
$VAT
: values as foransible-playbook
's--tags
option.$VAV
: values as foransible-playbook
's--verbose
option.
The only operation Vagrant commands can run on both servers is to boot them:
# Boot `dev` and `prod`, and run Ansible provisioner on `dev`.
vagrant up
# Boot `dev` only, and run Ansible provisioner.
vagrant up dev
# Boot `prod` only.
vagrant up prod
# Run only `provision` play on `dev` when vagrant runs for the first time.
VAT=provision vagrant up dev
# Run only `deploy` play when booting `dev`.
VAT=deploy vagrant up --provision dev
# Run only `deploy` play on already-booted `dev` host.
VAT=deploy vagrant provision
This repository includes a directory, .githooks that contains a pre-push
Git hook. Git hooks are generally scripts that correspond to a particular git command (git push
in this instance), run when that command is issued, and cause the command to fail or continue.
The pre-push
hook in this repo will only allow the push
operation to succeed if the current codebase can be successfully deployed to the dev
server.