MacからAnsible使ってVagrantにAnsibleを入れるまでの手順 ※Serverspec追記

# 目標
MacのAnsibleからVagrantで作ったサーバにAnsibleを構築。
AnsibleでAnsible構築。実行先のOSは`CentOS7`
「Ansibleが実行できるサーバ欲しいけど、それ自体Ansibleでやりたいよね」ということで。

# インストール
- Ansible
    - [公式Link](http://docs.ansible.com/ansible/latest/intro_installation.html#latest-releases-on-mac-osx)
- VirtualBox
    - https://www.virtualbox.org/wiki/Downloads
- Vagrant
    - https://www.vagrantup.com/downloads.html

# まずはAnsibleをMacにインストール

https://docs.ansible.com/ansible/latest/intro_installation.html#latest-releases-via-pip
Macはpipからインストールするらしい。

```bash:コンソール
[~ $] sudo easy_install pip
[~ $] sudo pip install ansible
```

「ccコマンドインストールするならXCode入れてね」って言われたけどインストールしなくてもちゃんと終わった。*※キャプチャ忘れ*

```bash:コンソール
[~ $] ansible --version
ansible 2.4.2.0
  config file = None
  configured module search path = [u'/Users/user_name/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Library/Python/2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.10 (default, Feb  7 2017, 00:08:15) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
```
# VirtualBoxをインストール
https://www.virtualbox.org/wiki/Downloads
`OS X hosts`をDLしてマウントしてインストール実行。特記事項なし。

# Vagrantをインストール
https://www.vagrantup.com/downloads.html
`Mac OS X 64-bit` からDLしてマウントしてインストール。特記事項なし。 

### Rollbackできるようにプラグインを入れておく
DLに数分かかります。（約2,3分)

```bash:コンソール
[~ $] vagrant plugin install sahara
Installing the 'sahara' plugin. This can take a few minutes...
Fetching: vagrant-share-1.1.9.gem (100%)
Fetching: open4-1.3.4.gem (100%)
Fetching: Platform-0.4.0.gem (100%)
Fetching: popen4-0.1.2.gem (100%)
Fetching: sahara-0.0.17.gem (100%)
Installed the plugin 'sahara (0.0.17)'!
```

# 共通で使う秘密鍵を作る

今回はパスワード設定をしてない。（設定した時にAnsibleで失敗した時わかりにくいと思って）
*後で指定したバージョンも確認しておきたい。*
> playbook実行時に`-k`とか`-K`つければ行けそう。

```bash:コンソール
[~ $]  ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/user_name/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/user_name/.ssh/id_ed25519.
Your public key has been saved in /Users/user_name/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:oYa5quPQU4qsUIohvs1uIPhdcIiSgY7p7tuLDcR8LSM user_name@host_name.local
The key's randomart image is:
+--[ED25519 256]--+
|.                |
|o                |
|o+ . .  .        |
|B.. +o.. .       |
|=E.+++o S        |
|OOoooo.          |
|O==...           |
|=.X+.            |
|=O=B.            |
+----[SHA256]-----+
```

# VagrantでCentOS7を立ち上げる
今時オフィシャルイメージはこっちから探す
https://app.vagrantup.com/boxes/search
*※`prompt`はサーバ愛称*

```bash:コンソール
[~ $] mkdir -p ~/vm/prompt && cd ~/vm/prompt
[prompt $] vagrant init centos/7
```

カレントディレクトリに`Vagrantfile`が作成される。
以下、作った公開鍵の設定とかを適応。

```ruby:Vagrantfile
...
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  # IPを固定
  config.vm.network "private_network", ip: "192.168.33.10"
  # デフォルトのマウント止める
  config.vm.synced_folder ".", "/vagrant", disabled: true

  config.vm.provider "virtualbox" do |vb|
    # VirtualBoxのVM名を定義
    vb.name = "vagrant-prompt-server"
    # メモリ1GiB
    vb.memory = "1024"
  end
  # 作った公開鍵を追記
  config.vm.provision "file", source: "~/.ssh/id_ed25519.pub", destination: "/tmp/id_ed25519.pub"
  config.vm.provision "shell", inline: <<-SHELL
    cat /tmp/id_ed25519.pub >>  /home/vagrant/.ssh/authorized_keys && rm -f /tmp/id_ed25519.pub
  SHELL
end

```
んで起動。

```bash:コンソール
[prompt $] vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'centos/7' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'centos/7'
    default: URL: https://vagrantcloud.com/centos/7
==> default: Adding box 'centos/7' (v1710.01) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/centos/boxes/7/versions/1710.01/providers/virtualbox.box
    default: Progress: 26% (Rate: 257k/s, Estimated time remaining: 0:15:45)
```
ImageのDLが結構時間かかります。（20分程度）
<details><summary>... 時間経過後 ...</summary><div>

```bash:コンソール
==> default: Successfully added box 'centos/7' (v1710.01) for 'virtualbox'!
==> default: Importing base box 'centos/7'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'centos/7' is up to date...
==> default: Setting the name of the VM: foundation_default_1513679402917_57773
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: 
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: 
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: No guest additions were detected on the base box for this VM! Guest
    default: additions are required for forwarded ports, shared folders, host only
    default: networking, and more. If SSH fails on this machine, please install
    default: the guest additions and repackage the box to continue.
    default: 
    default: This is not an error message; everything may continue to work properly,
    default: in which case you may ignore this message.
==> default: Configuring and enabling network interfaces...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key 
```
</div></details>

プラグインで入れておいたsandboxモードを実行

```bash:コンソール
[foundation $] vagrant sandbox on
[default] Starting sandbox mode...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
```
これでいつでもリセットできる。

# Playbookを作る

baseファイル作成。

```bash:コンソール
[~ $] mkdir -p ~/ansible/playbook && cd ~/ansible/playbook
[playbook $] mkdir group_vars host_vars inventory requirements
[playbook $] touch prompt-server.yml ¥
group_vars/prompt-server ¥
group_vars/iaas-dev group_vars/all.yml ¥
inventory/iaas-dev_hosts ¥
requirements/iaas-dev_prompt-server.yml
```

`requirements/iaas-dev_prompt-server.yml`
これにroleのリポジトリが書いてある想定だけど、localだけで完結させるので
roleディレクトリを作って、そのままリンクを張る。

```bash:コンソール
[~ $] mkdir -p ~/ansible/roles && cd ~/ansible/playbook
[playbook $] ln -s ../roles ./
```

<details><summary>*※roleをinstallするときはこちら*</summary><div>

```bash:コンソール
[playbook $] ansible-galaxy install -p ./roles ¥
-r requirements/iaas-dev_prompt-server.yml
```
</div></details>

# アクセスするhostを設定

```yaml:./inventory/iaas-dev_hosts
# 基盤サーバ
[prompt]
192.168.33.10
```

# 各サーバの実行プランを明記
```yaml:./prompt-server.yml
# 全サーバに適応
- hosts: all
  become: yes
  roles:
    - role-yum-update

# 基盤サーバ
- hosts: prompt
  become: yes
  roles:
    - role-ansible
```

# Roleの作成

```bash:コンソール
[~ $] cd ~/ansible/roles
[roles $] ansible-galaxy init --offline role-yum-update
[roles $] ansible-galaxy init --offline role-ansible
```

```yaml:./roles/role-yum-update/tasks/main.yml
---
# tasks file for roles/role-yum-update
- name: Run yum update.
  yum:
    name: '*'
    state: latest
  tags:
    - update
```


```yaml:./roles/role-ansible/tasks/main.yml
---
# tasks file for role-ansible
- name: install ansible
  yum:
    name: "{{ item }}"
    state: latest
  with_items:
    - epel-release
    - ansible
  tags:
    - prompt
    - ansible
```

# Playbookの実行

```bash:コンソール
[playbook $] ansible-playbook prompt-server.yml -i inventory/iaas-dev_hosts ¥
--user vagrant --private-key=~/.ssh/id_ed25519 -vv
```

＃　Serverspecのインストール

```bash:コンソール
[~ $] sudo gem install serverspec
```
<details><summary>*※インストール過程*</summary><div>

```bash:コンソール
Fetching: rspec-support-3.7.1.gem (100%)
Successfully installed rspec-support-3.7.1
Fetching: rspec-core-3.7.1.gem (100%)
Successfully installed rspec-core-3.7.1
Fetching: diff-lcs-1.3.gem (100%)
Successfully installed diff-lcs-1.3
Fetching: rspec-expectations-3.7.0.gem (100%)
Successfully installed rspec-expectations-3.7.0
Fetching: rspec-mocks-3.7.0.gem (100%)
Successfully installed rspec-mocks-3.7.0
Fetching: rspec-3.7.0.gem (100%)
Successfully installed rspec-3.7.0
Fetching: rspec-its-1.2.0.gem (100%)
Successfully installed rspec-its-1.2.0
Fetching: multi_json-1.13.1.gem (100%)
Successfully installed multi_json-1.13.1
Fetching: net-ssh-4.2.0.gem (100%)
Successfully installed net-ssh-4.2.0
Fetching: net-scp-1.2.1.gem (100%)
Successfully installed net-scp-1.2.1
Fetching: net-telnet-0.1.1.gem (100%)
Successfully installed net-telnet-0.1.1
Fetching: sfl-2.3.gem (100%)
Successfully installed sfl-2.3
Fetching: specinfra-2.73.2.gem (100%)
Successfully installed specinfra-2.73.2
Fetching: serverspec-2.41.3.gem (100%)
Successfully installed serverspec-2.41.3
Parsing documentation for rspec-support-3.7.1
Installing ri documentation for rspec-support-3.7.1
Parsing documentation for rspec-core-3.7.1
Installing ri documentation for rspec-core-3.7.1
Parsing documentation for diff-lcs-1.3
Couldn't find file to include 'Contributing.rdoc' from README.rdoc
Couldn't find file to include 'License.rdoc' from README.rdoc
Installing ri documentation for diff-lcs-1.3
Parsing documentation for rspec-expectations-3.7.0
Installing ri documentation for rspec-expectations-3.7.0
Parsing documentation for rspec-mocks-3.7.0
Installing ri documentation for rspec-mocks-3.7.0
Parsing documentation for rspec-3.7.0
Installing ri documentation for rspec-3.7.0
Parsing documentation for rspec-its-1.2.0
Installing ri documentation for rspec-its-1.2.0
Parsing documentation for multi_json-1.13.1
Installing ri documentation for multi_json-1.13.1
Parsing documentation for net-ssh-4.2.0
Installing ri documentation for net-ssh-4.2.0
Parsing documentation for net-scp-1.2.1
Installing ri documentation for net-scp-1.2.1
Parsing documentation for net-telnet-0.1.1
Installing ri documentation for net-telnet-0.1.1
Parsing documentation for sfl-2.3
Installing ri documentation for sfl-2.3
Parsing documentation for specinfra-2.73.2
Installing ri documentation for specinfra-2.73.2
Parsing documentation for serverspec-2.41.3
Installing ri documentation for serverspec-2.41.3
14 gems installed
```
</div></details>
# 以上
`yum update`が時間かかるけど全部組み上がった。