ローカルPCでのVagrant、Ansibleを用いた開発環境構築
では、実際にVagrant及びAnsibleを使用してローカルに開発環境を構成する例をご紹介します。
インストール
ここではMacを対象として、VirtualBoxを利用してVagrant/Ansibleが動作する環境の構築方法についてご説明します。
本稿では、以下の環境での実行例をご紹介します。
- VirtualBox:5.2.22
- Vagrant:2.2.1
- Ansible:2.7.1
ここではHomebrewを利用して必要なソフトをインストールします。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
xcode-select --install
brew cask install virtualbox
brew cask install vagrant
vagrant plugin install vagrant-hostsupdater
sudo mkdir /usr/local/lib sudo mkdir /usr/local/include sudo mkdir /usr/local/Frameworks sudo mkdir /usr/local/Frameworks/Python.framework sudo chown -R $(whoami) $(brew --prefix)/* brew install ansible
Vagrantの設定(1)
Boxファイルは弊社にてVagrant Cloudに登録したAmazon Linux2のBoxファイルを利用して、最小限Webサーバが動作する環境を構築します(実際にはPHPなどさまざまなソフトをインストール、設定する必要がありますが、ここではWebサーバが動作するところまでを説明します)。
プロジェクトのルートディレクトリ(以下、PROJECT_ROOT)にvagrantフォルダを作成し、Vagrant関連の設定をします。ディレクトリのベストプラクティスについてはさまざまなWebサイト(例:Ansible Directory Layout)に紹介がありますので、ご参照ください。
今回想定するディレクトリ構成は以下のとおりです。
PROJECT_ROOT
├── vagrant
│ ├── config.yml // Vagrantfileで読み込む設定ファイル
│ ├── Vagrantfile // Vagrantの動作を記載
│ └── provisioning
│ ├── vagrant_playbook.yml // Vagrantでprovisionする際のplaybook
│ ├── group_vars
│ │ └── all.yml // Ansible全体をスコープとした変数
│ └── roles // Playbookて定義されたRole
│ │── common // 共通のタスク
│ │ └── tasks
│ │ │── main.yml
│ │ └── install_common_tools.yml
│ │── user_setup // ユーザー関連のタスク
│ │ │── tasks
│ │ │ │── main.yml
│ │ │ └── add_user.yml
│ │ └── templates
│ │ └── default_user_sudoers.j2
│ └── web // Webサーバ関連のタスク
│ │── tasks
│ │ │── main.yml
│ │ └── install_nginx.yml
│ │── templates
│ │ │── nginx.conf.j2
│ │ └── virtual.conf.j2
│ └── vars
│ └── main.yml
└── app
└── public
└── index.html
以下の手順で構築していきます。
- Vagrantの設定、実行用ファイルの作成
- Playbookの作成
- Roleの作成
- Vagrantの起動
1. Vagrantの設定、実行用ファイルの作成
VagrantファイルはVagrant及びVirtuialBoxでの動作を記載します。
ここではconfig.ymlに設定を記載し、Vagrantファイルで読み込ませます。
---
### VagrantCloudのOSイメージを落としてプロビジョニング(AmazonLinux2)
# https://app.vagrantup.com/suzukishouten/boxes/amznlinux2
vagrant_box: suzukishouten/amznlinux2
vagrant_box_version: 20180622.1.1
# 仮想マシン名
vagrant_hostname: sample.test
# 仮想マシンのIPアドレス
vagrant_ip: 192.168.33.10
# ホストマシンと仮想マシンのフォルダ共有
vagrant_synced_folder:
local_path: ../.
destination: /var/www/html
# nginxのポート番号の、ホストと仮想マシン間の変換
vagrant_forwarded_ports:
# nginx
- guest: 80
host: 8880
# メモリとCPUの設定
vagrant_memory: 613
vagrant_cpus: 1
# coding: utf-8
# -*- mode: ruby -*-
# Vagrant1.1+はAPI_VERSION=2を使用する
VAGRANTFILE_API_VERSION = "2"
# ディレクトリ定義
conf_dir = File.dirname(File.expand_path(__FILE__))
provision_dir = File.join(conf_dir, 'provisioning')
# config.ymlの取得
require 'yaml'
vconfig = YAML::load_file(File.join(conf_dir, "config.yml"))
# config.ymlを読み込み仮想マシンを設定
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# ホスト名を設定
config.vm.hostname = vconfig['vagrant_hostname']
# 自動設定
if vconfig['vagrant_ip'] == "0.0.0.0" && Vagrant.has_plugin?("vagrant-auto_network")
config.vm.network 'private_network', ip: vconfig['vagrant_ip'], auto_network: true
# IPアドレスが指定されている場合(vagrant_ip)
else
config.vm.network 'private_network', ip: vconfig['vagrant_ip'], auto_config: true
end
# ディレクトリの同期
# provisioning/group_vars/all.ymlのユーザのUIDと合わせる
# groupはvboxsfマウントのためwheelとしておく
config.vm.synced_folder vconfig['vagrant_synced_folder']['local_path'], vconfig['vagrant_synced_folder']['destination'], owner: 1002, group: "wheel", mount_options: ['dmode=775,fmode=775']
# ansible-playbookを使用してプロビジョニングを実施
config.vm.box = vconfig['vagrant_box']
config.vm.box_version = vconfig['vagrant_box_version']
# provisioning
extra_vars = {
"hostname" => vconfig['vagrant_hostname'],
}
config.vm.provision "ansible" do |ansible|
ansible.playbook = File.join(provision_dir, "vagrant_playbook.yml")
ansible.groups = {
"all:vars" => extra_vars
}
end
# VirtualBox用設定
config.vm.provider "virtualbox" do |v|
v.name = vconfig['vagrant_hostname']
v.memory = vconfig['vagrant_memory']
v.cpus = vconfig['vagrant_cpus']
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on", "--ioapic", "on", "--paravirtprovider", "kvm"]
end
end
詳細はファイル中のコメントを参照いただけるとわかると思いますが、重要な点は以下です。
config.yml
ホスト名をsample.testとしています。このホスト名はvagrant-hostsupdaterにより、/etc/hostsに書き込まれ、今回用意するWebサーバはhttp://sample.test/index.htmlでアクセス可能となります。
Vagrantfile
ゲストOSでのホストOSのディレクトリのマウントは以下のように実施されます。このマウントを実施することで、開発が容易になります。
- PROJECT_ROOT/vagrant ⇒ /vagrant
- PROJECT_ROOT ⇒ /var/www/html
他にも、MySQLなどをインストールする際にはポートマッピングを追加し、メンテナンスを容易にしたり、WindowsのホストOSでも動作させるために、config.vm.provisionをOSで分岐させ、Windowsでは(ansible.playbookではなく)shellを実行させたりすることも可能です。
上記のファイルを構成することで、VagrantによりゲストOS(Amazon Linux 2)が立ち上がり、provisioning/vagrant_playbook.ymlを用いて、プロビジョニングがされるようになります。
2. Playbookの作成
次に、AnsibleのPlaybookを作成していきます。
ここではvagrant/provisioning/group_vars/all.yml、vagrant/provisioning/vagrant_playbook.ymlを作成します。
vagrant/provisioning/group_vars/all.ymlでは、Ansible全体共通の変数を定義できます。ここでは、共通で作成するユーザーの情報を定義します。
# 全てのLinuxに共通して使用するユーザ default_user: name: sample uid: 1002 group: sample # 生成方法を下を参照 # 値はtesttest password: '$6$2GuHVOraryAl17aM$hngX4mqiKxsOA50KV/vOh10UbGnU1fZElnETy//M9nb7ZC4YIyCFLZS58KBzee14N1YcCjDqzV9C8TEikP6EE1'
ここで、passwordはLinux上のユーザーのパスワードです。ハッシュ化された値を入れる必要がありますが、ハッシュ化された値は以下の手順で生成します(別のLinux上で実行し生成します)。
$ sudo grub-crypt Password:testtest Retype password:testtest $6$2GuHVOraryAl17aM$hngX4mqiKxsOA50KV/vOh10UbGnU1fZElnETy//M9nb7ZC4YIyCFLZS58KBzee14N1YcCjDqzV9C8TEikP6EE1
次にvagrant/provisioning/vagrant_playbook.ymlを作成します。
このPlaybookで、Playbook内の変数の初期化や実際に実行されるロールを定義します。
- hosts: all
user: vagrant
# sudoをしてprovisioningを実施
become: yes
# このplaybookで実行される際の全体で使用できる変数
vars:
is_vagrant: True
# 実行されるロール
roles:
- common
- user_setup
- web
ここで、変数is_vagrantを定義していることに注意してください。この後説明するRoleは後述するPackerでも使用します。その際、Vagrantでのみ実行させたい分岐がある場合、ここで分岐の元となる変数を定義しておくと便利です(なお、VagrantFileで定義するとBooleanでもStringとして認識されるため、ここで分岐することをおすすめします)。
