2018/6 Vagrant入門

佐々木誠
大阪

概要

Vagrantは仮想環境の構築を手助けしくれるツールです。 開発はWindowsマシンだけど、本番サーバはLinux。そこでLinux仮想環境でwebアプリ開発環境を整える。というような場合に便利です。

メリット

素直に仮想化ソフトVirtualBoxだけでもLinux仮想環境を作ることはできますが、 チームメンバに同じ環境を構築してもらうためには大きなboxファイルを共有しなくてはいけないのが難点です。 その点Vagrantは仮想環境の構築・設定にフォーカスされているので、以下のような点で楽に構築ができます。

仕組み

VirtualBoxとVagrantは対立するような説明の仕方をしましたが、Vagrantを利用するにはVirtualBoxが必要です。 Vagrant自体は仮想機能を持っていません。 仮想環境を構築しやすいような仕組みをVagrantを提供してくれますが、裏ではVagrantがVirtualBoxを利用して仮想環境を構築しているのです。

Vagrant準備

VirtualBoxインストール

Download VirtualBoxからダウンロードしてインストールしてください。

Vagrantインストール

Download Vagrantからダウンロードしてインストールしてください。

念の為、PCを再起動するとよいでしょう。

> vagrant -v
Vagrant 2.0.1

といった感じで表示されれば成功です。

仮想環境の構築

OSの入手

まずは元となるOSを入手します。 Vagrantbox.esで配布されているのでを選びましょう。 今回はCentOS 7 x64 (Minimal, Shrinked, Guest Additions 4.3.26) (Monthly updates)を利用します。

> vagrant box add sample_box https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box

このように仮想環境名(例:sample_box)と元となるOSのURLを指定すればOKです。

Vagrantfile準備

Vagrantfileは、仮想環境指定やメモリ割り当て・ネットワーク指定といったVirtualBoxで設定できる項目をRubyで記述したファイル(拡張子なし)です。 今回は以下にします。これを任意のフォルダに用意します。(例:my_project/Vagrantfile)

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # VM名
  config.vm.box = "sample_box"

  config.vm.provider "virtualbox" do |vb|
    # 1GBメモリ割当
    vb.memory = "1024"
  end

  # IPアドレス指定
  config.vm.network :private_network, ip: "192.168.33.36"

  # 環境構築
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "ansible.yml"
  end

end

ansible準備

ansibleは構成管理ツールで、ソフトのインストールや環境変数設定などを自動で行ってくれるツールです。 前述のVagrantfileのようにprovisionにansible_local指定することで、 仮想環境起動時に自動で1度だけansible.ymlを実行し環境を整えてくれます。 以下のように記述したansible.ymlを用意すればPostgreSQL環境を構築できます。 ansible.ymlはVagrantfileと同じフォルダに用意します。(例:my_project/ansible.yml)

- name: provisioning
  hosts: all
  become: yes
  user: vagrant
  vars:
    # 基本
    base_locale: LANG=ja_JP.UTF-8
    base_timezone: Asia/Tokyo
    # PostgreSQL
    dbuser: "postgres"
    dbpass: "postgres"
    dbname: "sample"
  
  tasks:
    # 基本 ###################################
    - name: yum update
      yum: 
        name=*
        state=latest

    - name: SELinux無効
      selinux: state=disabled

    - name: locale設定
      command: localectl set-locale {{ base_locale }}
     
    - name: timezone設定
      command: timedatectl set-timezone {{ base_timezone }}

    - name: ntpインストール
      yum: name=ntp state=latest

    - name: ntp設定
      command: ntpdate ntp.nict.jp

    - name: firewalld停止
      command: systemctl stop firewalld
      become_user: root
      become: yes

    - name: firewalld無効
      command: systemctl mask firewalld
      become_user: root
      become: yes

    # PostgreSQL ###################################
    - name: PostgreSQLインストール
      yum: name={{ item }} state=latest
      with_items:
        - postgresql-server
        - postgresql-devel
        - postgresql-contrib
        - python-psycopg2

    - name: PostgreSQL初期化
      shell: service postgresql initdb

    - name: pg_hba.conf Windowsから接続設定
      copy: 
        dest: /var/lib/pgsql/data/pg_hba.conf
        content: "local all all peer\nhost all all 127.0.0.1/32 md5\nhost all all ::1/128 md5\nhost all all all trust"

    - name: postgresql.conf Windowsから接続設定
      lineinfile: dest=/var/lib/pgsql/data/postgresql.conf
        regexp="^#listen_addresses"
        line="listen_addresses = '*'"
        state=present
        backup=yes

    - name: PostgreSQL起動
      service: name=postgresql state=started  enabled=yes

    - name: PostgreSQL sudores設定
      lineinfile: 
        dest: /etc/sudoers.d/postgres 
        owner: root
        group: root
        mode: 0440
        line: "%vagrant ALL=(postgres) NOPASSWD: ALL"
        state: present
        create: yes
        validate: "visudo -cf %s"

    - name: DBユーザ作成
      user: name={{ dbuser }} password={{ dbpass }}

    - name: PostgreSQLユーザ作成
      postgresql_user: 
        name: "{{ dbuser }}"
        password: "{{ dbpass }}"
        state: present
        login_user: postgres
        role_attr_flags: CREATEDB,LOGIN
      become_user: postgres
      become: yes

    - name : 開発用データベース作成
      postgresql_db: 
        name: "{{ dbname }}_development"
        lc_collate: "ja_JP.UTF-8"
        lc_ctype: "ja_JP.UTF-8"
        template: "template0"
        encoding: "UTF-8"
        login_user: postgres
      become_user: postgres
      become: yes

    - name : テスト用データベース作成
      postgresql_db: 
        name: "{{ dbname }}_test"
        lc_collate: "ja_JP.UTF-8"
        lc_ctype: "ja_JP.UTF-8"
        template: "template0"
        encoding: "UTF-8"
        login_user: postgres
      become_user: postgres
      become: yes

    - name : 本番用データベース作成
      postgresql_db: 
        name: "{{ dbname }}_production"
        lc_collate: "ja_JP.UTF-8"
        lc_ctype: "ja_JP.UTF-8"
        template: "template0"
        encoding: "UTF-8"
        login_user: postgres
      become_user: postgres
      become: yes

普通にCentOSでの設定ですね。 各インストールコマンドをメモしてシェルにしたりして配布するのもよいですが、 ansible.ymlは可読性がよいですね。

仮想環境の起動

さて、設定ファイルVagrantfile, ansible.ymlを用意したので準備は整いました。 Vagrantfileのあるフォルダに移動して、vagrant upを実行すれば起動します。 前述のように、初回起動時にはansibleが実行され環境構築が自動で実行されます。

> cd my_project
> vagrant up

これだけで起動します。 Windows側からは、Vagrantfileで指定した192.168.33.36:5432でPostgreSQLにアクセスできます。

終了

仮想環境を終了しないでWindowsを終了すると、仮想環境が壊れてもう一度作り直さないといけなくなります。

> vagrant halt

仮想環境の終了を忘れないようにしましょう。

仮想環境の配布

上記のように、基盤構築担当者が一度準備行います。

チームメンバにVagrantfileansible.ymlを配布し

してもらえば、あっというまに開発環境が整えられます。

最後に

重いboxファイルを共有するよりは、Vagrantfileとainsble.ymlを配布すればいいのでチーム開発における便利さをわかってもらえたと思います。 その上、ただのファイルなのでgitなどでの管理や差分管理も楽なので嬉しい限りです。

備考

こんな記事も読まれています