Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Release Deployments
$ ansible-playbook deploy/deploy.yml
$ ansible-playbook deploy/migrations.yml
$ ansible-playbook deploy/startup.yml
#! /usr/bin/env bash
ansible-playbook deploy/deploy.yml
# deploy-release.yml
---
# 1
- name: check to see if release archive exists locally
stat:
path: "{{ release_archive_path }}"
register: release_stat
delegate_to: 127.0.0.1
# 2
- name: fail if no local release
fail:
msg: "Local release tarball not found. Copy it to {{ release_archive_path }}."
when: not release_stat.stat.exists
# 3
- name: clean remote release directory
file:
path: "{{remote_release_dir}}"
state: absent
- name: create remote release directory
file:
path: "{{remote_release_dir}}"
state: directory
# 4
- name: unarchive release on remote server
unarchive:
src: "{{release_archive_path}}"
dest: "{{remote_release_dir}}"
# 5
- name: check to see if release artifact exists remotely
stat:
path: "{{remote_release_artifact_path}}"
register: remote_release_artifact_stat
# 6
- name: echo end
debug:
var: remote_release_artifact_stat.stat.exists
~/project/deploy/
--- facts/
---- project-facts.yml
---- postgres-facts.yml
--- tasks/
---- system-setup.yml
---- postgres.yml
---- deploy-release.yml
---- run-migrations.yml
---- up.yml
---- down.yml
-- create-db.yml
-- deploy.yml
-- migrations.yml
-- startup.yml
-- teardown.yml
# down.yml
---
# 1
- name: check to see if release artifact exists remotely
stat:
path: "{{remote_release_artifact_path}}"
register: remote_release_artifact_stat
# 2
- name: stop remote server
command: "{{remote_release_artifact_path}} stop"
when: remote_release_artifact_stat.stat.exists
register: stop_cmd
# 3
- name: clean remote release directory
file:
path: "{{remote_release_dir}}"
state: absent
# 4
- name: echo end
debug:
var: stop_cmd
# mix.exs
...
defp aliases do
[
deploy: ["cmd ./path/to/deploy.sh"],
up: ["cmd ./path/to/up.sh"],
down: ["cmd ./path/to/down.sh"]
]
end
# postgres.yml
- name: install psycopg2
pip:
name: psycopg2
# postgres.yml
- name: create postgres user
postgresql_user:
name: "{{database_user}}" # 1
password: "{{database_password}}" # 1
role_attr_flags: CREATEDB,SUPERUSER # 2
state: present
become_user: postgres # 3
become: yes # 4
- name: create database
postgresql_db:
name: "{{database_name}}" # 1
encoding: "UTF-8"
become_user: postgres # 3
become: yes # 4
# postgres-facts.yml
- when: "database_name is not defined"
name: "compute database name"
set_fact:
database_name: "{{ lookup('env', 'DATABASE_NAME') }}"
- name: set database host
set_fact:
database_host: "{{ lookup('env', 'DATABASE_HOST') }}"
- name: create or get postgres password
set_fact:
database_password: "{{ lookup('env', 'DATABASE_PASSWORD') }}"
- name: set database user
set_fact:
database_user: "{{ lookup('env', 'DATABASE_USER') }}"
# postgres.yml
---
- name: install postgres + postgres packages
apt:
update_cache: yes
state: present
name:
- postgresql
- postgresql-contrib
- libpq-dev
# project-facts.yml
---
- name: set app name
set_fact:
app_name: api
- name: set app version
set_fact:
app_version: "0.1.0"
- name: set credentials directory path
set_fact:
credentials_dir: "~/credentials/"
- name: set release name
set_fact:
release_name: "{{app_name}}-{{app_version}}"
- name: set release directory name
set_fact:
release_dir: "../rel/artifacts/"
- name: set release archive path
set_fact:
release_archive_path: "{{release_dir}}{{release_name}}.tar.gz"
- name: set remote release directory
set_fact:
remote_release_dir: "~/rel/artifacts/"
- name: set remote release archive path
set_fact:
remote_release_archive_path: "{{remote_release_dir}}{{release_name}}.tar.gz"
- name: set remote release artifact path
set_fact:
remote_release_artifact_path: "{{remote_release_dir}}opt/build/_build/prod/rel/api/bin/api"
# release_tasks.ex
defmodule ReleaseTasks do
def migrate do
{:ok, _} = Application.ensure_all_started(:app)
Ecto.Migrator.run(
Api.Repo,
path("priv/repo/migrations"),
:up,
all: true
)
# Close process
:init.stop()
end
end
# run-migrations.yml
---
# 1
- name: check if postgres is running
command: "/etc/init.d/postgresql status"
register: postgres_status
# 2
- fail:
msg: "Postgres is not running"
when: postgres_status.stderr != "" or postgres_status.failed != false
# 3
- name: check to see if release artifact exists remotely
stat:
path: "{{remote_release_artifact_path}}"
register: remote_release_artifact_stat
# 4
- fail:
msg: "No remote release artifact"
when: not remote_release_artifact_stat.stat.exists
# 5
- name: run migrations on remote server
command: "{{remote_release_artifact_path}} eval 'ReleaseTasks.migrate'"
when: remote_release_artifact_st.stat.exists
$ scp local/path/to/release/folder username@host_ip:remote/path/to/release/folder
$ ssh username@host_ip
<... authenticate ...>
$ local/path/to/release/folder daemon
# system-setup.yml
- name: install pip
apt:
update_cache: yes
state: present
name: python-pip
---
- name: install system packages
apt:
update_cache: yes
state: present
name:
- gcc
- g++
- curl
- wget
- unzip
- git
- python-dev
- python-apt
- make
- automake
- autoconf
- libreadline-dev
- libncurses-dev
- libssl-dev
- libyaml-dev
- libxslt-dev
- libffi-dev
- libtool
- unixodbc-dev
#! /usr/bin/env bash
ansible-playbook deploy/startup.yml
# up.yml
---
# 1
- name: check to see if release artifact exists remotely
stat:
path: "{{remote_release_artifact_path}}"
register: remote_release_artifact_stat
# 2
- name: start remote server
command: "{{remote_release_artifact_path}} daemon"
when: remote_release_artifact_stat.stat.exists
register: foo
# 3
- name: echo end
debug:
var: foo
$ mix deploy
$ mix up
# For tear down...
$ mix down
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment