[初心者向け] Ansible を体験してみよう

いきなりですが「Ansible」普段から使用していますか?
「infrastructure as Code」が当たり前になってきている世の中、インフラエンジニアの方は勿論アプリケーションエンジニアの方も知っておいて損はない技術です。

Ansibleとは、Red Hat社が開発するオープンソースの構成管理ツールです。
ソフトウェアのインストール、コマンド実行などのタスクをコード化し、自動化することが可能です。
詳細は「Ansibleとは」などでググってみてください。

本記事ではAnsibleを使用したことがない方に向けて1から手順を説明し、実際に実行するまでのデモを行います。
目標は以下の通りです。

* ローカルPC上に仮想マシン(Ubuntu18.04)を2台立ち上げ、1台のマシンからもう1台の仮想マシンに対してnode.jsの自動インストールを行う

イメージはこんな感じです。

![alt](http://www.plantuml.com/plantuml/png/PO-z3e9048JxVOeDrhu0XK4jR3GML9RhCO5BbYEvEz24yEx2SPrJpMRdsvygHF5nx9KyJ1JNAlWXvbcp1Ex5yE5ksow-e3fyPk9LRcZ0nTa5-rRKy1DyiQL3iXcuUS2bV58oopz-LGiN4swIpVX5HyoKgOLek-HuoYjAdgnm21tjzTh9TCdumemHBFjygk2QzRiV)

早速やっていきましょう!

## 前提条件

前提条件は以下を想定しております。

* ローカルPCはMacOSであること

Windowsの方でも本手順は行えますが、vagrant 周りでエラーが発生する可能性があるかもしれません。
その際は GUI画面からVirtualBoxアプリを開き、仮想環境を2台手動で立ち上げるなどの方法でも問題ありません。

## VirtualBox + Vagrant をMacにインストールする

本環境を作成するにあたり必要なソフトウェアのインストールを行います。

* VirtualBox
* vagrant

VirtualBoxは仮想マシンを作成するために必要なもので、vagrant はVirtualBoxをコードレベルで操作するものと覚えて頂いて問題ありません。

インストール方法ですが、以下の記事が大変わかりやすいです。

https://qiita.com/inouet/items/b36638adc2b5772db457

「2. VirtualBox を公式サイトからインストール」まで実行してください。

## 環境の立ち上げとAnsibleのインストール

インストールが完了したら仮想マシンの立ち上げから行います。

Vagrantfileを作成し、中を全削除後以下のように書き換えてください

```
$ vagrant init
$ ls
Vagrantfile
$ vim Vagrantfile

Vagrant.configure(2) do |config|
 config.vm.define "AnsibleServer" do |node|
    node.vm.box = "bento/ubuntu-18.04"
    node.vm.hostname = "AnsibleServer"
    node.vm.network :private_network, ip:"192.168.7.7"
    node.vm.provider "virtualbox" do |vb|
      vb.customize ["modifyvm", :id, "--memory", "1024"]
    end
    node.vm.provider "virtualbox" do |vb|
      vb.gui = false
    end
  end
 config.vm.define "AnsibleClient" do |node|
    node.vm.box = "bento/ubuntu-18.04"
    node.vm.hostname = "AnsibleClient"
    node.vm.network :private_network, ip:"192.168.8.8"
    node.vm.provider "virtualbox" do |vb|
      vb.customize ["modifyvm", :id, "--memory", "1024"]
    end
    node.vm.provider "virtualbox" do |vb|
      vb.gui = false
    end
  end  
end
```

ファイルの作成完了後、Vagrantfileがあるディレクトリで以下コマンドを実行します。
実行完了後、2台の仮想マシンが立ち上がっています。

```
$ vagrant up
```
無事作成が完了したら、1度Server側となる仮想マシンにログインしてみましょう。

```
$ vagrant ssh AnsibleServer
vagrant@AnsibleServer:~$ 
```

無事ログインできましたね!
早速Server側にAnsibleのインストールを行いましょう。

```
vagrant@AnsibleServer:~$ sudo apt update
vagrant@AnsibleServer:~$ sudo apt install software-properties-common
vagrant@AnsibleServer:~$ sudo apt-add-repository ppa:ansible/ansible
vagrant@AnsibleServer:~$ sudo apt update
vagrant@AnsibleServer:~$ sudo apt install ansible
vagrant@AnsibleServer:~$ ansible --version
ansible 2.8.5
```

version 2.8.5 のansibleインストールが完了です!

## Ansibleのコード作成

次に、Ansilbeのコードを確認します。
Server側の仮想マシンにログインしたまま以下の手順を実行してください。
今回のデモで使用するAnsibleのディレクトリ構造は以下のようになります。

```
.
├── ansible.cfg
├── hosts
├── playbook.yml
└── roles
    └── node
        └── tasks
            └── main.yml
```

* ansible.cfg
    * 設定ファイルのようなもの。Clientへの初回接続SSHエラーが出ないように設定している
* hosts
    * 接続先を定義します
* playbook.yml
    * 実行するRoleを定義します。
* roles
    * Roleの定義を行います。

まずは上記のディレクトリ構成を実現するため、Homeディレクトリでファイルとディレクトリの作成から行います。

```
vagrant@AnsibleServer:~$ touch hosts playbook.yml ansible.cfg
vagrant@AnsibleServer:~$ mkdir -p roles/node/tasks/
vagrant@AnsibleServer:~$ touch roles/node/tasks/main.yml
```

各ファイルの中身を以下のように編集してください。

```
vagrant@AnsibleServer:~$ vim hosts

[AnsibleClient]
192.168.8.8

vagrant@AnsibleServer:~$ vim playbook.yml

---
- hosts: AnsibleClient
  become: no
  roles:
    - {role: 'node', tags: ’node’}

vagrant@AnsibleServer:~$ vim ansible.cfg

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null

vagrant@AnsibleServer:~$ vim roles/node/tasks/main.yml

- name: remove node.js
  become: yes
  apt:
    name: node.js
    state: absent
    purge: yes

- name: add repository of node.js
  become: yes
  shell: curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -

- name: apt-get update
  become: yes
  apt:
    update_cache: yes

- name: install latest node.js
  become: yes
  apt:
    name: nodejs
```

以上で準備完了です。
あと一息です!!

## Ansibleの実行

いよいよAnsibleの実行です。

いきなり実行する前にClientの状態を確認しておきましょう。
今回の目標はClientにNode.jsをインストールすることだったので、事前に入っていないか確認します。
(ServerとClientを行き来するのでiTerm2を使用している方は2画面でやると良いです。)

```
vagrant@AnsibleServer:~$ exit
$ vagrant ssh AnsibleClient
vagrant@AnsibleClient:~$ node -v
-bash: node: command not found
```

入っていないことが確認できました!

ではもう一度Server側にログインします。

```
vagrant@AnsibleClient:~$ exit
$ vagrant ssh AnsibleServer
vagrant@AnsibleServer:~$
```

確認が取れたので改めてAnsibleの実行を行います。
以下コマンドをサーバ側で実行してください。
パスワードを求められるので、 `vagrant` と入力してください。

```
vagrant@AnsibleServer:~$ ansible-playbook -i hosts playbook.yml -u vagrant -k
SSH password:

PLAY [AnsibleClient] *************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
ok: [192.168.8.8]
.
.
192.168.8.8                : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

Ansibleの実行は完了しましたでしょうか?
無事成功すると、ok=5とレスポンスがあると思います。
ではClietにログインし、Node.jsがインストールされているか確認してみましょう。

```
vagrant@AnsibleServer:~$ exit
$ vagrant ssh AnsibleClient
vagrant@AnsibleClient:~$ node -v
v10.16.3
```

無事インストールされていまね!
今回はNode.jsのみのインストールでしたが、他にも自分の使いたいものや実行したいものをタスク化しておけばコマンド1回叩くだけで自動で行ってくれます。

## おわりに

最後までみて頂きありがとうございます。
長い道のりでしたが、Ansibleのことについて少しでも理解して頂けたでしょうか。
今回はテストを手動で行いましたが、
業務で使用されるのであれば自動テストツールである`ServerSpec`も同時に学習すると良いと思います。
Ansibleを活用し、皆さんの作業が少しでも楽になれば幸いです!

ServerSpecについて簡単にまとめました
https://qiita.com/Hiro-AGU/items/ac7f4336e266a2208288