ansibleを使ったデプロイツールAnsistranoを使ってみた

# 動機
手動でのデプロイが常態化してしまっている職場に, いい加減デプロイツールを導入しようと思い立つ.
以前使ったことがあるcapistranoでも良かったのですが, ansibleをもう少し使っていきたいので
ansistranoを使うことにする

# 動作環境ほか
## ansibleのバージョン
```
$ ansible --version
ansible 2.1.0.0
```

## gitのあれこれ
リポジトリはgithubではなく, 社内に立てているgitlabで管理している.
また, gitlabサーバには, sshを使ってアクセスする

## デプロイ対象のサーバ
実験のためにローカルのvagrant環境にデプロイを行う

# ansistranoのインストール
ansistranoは, ansistrano-deployとansistrano-rollbackの2つのroleから構成されており,
それぞれansible-galaxyを使ってインストールを行います.

```
$ sudo ansible-galaxy install carlosbuenosvinos.ansistrano-deploy carlosbuenosvinos.ansistrano-rollback
```

# playbookの作成と, その実行結果
deploy.ymlという名前で, 以下のようなplaybookを作り

```yml:deploy.yml
- hosts: all
  vars:
    ansistrano_deploy_via: git
    ansistrano_git_repo: ssh://git@our.gitlab.server/repos/sample.git
    ansistrano_git_identity_key_path: /Users/hoge/.ssh/id_rsa
    ansistrano_shared_paths: ["backend/runtime"]
    ansistrano_after_update_code_tasks_file: roles/after_update_code.yml
  vars_files:
    - vars/{{ env }}.yml
  roles:
    - carlosbuenosvinos.ansistrano-deploy
```

以下のコマンドを実行すると

```
$ ansible-playbook -i dev_hosts deploy.yml
```

デプロイ先サーバに以下のようなファイルが展開されました

```
[vagrant@localhost sample]$ tree -L 1
.
├── current -> ./releases/20161021034119Z
├── git_identity_key
├── releases
├── repo
└── shared
```

# 作業手順
## デプロイ先ホストの情報をまとめるhostsファイルを作成する
開発環境向けhostsファイルとして, dev_hostsという名前で以下のようなファイルを作ります

```dev_hosts
[web]
192.168.33.100

[all:vars]
env=Development
```

ansibleは, 様々な場所で変数の定義ができますが, 後に環境毎の変数ファイルを読み込むために
ここで, 変数envを定義しておきます.


## deploy.ymlを作成する
```deploy.yml:yml
- hosts: all
  vars:
    ansistrano_deploy_via: git
    ansistrano_git_repo: ssh://git@our.gitlab.server/repos/sample.git
    ansistrano_git_identity_key_path: /Users/hoge/.ssh/id_rsa
    ansistrano_shared_paths: ["backend/runtime"]
    ansistrano_after_update_code_tasks_file: roles/after_update_code.yml
  vars_files:
    - vars/{{ env }}.yml
  roles:
    - carlosbuenosvinos.ansistrano-deploy
```

メインとなるPlaybookです.
各環境で共通となる変数はここで定義しておき, 各環境毎に変わる変数は
``` vars/{{ env }}.yml ```に記述することにします.
(この環境毎の変数の切り分け方は[こちら](http://qiita.com/NewGyu/items/5de31d76d2488ab27ed6)を参考にしました)

それぞれの変数の意味は以下の通り

| 変数名 | 意味 |
|-------|------|
|ansistrano_deploy_via |展開するソースファイルの取得方法 |
|ansistrano_git_repo |ソースをgitで取得する場合に使うリポジトリURL |
|ansistrano_git_identity_key_path |ソースをgitで取得する場合に使うSSHの秘密キー |
|ansistrano_shared_paths |各リリース間で共有するディレクトリ |
|ansistrano_after_update_code_tasks_file |UpdateCodeの後に呼ばれるタスクが書かれたHookファイルのパス. |

なお, 今回は使っていないその他Hookが定義されているタイミングと, 対応する変数については
[こちら](https://github.com/ansistrano/deploy/blob/master/README.md#main-workflow)を参照してみて下さい

## 環境毎の変数ファイルを作成する

```yml:Develop.yml
ansistrano_git_branch: feature/something
ansistrano_deploy_to: /vagrant/sample
ansible_ssh_user: vagrant
ansible_ssh_private_key_file: /Users/hoge/sample/.vagrant/machines/default/virtualbox/private_key
```

このファイルに各環境毎に異なりうる変数を定義していきます.
それぞれの変数の意味は以下の通り.

| 変数名 | 意味 |
|-------|------|
| ansistrano_git_branch | ソースをgitで取得する場合に使うブランチ名 |
| ansistrano_deploy_to | ソースを展開先するディレクトリパス |
| ansible_ssh_user | リモートサーバにアクセスするユーザ名(ansibleで定義された変数) |
| ansible_ssh_private_key_file | リモートサーバにアクセスする際に使うSSHの秘密鍵(ansibleで定義された変数) |

## 各種Hookファイルを作成する
最新ファイルの取得後に, composer installとフレームワークの初期化スクリプトを実行したいので
`ansistrano_after_update_code_tasks_file`で指定したパスに以下のようなファイルを作ります.


```yml:roles/after_update_code.yml
- name: composer install
  shell: composer instal
  args:
    chdir: "{{ ansistrano_release_path.stdout }}"

- name: switch framework environment
  shell: php init --env={{ env }} --overwrite=y
  args:
    chdir: "{{ ansistrano_release_path.stdout }}"

```

## デプロイを実行する
ここまで, 作業ディレクトリの内容は以下のようになっていると思われます.

```
$ tree
.
├── deploy.yml
├── dev_hosts
├── roles
│   └── after_update_code.yml
└── vars
└── Development.yml

```

後は, 最初に作成したdev_hostsをホスト指定してデプロイを実行するだけ

```
$ ansible-playbook -i dev_hosts deploy.yml

PLAY [] ******************************************************

TASK [setup] *******************************************************************
ok: [192.168.33.100]

....................

PLAY RECAP *********************************************************************
192.168.33.100             : ok=32   changed=13   unreachable=0    failed=0

$ 
```

デプロイの完了後, 開発環境を確認してみると... 

```
[vagrant@localhost sample]$ tree -L 2
.
├── current -> ./releases/20161021085411Z
├── git_identity_key
├── releases
│   └── 20161021085411Z
├── repo
│   ├
│   └
└── shared
    └── backend


[vagrant@localhost sample]$ ll current/vendor/
total 4
drwxr-xr-x 1 vagrant vagrant 442 Oct 21 17:54 .
drwxr-xr-x 1 vagrant vagrant 918 Oct 21 17:54 ..
-rw-r--r-- 1 vagrant vagrant 183 Oct 21 17:54 autoload.php
drwxr-xr-x 1 vagrant vagrant 136 Oct 21 17:54 bin
drwxr-xr-x 1 vagrant vagrant 272 Oct 21 17:54 bower-asset
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 cebe
drwxr-xr-x 1 vagrant vagrant 374 Oct 21 17:54 composer
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 ezyang
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 firebase
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 fzaninotto
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 phpspec
drwxr-xr-x 1 vagrant vagrant 102 Oct 21 17:54 swiftmailer
drwxr-xr-x 1 vagrant vagrant 408 Oct 21 17:54 yiisoft


[vagrant@localhost sample]$ ll current/backend/
total 4
drwxr-xr-x 1 vagrant vagrant 374 Oct 21 17:54 .
drwxr-xr-x 1 vagrant vagrant 918 Oct 21 17:54 ..
drwxr-xr-x 1 vagrant vagrant 272 Oct 20 16:10 assets
drwxr-xr-x 1 vagrant vagrant 306 Oct 21 17:54 config
drwxr-xr-x 1 vagrant vagrant 136 Oct 20 16:10 controllers
drwxr-xr-x 1 vagrant vagrant 102 Oct 20 16:10 messages
drwxr-xr-x 1 vagrant vagrant 170 Oct 20 16:10 models
lrwxr-xr-x 1 vagrant vagrant  31 Oct 21 17:54 runtime -> ../../../shared/backend/runtime
drwxr-xr-x 1 vagrant vagrant 136 Oct 20 16:10 views
drwxr-xr-x 1 vagrant vagrant 510 Oct 21 17:54 web
```

最新のソースがreleases以下にコピーされ, composer installをして, 共有するディレクトリを
shareディレクトリへシンボリックリンクした上で, 
そのディレクトリを最新版としてcurrentからシンボリックリンクを貼っていることが確認できると思います.

あとは, このcurrentディレクトリがDocumentRootになるようにWebサーバに設定すれば, 以降のデプロイは
何も考えずにコマンド一発でおあるようになります.


# 対応環境を増やす
今回はdevelop環境だけを作りましたが, stage環境を作りたい場合は, stage_hostsを作り
vars/stage.ymlに環境変数をまとめた上で

```
$ ansible-playbook -i stage_hosts deploy.yml
```

と実行するだけでOKです.


# 参考
[Ansistorano](https://github.com/ansistrano/deploy/blob/master/README.md)

[構成管理ツールで Ansible を使ってる人必見！デプロイするなら Ansistrano ロールを使おう！](http://qiita.com/kotarella1110/items/23ba0e1fb1eda974630c)

[Ansibleのインベントリファイルでステージを切り替える](http://qiita.com/NewGyu/items/5de31d76d2488ab27ed6)