Virtualbox, Vagrant, AnsibleでLAMP環境を構築

# 仮想環境の構成と要件
## 仮想環境の構成
### ホストOS
* macOS Mojave (10.14.x)

### 構成
* CentOS 7
* PHP 7
* MySQL 5.6
* Apache 2.4

## 要件
* ドキュメントルート配下のファイルを、ホスト（PC）とゲスト（仮想環境）で共有する
* ホストのブラウザで、ゲストに設置したHTMLファイルがウェブページとして見られるところを目指す

# 使うソフトウェア・ツール

* Virtualbox
* Vagrant
* Ansible

# 構築
## 必要なソフトウェアをインストール
### Virtualbox
公式サイトから最新版をダウンロードして、インストール。
(この記事の時点では 5.2.18)

Oracle VM VirtualBox
https://www.virtualbox.org/

### Vagrant
公式サイトから最新版をダウンロードして、インストール。
(この記事の時点では 2.1.2)

Vagrant by HashiCorp
https://www.vagrantup.com/

インストールが完了したら、ターミナルでコマンドを実行して、インストールがされているかを確認。

```
# インストール後の確認
$ vagrant -v
Vagrant 2.1.2
```

### Ansible
こちらはターミナルでコマンドを実行してインストール。

```
# インストール
$ brew install ansible

# インストール後の確認
$ ansible --version
ansible 2.6.0
```

## Vagrantの設定
### 新しくVagrantを作成
任意のディレクトリに移動して、そこに仮想環境を構築していく。

下記のコマンドを実行すると、Vagrantfileが作成される。これが、Vagrantの設定ファイルになる。

```
# Vagrantを初期化
$ vagrant init
```

### Vagrantfileに、仮想環境の設定を記述
Vagrantfileでは、作成する仮想環境のOSや、割り当てるメモリ、ホストとのディレクトリ共有設定などの設定ができる。

今回変更した箇所は、以下の通り。

#### OSにCentOS7を指定
Vagrantでは、boxという単位で環境を管理している。
今回は、CentOS7を構築するので、以下のように変更する。

```
# 元の記述
config.vm.box = "base"

# boxに centos/7 を指定
config.vm.box = "centos/7"
```

#### 固定ID:192.168.33.10でアクセスできるようにする
```
# 以下記述のコメントアウトを外す
config.vm.network "private_network", ip: "192.168.33.10"
```

#### ホストとゲストのディレクトリを共有する
ソースコードをホストとゲストで共有するために、ディレクトリの共有する記述をする。

以下の記述では、Vagrantfileと同じ階層にある htdocsディレクトリと、CentOS(ゲスト)の /var/www/htmlディレクトリを同期させている。なお、パーミッションは雑に777としているが、適宜変更すること。

```
# ディレクトリの共有の記述を書き換え

# 元の記述（コメントアウトされている）
# config.vm.synced_folder "../data", "/vagrant_data"

# 変更後
config.vm.synced_folder "./htdocs", "/var/www/html", :mount_options => [ "dmode=777", "fmode=777" ]
```

#### 仮想環境に割り当てるメモリを変更
仮想環境に割り当てるメモリを変更する。
あまり大きくしてもマシン全体が重たくなるだけなので、今回は大幅に減らして256MBとする。

```
# 元の記述（コメントアウトされている）
# config.vm.provider "virtualbox" do |vb|
#   # Display the VirtualBox GUI when booting the machine
#   vb.gui = true
#
#   # Customize the amount of memory on the VM:
#   vb.memory = "1024"
# end

# 変更後（コメントアウトを外して、値を変更）
config.vm.provider "virtualbox" do |vb|
#   # Display the VirtualBox GUI when booting the machine
#   vb.gui = true
#
#   # Customize the amount of memory on the VM:
  vb.memory = "256"
end
```

#### Ansible設定のための記述を追加
Ansibleを使うための記述を追加する。

```
# 以下の記述を、最終行の `end` の手前に追記
config.vm.provision "ansible" do |ansible|
  # 設定を適用する対象のサーバーの指定を記述するファイルの指定
  ansible.playbook = "ansible/playbook.yml"
  # サーバーの設定をカスタマイズするためのレシピを記述する設定ファイルの指定
  ansible.inventory_path = "ansible/hosts"
  ansible.limit = 'all'
end
```

## Ansibleの設定
次に、Ansibleの設定ファイルを作成し、記述していく。

### ansible/hosts を作成
まずは、設定を適用する対象のサーバーの指定を記述するファイルを作成する。
今回は、`ansible/hosts`というファイルを新規に作成して、以下の記述を行う。

```
[vagrant]
192.168.33.10
```

### ansible/playbook.yml を作成

次に、サーバーの設定をしていく設定ファイルを作成する。

今回記述した内容は、以下の通り。各項目で何をしているかはコメントで記載している。

```ansible/playbook.yml
---
- hosts: all
  sudo: yes
  vars:
    # MySQLのユーザーとパスワードを、変数に格納
    mysql_user_name: vagrant
    mysql_user_password: vagrant
  tasks:
    # SELinux停止
    - name: SELinuxのDisable設定
      selinux: state=disabled
 
    # ロケールの設定
    - name: add ja_JP.UTF-8 to locale
      shell: localedef -f UTF-8 -i ja_JP /usr/lib/locale/ja_JP.UTF-8
 
    - name: set locale
      shell: localectl set-locale LANG=ja_JP.utf8
      when: ansible_env.LANG | default('') != 'ja_JP.UTF-8'
 
    - name: set timezone to Asia/Tokyo
      timezone:
        name: Asia/Tokyo
 
    # Apacheをインストール
    - name: Install Apacheをインストール
      yum: name=httpd
 
    - name: Apacheを起動
      service: name=httpd state=started enabled=yes
 
    - name: .htaccessを有効にする
      replace: 
        dest=/etc/httpd/conf/httpd.conf
        regexp='AllowOverride None'
        replace='AllowOverride All'
 
    # PHP7.1をインストール
    - name: yum install epel-repease
      yum: name=epel-release state=installed
 
    - name: add remi-repo repository
      command: rpm -ih http://rpms.famillecollet.com/enterprise/remi-release-7.rpm creates=/etc/yum.repos.d/remi.repo
 
    - name: PHP7.1をインストール
      yum: name={{ item }} enablerepo=remi,remi-php71 state=installed
      with_items:
        - php
        - php-devel
        - php-fpm
        - php-mbstring
        - php-mcrypt
        - php-mysqlnd
        - php-pdo
        - php-xml
 
    - name: PHPをタイムゾーンの設定
      replace: >
        dest=/etc/php.ini
        regexp="^;date\.timezone ="
        replace="date.timezone = Asia/Tokyo"
 
    # MySQL5.6
    - name: MySQL5.6のリポジトリを追加
      command: >
        yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
        creates=/etc/yum.repos.d/mysql-community.repo
 
    - name: MySQLをインストール
      yum: name={{item}}
      with_items:
        - mysql-server
        - MySQL-python
 
    - name: MySQLを起動
      service: name=mysqld state=started enabled=yes
 
    - name: MySQLのユーザーを追加
      mysql_user: name={{ mysql_user_name }} password={{ mysql_user_password }} priv=*.*:ALL
 
    # Apache再起動
    - name: Apache再起動
      service: name=httpd state=restarted
```

## ゲストOSを起動して、動作確認

ゲストOSを起動して、動作確認する。

### ゲストOSを起動
Vagrantを起動する。
起動すると、ここまで設定してきた内容を勝手に読み込んで、サーバーの構築を進めてくれる。

```
# Vagrantを起動
$ vagrant up
```

問題なく進んでいけば、最後に以下のようなメッセージがでて、入力画面にもどるはず。

```
PLAY RECAP *********************************************************************
192.168.33.10              : ok=16   changed=15   unreachable=0    failed=0
```

### 動作確認
ホストOSの`/htdocs/`配下にphpinfoを出力するファイルを配置して、ゲストOSに同期され、実際にブラウザで表示できることを確認する。

#### ファイルを作成
```./htdocs/info.php
<?php phpinfo(); ?>
```

#### ブラウザでアクセス
以下のURLにアクセスします。
http://192.168.33.10/info.php

PHPに関する情報が表示されれば、OK。

## 環境を停止・破棄

仮想環境はメモリを常に使用する。ゲストOSを利用しないときはサーバーを停止しておくこともできる。

```
# Vagrantを停止（サーバーを停止）
$ vagrant halt
```

また、構築した環境が不要になった場合は、以下のコマンドでゲストOSを破棄できる。

```
# Vagrantを破棄（サーバーを廃棄）
$ vagrant destroy
```