Ansibleで行うVagrantの開発環境構築

/

Ansible

Ansibleはプロビジョニングツールと呼ばれる、サーバーの構成管理を行うツールの一種です。

Ansibleはサーバーの設定や管理をあらかじめ準備した設定ファイル元に実行するので、ファイルを使いまわす事でサーバーの構築から運用を効率的に行うことが可能になります。Ansible自体はPythonで作られていますが設定ファイルはYAMLで記述されるのでPythonの知識自体はあまり必要ありません。

Ansibleは本来は実際に稼働しているサーバーを設定するためのツールですが、Vagrantにも対応しているので今回はローカルの開発環境を設定するために利用します。

Ansibleを選んだ理由

Ansibleは他のプロビジョニングツールのChefなどと比較するとシンプルな作りで、サーバー側にソフトウェア(エージェント)のインストールが不要だという特徴があります。
シンプルな設計のため細かな設定は苦手ですが手軽だという点でローカル開発環境のセットアップに向いていますし、小さなWEBサービス用の開発環境を作ろうと思ったので後々本番でも使う事を考えてAnsibleを選択してみました。

実行環境

ホストOS ubuntu16.04LTS
ゲストOS centOS7.2
Vagrant 1.8.1
VirtualBox 5.0.24
Ansible 2.0.1.0

ディレクトリの構成

├─ .vagrant
├─ Vagrantfile
└─ provisioning
   ├─ hosts
   ├─ site.yml
   └─ tasks
      ├─ httpd.yml
      └─ hello.yml

インストール

Ansibleを使うにはバージョンが2.4以上のPythonとpipが、仮想環境を実行するにはVirtualBoxとVagrantが必要です。
それぞれのインストールの方法は以前別の記事に書いたので今回は割愛します。
Vagrant(&VirtualBox)で作る仮想開発環境 – Kolatt
Pythonを使ってみる – Kolatt
pipによるPythonのパッケージ管理 – Kolatt

Ansible

Ansibleのインストールはpipを利用して実行します。

$ pip install ansible

$ ansible --version
ansible 2.0.1.0

Vagrantfile

AnsibleをVagrantで実行するためにVagrantfileの設定をします。

Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.2"
  config.vm.network "private_network", ip: "192.168.33.10"
  
  config.vm.provider "virtualbox" do |vb|
     vb.memory = "1024"
  end

  #vagrant-hostsupdater
  config.vm.hostname = "ansilble.dev"

  #Ansible
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "provisioning/site.yml"
    ansible.inventory_path = "provisioning/hosts"
    ansible.limit= "all"
  end
end

BoxはchefのbentoのCentOS7のものを使いました。Ansibleを試すにchefのBoxを使うというのもあれですが…。

config.vm.hostnameではVagrantのプラグインのvagrant-hostsupdaterを利用しています。hostsupdaterを使うとVagrantを立ち上げた時に自動的にホストマシンのhostsにゲストのドメイン名を登録してくれます。ゲストマシンに設定したドメインでアクセス出来るので便利ですが、IPアドレスからでも接続出来るので必要なければこの設定は省略しても問題ありません。

config.vm.provisionからがAnsibleのためのの設定になります。
このあと見ていきますがansible.playbookで読み込むプレイブック(設定のテンプレート)を、ansible.inventory_pathでインベントリファイル(サーバーのリスト)のPathの設定をしています。またanslibe.limitでAnsibleを実行する仮想マシンとインベントリファイルに記述されたマシンを結びつけています。

Vagrantfileの設定が済んだらVagrantを起動しておきます。

$ vagrant up

Inventory

Ansibleでは接続するサーバーのリストをインベントリと呼ばれるファイルに登録して処理を実行します。
インベントリはデフォルトでは /etc/ansible/hosts を利用しますが、今回はローカル環境のためのプロジェクト内のディレクトリにprovisioning/hostsを作って以下のように設定しました。

[vagrants]
192.168.33.10

PlayBook

Ansibleではサーバーに実行させたい処理を書いたYAMLファイルをプレイブックと呼んで管理しています。

#Apacheのインストール
- hosts: vagrants
  become: yes
  become_user: vagrant

  tasks:
    - name: install the latest version of Apache
      yum: name=httpd state=latest
    - name: start httpd.service
      service: name=httpd state=started
      service: name=httpd enabled=yes

このプレイブックでは処理を実行するホストとユーザーを指定し、CentOSのyumを使ってWebサーバーのApacheのインストールとサービスの自動起動の設定を行っています。

またVagrantで実行するプレイブックはsite.ymlを読み込むように設定していますが、新しい処理をを追加するたびにsite.ymlに直接タスクを書き足していったりVagrantfileにプレイブックのパスを追記していくのは管理が煩雑になるので、サーバーに実行させたいそれぞれのタスクはsite.ymlには直接書かずにtasks/以下に別々のプレイブックとして置き、site.ymlからインクルードして実行するように設定します。

- include: tasks/httpd.yml

Ansibleの準備が出来たのでVagrantでプロビジョニングを実行します。

$ vagrant provision

...
PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.33.10]

TASK [install the latest version of Apache] ************************************
changed: [192.168.33.10]

TASK [service] *****************************************************************
changed: [192.168.33.10]

TASK [service] *****************************************************************
changed: [192.168.33.10]

PLAY RECAP *********************************************************************
192.168.33.10              : ok=4    changed=3    unreachable=0    failed=0  

処理が実行されたのでvagrantに接続して設定を確かめてみます。

$ vagrant ssh

//Apacheのserviceの確認
$ systemctl status httpd.service
...
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) 
...

Apacheの状態がアクティブになっている事が確認出来ます。

Ansibleのプレイブックではパッケージのインストールや起動以外の処理も行う事が出来ます。

- hosts: vagrants
  become: yes
  become_user: vagrant

  tasks:
    - name: create file
      file: path=/vagrant/text.txt state=touch owner=vagrant group=vagrant
    - name: hello world!!
      shell: echo "Hello Wordld!!" >> /vagrant/text.txt

このプレイブックではファイルの作成とshellスクリプトを実行しています。
hello.ymlもsite.ymlに追加して再びプロビジョニングを実行します。

- include: tasks/httpd.yml
- include: tasks/hello.yml
$ vagrant provision
PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.33.10]

TASK [install the latest version of Apache] ************************************
ok: [192.168.33.10]

TASK [service] *****************************************************************
ok: [192.168.33.10]

TASK [service] *****************************************************************
ok: [192.168.33.10]

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.33.10]

TASK [create file] *************************************************************
changed: [192.168.33.10]

TASK [hello world!!] ***********************************************************
changed: [192.168.33.10]

PLAY RECAP *********************************************************************
192.168.33.10              : ok=7    changed=2    unreachable=0    failed=0  


$ vagrant ssh
$ vi /vagrant/text.txt
Hello World!!

この他にもAnsibleでは色々な処理をサーバーに実行させる事が可能です。

実行させたい処理を記述したプレイブックをAnsibleのサイトのドキュメントなどを参考に作成し、対象のサーバーに実行させるプレイブックとして追加していく事でサーバーの構築・運用を行うのがAnsibleの基本的な使い方になります。
Ansibleのサイトにあるドキュメントは英語ですが、普段手動で行っている処理を書き変えていく形になるので英語が苦手でも比較的予想がつきやすいですし、Githubなどで公開されている他人のプレイブックなども自分でプレイブックを書くときの参考になると思います。

あとがき

Ansibleは期待通り少ない手数で動いてくれました。以前Chefも試してみましたが小規模な環境ではやはりAnsibleのほうが向いているように思います。
Vagrantの設定も簡単ですし仮想環境はしばらく使っていないと中がどんな設定だったか忘れてしまう事も多いため、スクリプトとドキュメントが一緒になったプレイブックでサーバーの状態を把握しやすくなった事で以前より管理が楽になりました。