RailsアプリをAnsibleで構築した環境にCapistranoでデプロイするまでにやったこと


# 実現したいこと
+ Ansibleで構成管理
	+ Ansible ServerはローカルにVagrantで立てる(host)
	+ Ansible Clientは構成の検証用(node)とec2に用意する。nodeは失敗したら潰して立て直す。上手くいったらec2に変更を適用する
+ capistranoでデブロイ
	+ ローカルから実行できることを目的とする
	+ よって、CIツールとの連携や自動化は今回のスコープ外とする

![Untitled.jpg](https://qiita-image-store.s3.amazonaws.com/0/2624/c16cfdc6-6c79-59e3-16aa-2b6cadcf0493.jpeg "Untitled.jpg")

#Vagrant
##BaseBoxの追加
本来は本番環境になるべく近いイメージを用意したいところですが、今回はアメリカ国立再生可能エネルギー研究所の提供するBaseBoxを利用して進めます（Chef 11.8.0, Puppet 3.3.1が入ってしまっていますが影響ないと判断しました）。

```bash
$ vagrant box add centos64 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box

$ vagrant init centos64
```

## Ansibleの設定ファイルもコミットできるようにローカルに保存できるようにしておく
```
$ mkdir ansible_data
```

## hostとnodeの作成
```Vagrantfile
  config.vm.define :host do |node|
    node.vm.box = "centos64"
    node.vm.network :forwarded_port, guest: 22, host: 2001, id: "ssh"
    node.vm.network :private_network, ip: "192.168.33.11"
  end
 
  config.vm.define :node do |node|
    node.vm.box = "centos64"
    node.vm.network :forwarded_port, guest: 22, host: 2002, id: "ssh"
    node.vm.network :forwarded_port, guest: 80, host: 3000, id: "http"
    node.vm.network :private_network, ip: "192.168.33.12"
  end

config.vm.synced_folder "./ansible_data", "/home/vagrant/ansible_data"
```

## hostからnodeとec2にssh接続できるようにしておく
それぞれの鍵ファイルをhostの`~/.ssh`にコピーしてあげます。

```bash
$ vagrant ssh-config host > ssh_config
$ vagrant ssh-config node >> ssh_config
$ scp -F ssh_config ~/.vagrant.d/insecure_private_key host:.ssh/id_rsa
$ scp -F ssh_config ~/.ssh/aws.pem host:.ssh/aws.pem
```

# Ansible (サーバセットアップ編）
## hostとnodeの立ち上げ
```bash
$ vagrant up
```

## hostにAnsibleサーバをインストール
```bash
$ vagrant ssh host

[vagrant@localhost ~]$ wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

[vagrant@localhost ~]$ sudo rpm -Uvh epel-release-6-8.noarch.rpm 

[vagrant@localhost ~]$ sudo yum install ansible -y

[vagrant@localhost ~]$ ansible --version
ansible 1.7
```

## hostファイルの作成

```bash
cd ansible_data
vi hosts
```
```hosts
[vagrant]
192.168.33.12 ansible_ssh_user=vagrant ansible_ssh_private_key_file=~/.ssh/id_rsa

[ec2]
54.xxx.xxx.xxx ansible_ssh_user=ec2-user ansible_ssh_private_key_file=~/.ssh/aws.pem
```

## 接続テスト
```bash
[vagrant@localhost ansible_data]$ ansible all -i hosts -m ping
192.168.33.12 | success >> {
    "changed": false, 
    "ping": "pong"
}

54.xxx.xxx.xxx | success >> {
    "changed": false, 
    "ping": "pong"
}
```

## ここまでに参考にしたサイト
+ [Ansible入門 (全15回) - プログラミングならドットインストール](http://dotinstall.com/lessons/basic_ansible)
+ [構成管理ツール Ansibleを使ってみる ｜ Developers.IO](http://dev.classmethod.jp/tool/ansible/)

また、Ansibleの基礎的な知識の習得は、[Ansible Meetup in Tokyo 2014.09](http://ansible-users.connpass.com/event/7942/)でLTを行いましたのでそちらの資料を参考にしていただければと思います。

LT資料：[Where to start Ansible ~初心者のためのAnsibleの始め方~](https://speakerdeck.com/tetsuya/where-to-start-ansible-chu-xin-zhe-falsetamefalseansiblefalseshi-mefang)

# Capistrano
## CapistranoのインストールとCapfileの作成
```Gemfile
group :development do
  gem 'capistrano', :require => false
  gem 'capistrano-rails', :require => false
  gem 'capistrano-rbenv', :require => false
  gem 'capistrano-bundler', :require => false
  gem 'capistrano3-unicorn', :require => false
end
```

```bash
$ bundle install --path vendor/bundle
```

```bash
$ bundle exec cap install
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
Capified
```

```Capfile
# Load DSL and Setup Up Stages
require 'capistrano/setup'

# Includes default deployment tasks
require 'capistrano/deploy'

# Includes tasks from other gems included in your Gemfile
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.1.3'
require 'capistrano/bundler'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
```

```/config/deploy.rb
# config valid only for Capistrano 3.1
lock '3.2.1'

set :application, 'my_app'
set :repo_url, 'git@github.com:foobar/#{application}.git'

# Default deploy_to directory is /var/www/#{application}
set :deploy_to, '/var/www/#{application}'

# Default value for :log_level is :debug
set :log_level, :info

# Default value for linked_dirs is []
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

set :bundle_flags, "--quiet"

after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
```

```/config/deploy/staging.rb
set :stage, :staging
set :branch, 'master'
server '192.168.33.12',
  user: 'vagrant',
  roles: %w{app},
  ssh_options: {
    keys: [File.expand_path('~/.vagrant.d/insecure_private_key')],
    auth_methods: %w(publickey)
  }
```

```/config/deploy/production.rb
set :stage, :production
set :branch, 'master'
server '54.xxx.xxx.xxx',
  user: 'ec2-user',
  roles: %w{app},
  ssh_options: {
    keys: [File.expand_path('~/.ssh/unote-aws.pem')],
    auth_methods: %w(publickey)
  }
```

```/config/unicorn.rb
app_path = "/var/www/my_app"
# Set the working application directory
# working_directory "/path/to/your/app"
working_directory "#{app_path}/current"

# Unicorn PID file location
# pid "/path/to/pids/unicorn.pid"
pid "#{app_path}/current/tmp/pids/unicorn.pid"

# Path to logs
# stderr_path "/path/to/log/unicorn.log"
# stdout_path "/path/to/log/unicorn.log"
stderr_path "#{app_path}/current/log/unicorn.log"
stdout_path "#{app_path}/current/log/unicorn.log"

# Unicorn socket
listen "/tmp/unicorn.my_app.sock"

# use correct Gemfile on restarts
before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile"
end

# Number of processes
worker_processes 2

# Time-out
timeout 60

# preload
preload_app true

# copied from https://github.com/tablexi/capistrano3-unicorn/blob/master/examples/unicorn.rb
before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
  end

  # Before forking, kill the master process that belongs to the .oldbin PID.
  # This enables 0 downtime deploys.
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end
end
```

```bash
$ bundle exec cap staging deploy:check
ERRORrbenv: 2.1.3 is not installed or not found in ~/.rbenv/versions/2.1.3
cap aborted!
```

上手く接続できたようです。当然、検証環境(node)には何もインストールされていないのでrbenvが無いよと怒られました。

## ここまでに参考にしたサイト
+ [unicorn + rails 用 Capistrano 3 の設定ファイル - Qiita](http://qiita.com/satococoa/items/9b0cc416ffc042680b9b)
+ [Capistrano 3系でRails4.1のデプロイ[rbenv][rvm][ruby2.1] - 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/capistrano3-rails-deploy-multi-rbenv/)
+ [tablexi/capistrano3-unicorn](https://github.com/tablexi/capistrano3-unicorn)

コメントにも書いていますが、`/config/unicorn.rb`のpreloadの設定まわりは[capistrano3-unicorn/unicorn.rb at master · tablexi/capistrano3-unicorn](https://github.com/tablexi/capistrano3-unicorn/blob/master/examples/unicorn.rb)をそのまんま利用しています。unicornのpreloadに関してはこちらのサイトが参考になりました。

+ [unicornのpreload_app - motsatのブログ](http://d.hatena.ne.jp/motsat/20120314/1331736445)

# Ansible (クライアントセットアップ編）

ここからAnsibleのコードを書いていくわけですが、インフラの知識が無いためかなり苦労しました。トライアンドエラーで、まずは検証環境(node)で環境構築が上手くいってからEC2に反映します。Ansibleのコードを書く --> `cap staging deploy` --> 失敗する --> `vagrant destroy node` --> `vagrant up node` --> Ansibleのコードを書くという流れて徐々に正しい構成を作り上げていきました。

以下、完成したコードです。

```ansible_data/api.yml
---
- name: Install ruby and nginx
  hosts: vagrant
  sudo: yes

  roles:
    - common
    - nginx
    - ruby
```

```ansible_data/hosts
[vagrant]
192.168.33.12 ansible_ssh_user=vagrant ansible_ssh_private_key_file=~/.ssh/id_rsa

[aws]
54.xxx.xxx.xxx ansible_ssh_user=ec2-user ansible_ssh_private_key_file=~/.ssh/aws.pem
```

```ansible_data/group_vars/all
# These are the rbenv settings
ruby_version: 2.1.3
rbenv_root: /home/{{ login_user }}/.rbenv

# This is used for the nginx server configuration
server_hostname: my_app.domain.com

# Disable All Updates
auto_up_disable: false

#Define Core Update Level
core_update_level: true
```

```ansible_data/group_vars/aws
login_user: ec2-user
```

```ansible_data/group_vars/vagrant
login_user: vagrant
```

```ansible_data/roles/common/files/iptables-save
# {{ ansible_managed }}
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [37:13960]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
```

publickey hogehoge

### SSH鍵の生成
今回はGithubのPrivate RepositoryからソースをクローンするためにSSH鍵が必要になります。ローカルで使っている鍵をコピしてもいいのですが、開発用と運用用は分けたいので`ansible_data`ディレクトリに作成します。

```bash
$ ssh-keygen -t rsa -C "foobar@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/tetsuya/.ssh/id_rsa): /Users/tetsuya/Development/ansible/ansible_data/id_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/tetsuya/Development/ansible/ansible_data/id_rsa.
Your public key has been saved in /Users/tetsuya/Development/ansible/ansible_data/id_rsa.pub.
The key fingerprint is:
bb:90:89:89:23:d5:91:d0:ea:81:79:02:c8:b7:4f:85 foobar@example.com
The key's randomart image is:
+--[ RSA 2048]----+
|o ..  .          |
|o. o.E .         |
|.o..+ .          |
|+ +o o           |
| +..+   S        |
| ... + o .       |
|. o o + .        |
| . .   . .       |
|        .        |
+-----------------+
```

公開鍵はgithubに登録します。

```ansible_data/roles/common/handlers/main.yml
---
- name: restart iptables
  service: name=iptables state=restarted
```

```ansible_data/roles/common/tasks/main.yml
---
- name: Set up iptables rules
  copy: src=iptables-save dest=/etc/sysconfig/iptables
  notify: restart iptables

- name: Change localtime to JST
  copy: src=/usr/share/zoneinfo/Japan dest=/etc/localtime

- name: Add the EPEL software repository
  yum: name=http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm state=present

- name: Install build depends
  yum: name={{ item }} state=latest
  with_items:
    - gcc
    - gcc-c++
    - git
    - make
    - tar
    - vim

- name: Copy ssh key
  sudo: no
  copy: src=id_rsa dest=~/.ssh/id_rsa mode=700

- name: Create /var/www directory
  file: path=/var/www state=directory owner={{ login_user }} group={{ login_user }}
```

```/ansible_data/roles/nginx/handlers/main.yml
---
- name: restart nginx
  service: name=nginx state=restarted
```

```ansible_data/roles/nginx/tasks/main.yml
---
# copied from https://github.com/ansible/ansible-examples/blob/master/wordpress-nginx/roles/nginx/tasks/main.yml
- name: Install nginx
  yum: name=nginx state=present


- name: Copy nginx configuration
  template: src=default.conf dest=/etc/nginx/conf.d/default.conf
  notify: restart nginx
```

```ansible_data/roles/nginx/templates/default.conf
# copied from https://www.digitalocean.com/community/tutorials/how-to-deploy-rails-apps-using-unicorn-and-nginx-on-centos-6-5
upstream app {
    server unix:/tmp/unicorn.my_app.sock fail_timeout=0;
}

server {


    listen 80;
    server_name localhost;

    # Application root, as defined previously
    root /var/www/my_app/current/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}
```

```ansible_data/roles/ruby/files/rbenv.sh
export PATH="~/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

```ansible_data/roles/ruby/tasks/main.yml
---
- name: install build depends
  yum: name={{ item }} state=latest
  with_items:
    - openssl-devel
    - readline-devel
    - ruby-devel
    - zlib-devel
    - mysql-devel

- name: clone rbenv repo
  sudo: no
  git: repo=https://github.com/sstephenson/rbenv.git dest={{ rbenv_root }}

- name: add rbenv initialization to profile
  copy: src=rbenv.sh dest=/etc/profile.d/rbenv.sh owner=root group=root mode=0755

- name: check ruby-build installed
  command: test -x /usr/local/bin/ruby-build
  register: rbuild_present
  ignore_errors: yes

- name: clone ruby-build repo
  sudo: no
  git: repo=https://github.com/sstephenson/ruby-build.git dest={{ rbenv_root }}/plugins/ruby-build
  when: rbuild_present|failed

- name: install ruby-build
  command: ./install.sh chdir={{ rbenv_root }}/plugins/ruby-build
  when: rbuild_present|failed

- name: check ruby installed
  sudo: no
  shell: rbenv versions | grep {{ ruby_version }}
  register: ruby_installed
  ignore_errors: yes

- name: install ruby
  sudo: no
  shell: rbenv install {{ ruby_version }}
  when: ruby_installed|failed

- name: set global ruby
  sudo: no
  shell: rbenv global {{ ruby_version }}
  when: ruby_installed|failed

- name: rehash
  sudo: no
  shell: rbenv rehash
  when: ruby_installed|failed

- name: install bundler
  command: gem install bundler
  sudo: no
```

## 実行結果
```
[vagrant@localhost ansible_data]$ ansible-playbook -i hosts api.yml

PLAY [Install ruby and nginx] ************************************************* 

GATHERING FACTS *************************************************************** 
ok: [192.168.33.12]

TASK: [common | Set up iptables rules] **************************************** 
changed: [192.168.33.12]

TASK: [common | Change localtime to JST] ************************************** 
changed: [192.168.33.12]

TASK: [common | Add the EPEL software repository] ***************************** 
changed: [192.168.33.12]

TASK: [common | Install build depends] **************************************** 
changed: [192.168.33.12] => (item=gcc,gcc-c++,git,make,tar,vim)

TASK: [common | Copy ssh key] ************************************************* 
changed: [192.168.33.12]

TASK: [common | Create /var/www directory] ************************************ 
changed: [192.168.33.12]

TASK: [nginx | Install nginx] ************************************************* 
changed: [192.168.33.12]

TASK: [nginx | Copy nginx configuration] ************************************** 
changed: [192.168.33.12]

TASK: [ruby | install build depends] ****************************************** 
changed: [192.168.33.12] => (item=openssl-devel,readline-devel,ruby-devel,zlib-devel,mysql-devel)

TASK: [ruby | clone rbenv repo] *********************************************** 
changed: [192.168.33.12]

TASK: [ruby | add rbenv initialization to profile] **************************** 
changed: [192.168.33.12]

TASK: [ruby | check ruby-build installed] ************************************* 
failed: [192.168.33.12] => {"changed": true, "cmd": ["test", "-x", "/usr/local/bin/ruby-build"], "delta": "0:00:00.011944", "end": "2014-10-03 15:17:05.416544", "rc": 1, "start": "2014-10-03 15:17:05.404600"}
...ignoring

TASK: [ruby | clone ruby-build repo] ****************************************** 
changed: [192.168.33.12]

TASK: [ruby | install ruby-build] ********************************************* 
changed: [192.168.33.12]

TASK: [ruby | check ruby installed] ******************************************* 
failed: [192.168.33.12] => {"changed": true, "cmd": "rbenv versions | grep 2.1.3", "delta": "0:00:00.040867", "end": "2014-10-03 15:17:41.363395", "rc": 1, "start": "2014-10-03 15:17:41.322528"}
...ignoring

TASK: [ruby | install ruby] *************************************************** 
changed: [192.168.33.12]

TASK: [ruby | set global ruby] ************************************************ 
changed: [192.168.33.12]

TASK: [ruby | rehash] ********************************************************* 
changed: [192.168.33.12]

TASK: [ruby | install bundler] ************************************************ 
changed: [192.168.33.12]

NOTIFIED: [nginx | restart nginx] ********************************************* 
changed: [192.168.33.12]

PLAY RECAP ******************************************************************** 
192.168.33.12              : ok=21   changed=20   unreachable=0    failed=0   
```

これで、Ansibleで環境構築ができました。

### ここまでに参考にしたサイト
+ [Installing ruby/rbenv with Ansible | Maykel Moya's blog](http://mmoya.org/blog/2013/02/22/installing-rubyrbenv-with-ansible/)
+ [Vagrant/AWS + AnsibleでCentOS/Nginx/MySQL/RVM/Ruby2.1.2環境を構築 - 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/vagrant-ansible-rails-rvm-nginx-mysql/)
+ [Ansible script to install rbenv.  Intended for CentOS images.](https://gist.github.com/brendan-skyrkt/7699067)

コメントにも書いていますが、`ansible_data/roles/nginx`配下の設定は[ansible-examples/wordpress-nginx/roles/nginx at master · ansible/ansible-examples](https://github.com/ansible/ansible-examples/tree/master/wordpress-nginx/roles/nginx)をそのまんま利用しています。

また、Ansibleとは関係ないのですが、単純にインフラ構築の資料も多いに役立ちます。今回は下記サイトをかなり参考にし、`ansible_data/roles/nginx/templates/default.conf`もこちらから拝借しています。

+ [How To Deploy Rails Apps Using Unicorn And Nginx on CentOS 6.5 | DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-deploy-rails-apps-using-unicorn-and-nginx-on-centos-6-5)

# Capistrano
それではもう一度、`deploy:check`を走らせてみましょう。

```bash
$ bundle exec cap staging deploy:check
INFO[a5c7cc90] Running /usr/bin/env mkdir -p /tmp/my_app/ on 192.168.33.12
INFO[a5c7cc90] Finished in 0.062 seconds with exit status 0 (successful).
INFOUploading /tmp/my_app/git-ssh.sh 100.0%
INFO[9ecd1ade] Running /usr/bin/env chmod +x /tmp/my_app/git-ssh.sh on 192.168.33.12
INFO[9ecd1ade] Finished in 0.070 seconds with exit status 0 (successful).
INFO[288d219a] Running /usr/bin/env mkdir -pv /var/www/my_app/shared /var/www/my_app/releases on 192.168.33.12
INFO[288d219a] Finished in 0.063 seconds with exit status 0 (successful).
INFO[9bc5cb47] Running /usr/bin/env mkdir -pv /var/www/my_app/shared/bin /var/www/my_app/shared/log /var/www/my_app/shared/tmp/pids /var/www/my_app/shared/tmp/cache /var/www/my_app/shared/tmp/sockets /var/www/my_app/shared/vendor/bundle /var/www/my_app/shared/public/system on 192.168.33.12
INFO[9bc5cb47] Finished in 0.070 seconds with exit status 0 (successful).
```

いい感じです。いよいよデプロイの実行です。

```bash
$ bundle exec cap staging deploy
INFO[acfd3a67] Running /usr/bin/env mkdir -p /tmp/my_app/ on 192.168.33.12
INFO[acfd3a67] Finished in 0.058 seconds with exit status 0 (successful).
INFOUploading /tmp/my_app/git-ssh.sh 100.0%
INFO[5f8a06f2] Running /usr/bin/env chmod +x /tmp/my_app/git-ssh.sh on 192.168.33.12
INFO[5f8a06f2] Finished in 0.057 seconds with exit status 0 (successful).
INFO[8777e82d] Running /usr/bin/env mkdir -pv /var/www/my_app/shared /var/www/my_app/releases on 192.168.33.12
INFO[8777e82d] Finished in 0.061 seconds with exit status 0 (successful).
INFO[e1bc9a43] Running /usr/bin/env mkdir -pv /var/www/my_app/shared/bin /var/www/my_app/shared/log /var/www/my_app/shared/tmp/pids /var/www/my_app/shared/tmp/cache /var/www/my_app/shared/tmp/sockets /var/www/my_app/shared/vendor/bundle /var/www/my_app/shared/public/system on 192.168.33.12
INFO[e1bc9a43] Finished in 0.056 seconds with exit status 0 (successful).
INFOThe repository mirror is at /var/www/my_app/repo
INFO[2218e350] Running /usr/bin/env git remote update on 192.168.33.12
INFO[2218e350] Finished in 7.807 seconds with exit status 0 (successful).
INFO[a84663d6] Running /usr/bin/env mkdir -p /var/www/my_app/releases/20141003083242 on 192.168.33.12
INFO[a84663d6] Finished in 0.057 seconds with exit status 0 (successful).
INFO[2faf7121] Running /usr/bin/env git archive master | tar -x -C /var/www/my_app/releases/20141003083242 on 192.168.33.12
INFO[2faf7121] Finished in 0.062 seconds with exit status 0 (successful).
INFO[05c093ed] Running /usr/bin/env echo "b43abd4" >> REVISION on 192.168.33.12
INFO[05c093ed] Finished in 0.058 seconds with exit status 0 (successful).
INFO[401904dd] Running /usr/bin/env mkdir -pv /var/www/my_app/releases/20141003083242 /var/www/my_app/releases/20141003083242 /var/www/my_app/releases/20141003083242/tmp /var/www/my_app/releases/20141003083242/tmp /var/www/my_app/releases/20141003083242/tmp /var/www/my_app/releases/20141003083242/vendor /var/www/my_app/releases/20141003083242/public on 192.168.33.12
INFO[401904dd] Finished in 0.063 seconds with exit status 0 (successful).
INFO[2b3a7fc7] Running /usr/bin/env rm -rf /var/www/my_app/releases/20141003083242/bin on 192.168.33.12
INFO[2b3a7fc7] Finished in 0.057 seconds with exit status 0 (successful).
INFO[cce80d06] Running /usr/bin/env ln -s /var/www/my_app/shared/bin /var/www/my_app/releases/20141003083242/bin on 192.168.33.12
INFO[cce80d06] Finished in 0.056 seconds with exit status 0 (successful).
INFO[d5c9745c] Running /usr/bin/env ln -s /var/www/my_app/shared/log /var/www/my_app/releases/20141003083242/log on 192.168.33.12
INFO[d5c9745c] Finished in 0.056 seconds with exit status 0 (successful).
INFO[ab9090ad] Running /usr/bin/env ln -s /var/www/my_app/shared/tmp/pids /var/www/my_app/releases/20141003083242/tmp/pids on 192.168.33.12
INFO[ab9090ad] Finished in 0.057 seconds with exit status 0 (successful).
INFO[eaae451d] Running /usr/bin/env ln -s /var/www/my_app/shared/tmp/cache /var/www/my_app/releases/20141003083242/tmp/cache on 192.168.33.12
INFO[eaae451d] Finished in 0.055 seconds with exit status 0 (successful).
INFO[23cb70ed] Running /usr/bin/env ln -s /var/www/my_app/shared/tmp/sockets /var/www/my_app/releases/20141003083242/tmp/sockets on 192.168.33.12
INFO[23cb70ed] Finished in 0.056 seconds with exit status 0 (successful).
INFO[ab9ca208] Running /usr/bin/env ln -s /var/www/my_app/shared/vendor/bundle /var/www/my_app/releases/20141003083242/vendor/bundle on 192.168.33.12
INFO[ab9ca208] Finished in 0.061 seconds with exit status 0 (successful).
INFO[6ad3ebad] Running /usr/bin/env ln -s /var/www/my_app/shared/public/system /var/www/my_app/releases/20141003083242/public/system on 192.168.33.12
INFO[6ad3ebad] Finished in 0.055 seconds with exit status 0 (successful).
INFO[0636c0d0] Running ~/.rbenv/bin/rbenv exec bundle install --binstubs /var/www/my_app/shared/bin --path /var/www/my_app/shared/bundle --without development test --quiet on 192.168.33.12
INFO[0636c0d0] Finished in 14.448 seconds with exit status 0 (successful).
Recorded deployment to 'U-NOTE API (Staging)' (2014-10-10 17:33:10 +0900)
INFOUploaded deployment information to New Relic
INFO[906dabfb] Running /usr/bin/env rm -rf /var/www/my_app/current on 192.168.33.12
INFO[906dabfb] Finished in 0.060 seconds with exit status 0 (successful).
INFO[a0db6cec] Running /usr/bin/env ln -s /var/www/my_app/releases/20141003083242 /var/www/my_app/current on 192.168.33.12
INFO[a0db6cec] Finished in 0.061 seconds with exit status 0 (successful).
INFOunicorn is running...
INFOunicorn restarting...
INFO[bd8f7266] Running /usr/bin/env kill -s USR2 `cat /var/www/my_app/shared/tmp/pids/unicorn.pid` on 192.168.33.12
INFO[bd8f7266] Finished in 0.061 seconds with exit status 0 (successful).
INFO[cbaaf62d] Running /usr/bin/env echo "Branch master (at b43abd4) deployed as release 20141003083242 by tetsuya" >> /var/www/my_app/revisions.log on 192.168.33.12
INFO[cbaaf62d] Finished in 0.077 seconds with exit status 0 (successful).
```

最後に[http://192.168.33.12/](http://192.168.33.12/)にアクセスし、アプリが動いていることを確認します。問題がなさそうであれば、`ansible_data/api.yml`のhostsを`vagrant`から`all`に変更しEC2の環境を作りましょう。

# 最後に
コードの量が多い分長めの記事になってしまいましたが、少しでも誰かのお役に立てばと思います。ちなみに、ボクはAnsibleで構築構築からCapistrano使ってデプロイできるようにするまでに4-5日かかりました。特にCapistranoは癖もので途中で何度かやめようと思いました。次はそこら辺のハマりどころを公開できればと思います。