VirtualBox+Vagrantを使ってWindows10上に構築した仮想Linux環境にansibleを使ってプロビジョニングを行う一番簡単な方法

# 結論
Windowsのシェルで仮想環境を立ち上げ, 
Bash on Windows上でansibleを実行する

# 検証環境
- Windows10
- vagrant 1.9.4
- virtual-box 5.1.20
- ansible 2.4.0.0

# 作業手順
## Bash on Windowsの準備

### Bash on Windoesのインストール
いきなりで申し訳ないのですが, この作業を行ったのが昔すぎて, ログも記憶も残ってないため, 
詳しい話は書けません.
[こちらの記事](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)などを参考にインストールしてください.

### homeの変更
後の工程でbashとwiindowsシェルが同じディレクトリで作業するので, bash側のhomeを変更しておく.
両方がアクセスできるディレクトリならばどこでもよいのですが, 今回は`c:\User\[user_name]\bow`というディレクトリを作り
そこを今後の作業ディレクトリとします.
windowsのCドライブには`/mnt/c`というパスにマウントされているので, それをもとに`/etc/passwd`の内容を書き換えます

```:/etc/passwd

user-name:x:1000:1000:"",,,:/mnt/c/Users/user-name/bow:/bin/bash

```

Bashを再起動し, bashで作ったファイル等をwindows側でからもアクセスできるこちが確認出来たら
この工程は完了です.

### ansibleのインストール
ansibleはaptコマンドでインストールします
ただ, 標準リポジトリには, 1系(1.6くらい)のバイナリしか用意されていないようなので, 
ansibleの公式リポジトリを追加し, そちらからインストールします.

```:bash-console
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
$ ansible --version
ansible 2.4.0.0
```

最初にインストールしている`software-properties-common`パッケージは, aptのリポジトリ管理コマンドである
`apt-add-repository`を使えるようにするためのものなので, すでに入っているもしくは必要ないならば
インストールする必要はありません.

これで, bash上でansibleが使えるようになりました.

## 仮想Linux環境の準備
### virtualbox+vagrantのインストール
特にいうことはないです.
公式からインストーラを取得して, インストールしてください.

### 仮想環境の立ち上げ
先ほど作成した作業ディレクトリに移動し, 以下のようなVagrantファイルを作成します.

```:VagrantFile
Vagrant.configure("2") do |config|
    config.vm.box = "bento/centos-7.2"

    config.vm.provider :virtualbox do |v|
        v.name = "centos72"
        v.customize ["modifyvm", :id, "--memory", 4096]
    end

    config.vm.network :private_network, ip: "192.168.33.100" 
    config.ssh.forward_agent = true

end
```

使用するboxイメージについては, centosが使いたい以外にこだわりは特にないので, 
bentoプロジェクトのイメージ(Chefの開発メンバーがメンテしてるboxイメージ)を使用しています.


そして, vagrantを使って仮想環境を立ち上げ, sshでログインすることができたら完了.

```:windows-console
> vagrant up
...
> vagrant ssh
[vagrant@localhost ~]$
```

## 疎通テスト
### pingは通るか
まずは, bashのコンソールからpingが通るかのテストしてみます.

```:bash-console
$ ping 192.168.33.100
PING 192.168.33.100 (192.168.33.100) 56(84) bytes of data.
64 bytes from 192.168.33.100: icmp_seq=1 ttl=64 time=0.688 ms
64 bytes from 192.168.33.100: icmp_seq=2 ttl=64 time=1.44 ms
64 bytes from 192.168.33.100: icmp_seq=3 ttl=64 time=1.36 ms
64 bytes from 192.168.33.100: icmp_seq=4 ttl=64 time=1.35 ms
64 bytes from 192.168.33.100: icmp_seq=5 ttl=64 time=1.23 ms
64 bytes from 192.168.33.100: icmp_seq=6 ttl=64 time=1.43 ms
^C
--- 192.168.33.100 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5004ms
rtt min/avg/max/mdev = 0.688/1.254/1.448/0.261 ms
```
pingは問題なく, 通るようです.

### ssh経由でログインできるか
次にsshでのアクセスを試してみます.
vagrantで作成した環境は, 
- ユーザ名:vagrant
- sshキー : `[work_dir]/.vagrant/machines/default/virtualbox/private_key`
という設定でsshログインできるようになっているので, これらを使ってログインしてます.

```:bash-console
~$ ssh vagrant@192.168.33.100 -i .vagrant/machines/default/virtualbox/private_key
The authenticity of host '192.168.33.100 (192.168.33.100)' can't be established.
ECDSA key fingerprint is SHA256:DrnHAeFdOksJ55bMSmPERVhLTW2ft2gWxXloYREdYbY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.33.100' (ECDSA) to the list of known hosts.
Last login: Sat Oct 14 08:44:32 2017 from 10.0.2.2

[vagrant@localhost ~]$
```
無事ログインできることが確認されました.

### ansibleでアクセスできるか
最後に, ansibleからpingを打ってみます.

以下の作業ディレクトリで, 以下の疎通テスト用コマンドを実行してみると...

```:bash-console
$ ansible 192.168.33.100 -m ping -u vagrant --private-key=./.vagrant/machines/default/virtualbox/private_key
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available

 [WARNING]: Could not match supplied host pattern, ignoring: 192.168.33.100

 [WARNING]: No hosts matched, nothing to do
```

ホストが見つからないというエラーが…
調べたところ, 実行ディレクトリに`ansible.cfg`ファイルを作成し, 実行するインベントリファイルを指定してやる必要があるとのことなので, 指示通りファイルを作成します.

ansible.cnfをGithubから公式の[ansible.cfg](https://github.com/ansible/ansible/blob/devel/examples/ansible.cfg)を取得し, 
同ディレクトリのhostsファイルをインベントリファイルとして使用するように編集します.


```:ansible.cfg
#inventory      = /etc/ansible/hosts
inventory      = hosts
```

```:hosts
[web]
192.168.33.100
```

ファイル編集後, 改めてコマンドを実行すると... 

```:bash-console
$ ansible 192.168.33.100 -m ping -u vagrant --private-key=./.vagrant/machines/default/virtualbox/private_key
192.168.33.100 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: bind: Operation not permitted\r\nunix_listener: cannot bind to path: ... ",
    "unreachable": true
}
```

タスクは実行されるが, sshを使った接続に失敗という内容のエラーが発生してしましました.

このエラーの原因はわからないのですが, 

```:ansible.cfg
#ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
ssh_args =
```

と`ansible.cfg`ファイルの`ssh_args`を空に設定すれば良いという情報を信じて試してみると... 


```:bash-console
$ ansible 192.168.33.100 -m ping -u vagrant --private-key=./.vagrant/machines/default/virtualbox/private_key
192.168.33.100 | SUCCESS => {
    "changed": false,
    "failed": false,
    "ping": "pong"
}
```

無事(?)疎通テストに成功しました.


# まとめ
windowsで立ち上げた仮想環境に対して, bash上で動いているansibleからアクセスできることが確認されました.
ここからようやく実際のプロビジョニングの話が始まるわけですが, 今回のところはこれで終わりとします.


# 参考
[Bash on Ubuntu on Windowsをインストールしてみよう！](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)

[Bash on Windowsのホームディレクトリを変更する](http://fanblogs.jp/iorisprogramming/archive/46/0)

[vpsにssh接続してansibleのpingを通すまで](https://qiita.com/NewGyu/items/6a6ba033588514dbca9a)

[Ansible unable to connect to any servers after OpenSSH update](https://github.com/ansible/ansible/issues/9478)