開発環境の構築・共有を簡単にするVagrant入門

2015年3月19日(木)
前佛 雅人(ぜんぶつ まさひと)

Vagrantとは?

Vagrantは、開発環境の構築と共有を簡単に行うためのツールです。どこでも同じ環境を再現できるように仮想マシン環境を管理する機能と、Atlasを通して共有する仕組みが提供されています。

VagrantとAtlasの関係

Vagrantは、アプリケーションやシステム開発のバックエンドを簡単にパッケージ化し、共有するためのツールです。このパッケージ化された環境を、「box」と呼ばれる単位で管理します。このboxには、標準で対応しているVirtualBoxをはじめ、AWSなどの各種マシン・イメージに対応したプラグインを介してアクセスします。またboxを共有するための機能としてAtlasという名前のインターネット上のサービスが提供されています。なお、Atlasは以前VagrantCloudと呼ばれていたものですが、現在はHashiCorpの他のツール(Packer、Terraform、Consul)とも連携できるように拡張されています。

VagrantとAtlasの関係

図1:VagrantとAtlasの関係(クリックで拡大)

VirtualBoxとの違い

Vagrantは、yumやapt-getのようなコマンドの実行や、ChefやAnsible等のツールを使って自動的にアプリケーションやミドルウェアをセットアップするプロビジョニング機能を備えています。また、ネットワークの設定などVirtualBoxのGUIを通さず、VirtualBoxの設定ファイル上で管理することができます。そのため、自分の作業環境を別の場所で再現したり、あるいは、チームや社内で設定環境を共有したりする際に役立つでしょう。

Vagrantが管理できる仮想マシンは、VirtualBoxやVMwareのものだけでなく、AWS等のパブリック・クラウド上の仮想マシンも操作できます。Vagrantが各種の仮想マシンを操作するのに使うのが、プロバイダと呼ばれるものです。VirtualBox用のプロバイダが初めからインストールされていますが、それ以外にもVagrantのプラグイン機能を通して、様々なプロバイダを使い分けることができます。

今回は、Vagrantを使ってできることを具体的に見ていきます。

Vagrantのセットアップ

VagrantはMac OS X、Windows、Linuxに対応したパッケージが配付されています。自分の環境にあったものをダウンロードし、セットアップを行いましょう。またVagrantに加えて、VirtualBoxのダウンロードも必要です。

Vagrantのダウンロード

http://www.vagrantup.com/downloads.html

VirtualBoxのダウンロード

http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp

それぞれインストールが完了しますと、Vagrantが利用できるようになります。以降の操作では、Vagrantを使って仮想マシンの起動・停止を行いますが,その際にVirtualBoxの設定を行う必要はありません。

ここではVirtualBoxを使う前提で説明を進めますが、前述のようにVirtualBoxを使わずに、VMwareやパブリック・クラウドとの連携も可能です。

初めての仮想マシン起動と操作

それでは、実際に仮想マシンを起動し、ウェブサーバの自動設定や、SSHで仮想マシン内にログインしてみましょう。以下の手順で仮想マシンを起動します。

  1. 作業用ディレクトリでVagrantfileを作成し、仮想マシン・イメージ(box)を指定
  2. コマンドラインで「vagrant up」を実行

仮想マシンの環境設定

VagrantをインストールしたPC上の、任意のディレクトリで名称「Vagrantfile」という名前のファイルを作成します。ファイルにはリスト1のような内容を記述します。

リスト1:Vagrantfileの内容

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
end

1行目は、設定ファイルのバージョンが2であることを意味します。これは、将来の互換性を保持するためのものです。2行目の「config.vm.box」は、Vagrantが扱う「box」と呼ばれる仮想マシン・イメージの形式を指定します。ここでは「hashicorp/precise64」という名称のUbuntuが動作するboxを指定しています。

boxは、Atlas(旧VagrantCloud)で公開されているものや組織で共有しているものの他に、URLやファイル名のパスで指定することもできます。Atlasで公開されている boxイメージは、Vagrantfileで名前を指定するだけで自動的にダウンロードされます。その他のイメージ、例えばVagrantbox.esなどで配付されているboxは、「vagrant box add 」の形式で登録してから利用します。また公式サイトには、ユーザが自分でboxを作る方法も紹介されています。

Vagrantfileは新たに作成せずに、他の場所からコピーしてきても構いません。あるいは「vagrant init」コマンドの実行で、サンプルが記述されたVagrantfileが作成されますので、そちらを参考に設定を行うこともできます。

仮想マシンの起動

仮想マシンを起動するには、コマンドライン上で「vagrant up」コマンドを実行します(リスト2)。最初の実行時には、ローカルの環境にboxが存在しないのでAtlasからダウンロードが始まります。そのためネットワーク環境によっては、長い時間がかかるでしょう。しかし次回以降は、ローカルに保存しているboxを使って起動しますので、すぐに起動するようになります。

リスト2:Vagrantで仮想マシンを起動する

$ vagrant up

これで、仮想マシンが自動的に起動しました。先ほどの「vagrant up」を実行し、boxイメージのダウンロード後は、自動的にVirtualBoxを操作して仮想マシンが起動されていきます。VirtualBoxの画面を見ますと、自動的に仮想マシンが起動していることも確認できますが、通常はVirtualBoxを意識する必要はありません。

仮想マシンのログインと操作

仮想マシンにログインするには、「vagrant ssh」を実行します(リスト3)。成功するとvagrantアカウントでログインした状態となります。また、rootにスイッチするには「sudo su」と実行します。

リスト3:Vagrantで仮想マシンにログインする

$ vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:23:18 2012 from 10.0.2.2
vagrant@precise64:~$

この他にも、覚えておきたい基本的なコマンドがいくつかありますので、まとめて表にしておきます。

Vagrantの基本的なコマンド

コマンド機能
vagrant up仮想マシンを起動
vagrant ssh仮想マシンにログイン
vagrant halt仮想マシンを停止
vagrant suspend仮想マシンを一時停止
vagrant status仮想マシンの起動状態を確認
vagrant destroy仮想マシンを破棄

このように、Vagrantがあれば単純な操作で開発環境を構築できて、すぐ開発に取り組むことができます。

プロビジョニング機能

Vagrantは、「vagrant up」で仮想マシンを起動したあと、自動的なコマンドの実行やアプリケーションの設定を行うプロビジョニング機能を備えています。この機能を活用することで、OSの初期設定や、アプリケーションのインストール作業を迅速かつ正確に行えるようになります。

vagrant up実行後の処理

図2:vagrant up実行後の処理(クリックで拡大)

プロビジョニング機能を使うには、Vagrantfile中で設定を記述します。リスト4の例は、dateコマンドの実行結果を出力するものです。

リスト4:プロビジョニング機能の実行例。dateコマンドを実行している

 config.vm.provision "shell", inline: "date > /vagrant/date.txt"

Vagrantfileにリスト4を追加した後に「vagrant up」を行いますと、OS起動時にdateコマンドが実行されます。既に仮想マシンが起動状態の場合は、コマンド「vagrant provision」でプロビジョニング部分だけを実行できます。反対に「vagrant up --no-provision」とオプションを追加することで、Vagrantfileに書かれたプロビジョニングを実行せずに起動することもできます。

さらにPC上にあるスクリプトの実行も可能です。例えばprovision.shを実行したい場合はリスト5のように記述します。

リスト5:手元のPC上にあるスクリプトを実行する

 config.vm.provision "shell", path: "provision.sh"

また、リモートにあるファイルの実行も可能です。リスト5の「provision.sh」の代わりに、GitHubなどウェブサーバのURLも指定できます(リスト6)。

リスト6:リモートファイルを実行する

  config.vm.provision "shell", path: "https://gist.githubusercontent.com/xxxx/provision.sh"

そのほか、ChefやPuppetやAnsible等のプロビジョニング・ツールとも連携できます。詳細はドキュメントを参照してください。

Provisioning - Vagrant Documentation

http://docs.vagrantup.com/v2/provisioning/index.html

フォルダの共有機能

Vagrantは、開発をスムーズにするためのフォルダ共有機能を備えています。これはVagrantで仮想マシンを起動すると、開発用PCと仮想マシン内のディレクトリを自動的に同期してくれるものです。これにより、PCで使っている自分の好きなエディタを使って、仮想マシン上のソースコードを編集できるだけでなく、手元のツールでテストや任意の処理ができます。仮想サーバ上で何か処理する際に、いちいちログインする必要がありませんので、開発作業に集中することができます。

Vagrantのフォルダ共有機能で、開発用PCと仮想マシン間のディレクトリ内容がリアルタイムに同期される

図3:Vagrantのフォルダ共有機能で、開発用PCと仮想マシン間のディレクトリ内容がリアルタイムに同期される(クリックで拡大)

それでは実際に共有することを確かめて見ましょう。「vagrant up」で仮想マシンを起動すると、Vagrantfileを実行したフォルダと仮想マシン内の「/vagrant」ディレクトリがリアルタイムで同期します。リスト7のように、仮想マシン内でディレクトリを移動して、ファイルを作成すると、手元のPC上にも同様のファイルが作成されることが確認できます。

リスト7:同期されていることを確認してみる

vagrant@precise64:/vagrant# echo "hello" > hello.txt

その逆に、作成されたhello.txtをPC上のエディタで編集・保存すると、その結果がサーバ内のファイルにも反映されていることが分かります。

共有するフォルダは変更可能で、例えばPC内の「./data」フォルダと仮想マシンの「/share/data」を同期したい場合は、Vagrantfileにリスト8のように記述します。

リスト8:Vagrantfile内で共有フォルダを指定する

  config.vm.synced_folder "./data", "/share/data"

そのほか、共有機能ではNFS、rsync、SMBに対応しています。詳細はドキュメントをご覧ください。

Synced Folders - Vagrant Documentation

http://docs.vagrantup.com/v2/synced-folders/index.html

AtlasでHTTPとSSHの共有

開発環境をインターネットで共有するvagrant share

開発過程で、手元のPCの環境をリモートの開発者と共有したいとき、これを簡単に実現する機能がVagrantとAtlasを通して提供されています。開発環境で「vagrant share」コマンドを実行すると、実行した環境に対して「<ホスト名>.vagrantshare.com」のホスト名が自動的に割り当てられます。リモートの開発者はブラウザを通して開発環境にアクセスできるだけでなく、「vagrant connect 」コマンドを使って直接SSHログインすることもできます。また、ウェブだけの利用であれば、任意のホスト名・ドメイン名を指定することも可能ですので、開発環境だけでなく、デモ環境の提供やインターネット上のサービスとの連携にも活用できます。

VagrantとAtlasの機能を使って、開発環境を共有する

図4:VagrantとAtlasの機能を使って、開発環境を共有する(クリックで拡大)

Atlasにログイン

共有機能を使うには、まずAtlasにログインする必要があります。もしアカウントがなければ、登録から始めましょう。もしVagrantCloudのアカウントを持っていれば、アカウントは共通なので、そのままAtlasにもログインできます。

Atlas by HashiCorp

https://atlas.hashicorp.com/

ログインするには「vagrant login」コマンドを実行し、Atlasのユーザ名(Username)とパスワードを入力します(リスト9)。

リスト9:Atlasにログイン

$ vagrant login
(省略)
Atlas Username: <ユーザ名を入力>
Password (will be hidden): <パスワードを入力>
You are now logged in.

HTTP(S)を共有

それでは、実際に仮想マシン環境を共有してみましょう。HTTPとSSHを共有する環境を準備するために、リスト10のVagrantfileを準備します。この例では仮想マシンにUbuntuのboxを使い、Apacheのセットアップを行ったあと、ドキュメントルートを/vagrantに置き換えています。また、ホストマシンのポート4567番を仮想マシン内のポート80番にポート転送(Port Forward)する設定も行っています。HTTP(S)の環境を共有するためには、このようにホスト側にポートを割り当てる必要があります。

リスト10:共有機能を使うためのVagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.network :forwarded_port, host: 4567, guest: 80
  config.vm.provision :shell, inline = <<SCRIPT
    apt-get update
    apt-get install -y apache2
    if ! [ -L /var/www ]; then
      rm -rf /var/www
      ln -fs /vagrant /var/www
    fi
  SCRIPT
end

それから「vagrant up」を実行した後に、共有を開始するために「vagrant share」を実行します(リスト11)。すると自動的にホスト名が割り当てられ、画面に表示されるURLでアクセスできるようになります。終了したい場合は「Ctrl+C」を入力します。

リスト11:仮想マシンを起動した後に共有を開始する

$ vagrant up
$ vagrant share
(省略)
==> default: Checking authentication and authorization...
==> default: Creating Vagrant Share session...
    default: Share will be at: famous-dingo-xxxx
==> default: Your Vagrant Share is running! Name: famous-dingo-xxxx
==> default: URL: http://famous-dingo-xxxx.vagrantshare.com

ブラウザでこのURLにアクセスすると、Vagrantfileが見えます。このディレクトリでファイルの新規作成や編集をしますと、内容がブラウザにも反映することが確認できます。

SSHを共有

引き続きSSHを共有する方法を見ていきます。起動時のオプションで「vagrant share --ssh」を実行します(リスト12)。正常に処理が終われば、ホスト名とドメイン名が確認できます。

リスト12:SSH共有の手順

$ vagrant share --ssh
(省略)
==> default: Generating new SSH key...
    default: Please enter a password to encrypt the key: <SSHログイン用パスワード入力>
    default: Repeat the password to confirm: <パスワード再入力>
(省略)
==> default: Creating Vagrant Share session...
    default: Share will be at: demanding-zebra-xxxx
==> default: Your Vagrant Share is running! Name: demanding-zebra-xxxx
==> default: URL: http://demanding-zebra-xxxx.vagrantshare.com

この環境にSSHでログインするには「vagrant connect」を実行します(リスト13)。SSHの共有を終了したい場合も「Ctrl+C」を入力します。

リスト13:SSH共有の環境でログインする手順

$ vagrant connect --ssh demanding-zebra-xxxx

任意のドメイン名やホスト名を使う方法

共有時には、自動作成される*.vagrantup.comではなく、任意のドメイン名も利用できます。ここでは「<ホスト名>.vagrant.example.jp」でアクセスする方法を見ていきましょう。

まず始めに必要なのは、ゾーン情報の変更です。具体的には、share.vagrantcloud.comにCNAMEレコードを追加します。例えば、BINDを使って「<ホスト名>.vagrant.example.jp」というホスト名を使いたいとき、リスト14のようにレコードを記述します。

リスト14:ゾーン情報を変更して、任意のドメイン名・ホスト名を使用する

*.vagrant       IN      CNAME   share.vagrantcloud.com.

設定後「dig 任意の名称.vagrant.example.jp a」を実行し、share.vagrantcloud.comで名前解決ができていれば準備完了です。

次に、Atlas上にドメイン名を登録します。アカウントの設定画面で図5のように「ORGANIZATIONS」の欄に自分の名前が表示されていますので、そこをクリックします。さらにメニューで「Configuration」をクリックし、「Name」のフィールドに共有で使いたいドメイン名を記入し、「Add Domain」を入力します(この例では「vagrant.example.jp」と入力)。後ほど共有を解除したい場合にも、この画面から削除できます。

Atlas上でドメイン名を登録する

図5:Atlas上でドメイン名を登録する

最後に開発環境上で「vagrant share」コマンドを使います。リスト15のようにオプション「--domain」でドメイン名を、「--name」でホスト名を指定すると、「http://test.vagrant.example.jp」として接続することができます。

リスト15:vagrant shareコマンドで共有するURLを指定

$ vagrant share --name test --domain vagrant.example.jp

注意点としては、SSHで共有する場合はホスト名の指定ができないことが挙げられます。また、ドメインを毎回オプションで設定せずに、常に特定のドメイン名を使うこともできます。アカウントの設定から、「Configuration」をクリックし、Vagrant Share Domainsに表示されているドメイン名の列にある「Set default」をクリックします。有効化したあとは、自動的に登録したドメイン名が毎回割り当てられます。

コードを簡単にデプロイするPush機能

開発が進むと、コードを別のサーバ環境に送り、テストやデプロイなど開発中のコードを共有したい場合が出てきます。そのような場面に便利なのがPush機能で、「vagrant push」コマンドで利用します(Vagrantバージョン1.7以降に対応)。コマンドを実行すると、Vagrantfileのあるディレクトリ以下を別のサーバにFTPで転送したり、rsyncやscpのようなコマンドを実行したり、あるいはAtlasやHerokuへ送信したりすることもできます。

VagrantのPush機能でデプロイ作業を効率化する

図6:VagrantのPush機能でデプロイ作業を効率化する(クリックで拡大)

Push機能を使うためには、どの手段でどの環境に送信するかをVagrantfileに記述します。この手段のことをVagrantでは「strategy」と呼びます。例えばFTPを使ってデプロイするには、「ftp」という名称のstrategyをリスト16のように指定します。

リスト16:strategyにftpを指定する

  config.push.define "ftp" do |push|
    push.host = "ftp.example.jp"
    push.username = "ユーザ名"
    (省略)
  end

コードの共有には、Vagrantのboxを共有する方法もあります。しかし、boxは作成や転送に手間と時間を要するため、ある程度の完成形に近くなってからのアップロードに適しているでしょう。一方vagrant pushを使う方法であれば、既存の環境に対して手軽に送信できるという利点があります。以下では、ローカルのファイルをFTPかコマンドラインでデプロイする方法を見ていきます。

FTP・SFTPを使うには

リモートのサーバ上にFTP・SFTPでファイルを転送したい場合は、あらかじめVagrantfileにリスト17のように記述しておきます。

リスト17:FTP・SFTPでファイル転送をする際のVagrantfileの内容(strategy)

  config.push.define "ftp" do |push|
    push.host = "ホスト名"
    push.username = "ユーザ名
    push.password = "パスワード"
    push.destination = "/www" # アップロード先ディレクトリ
    # SFTP 使用時
    # push.secure = "true"
  end

記述後は、任意のタイミングで「vagrant push」コマンドを実行すると、自動的にFTP・SFTPでファイルの転送が実行されます。

Vagrantfileで利用できるオプションは、以下の表の通りです。

Push機能のstrategyで利用できるオプション

オプション説明デフォルト値
push.hostリモートのFTPサーバのホスト名
push.usernameサーバのログインに使用するユーザ名
push.passwordログインユーザのパスワード
push.passiveFTP時にPassiveモードを使用true
push.secureSFTPを使用false
push.destinationサーバ側の同期先ディレクトリ/
push.exclude除外するファイルやディレクトリのパターン(includeより優先)
push.includeアップロード対象とするファイルやディレクトリのパターン
push.dirファイルアップロード元のディレクトリ指定カレントディレクトリ

任意のコマンドを実行するには(LOCAL EXEC)

FTPだけでなく、作業をしているPCやサーバ内でディレクトリのコピーをしたり、rsync・scpコマンドを使ったりするような応用も可能です。リスト17の「ftp」の箇所を「local-exec」に書き換えます。リスト18の例は、scpを使って複数のサーバに特定のディレクトリをコピーするものです。

リスト18:scpを用いる場合のstrategyの例

  config.push.define "local-exec" do |push|
    push.inline = <<SCRIPT
      scp -r ./app/ vagrant@app.pocketstudio.net:/home/vagrant/
      scp -r ./data/ vagrant@data.pocketstudio.net:/home/vagrant/
    SCRIPT
  end

なお、このようにscpを使う場合は、パスフレーズを使わずSSHログインできるような設定が必要です。またpush.inlineでコマンドを記述する代わりに、任意のスクリプトを「push.script = "<スクリプト名>"」で指定し、実行することもできます。コマンドやファイルに対するパスは、Vagrantfileのあるディレクトリが起点となります。

複数のデプロイ先を切り替えるには

用途に応じてデプロイ先を使い分けることもできます。例えば、ステージング環境(staging)にはftpを、本番環境(prod)にはlocal-execを用いてデプロイするには、リスト19のように記述します。

リスト19:オプションでデプロイ先を切り替える例

  config.push.define "staging", strategy: "ftp" do |push|
    (省略)
  end
  config.push.define "prod", strategy: "local-exec" do |push|
    (省略)
  end

ステージング環境に送る場合は「vagrant push staging」、本番環境に送る際には「vagrant push prod」と入力することで、デプロイする環境を切り替えられます。

まとめ

開発環境の基盤としてのVagrantの役割と、Atlasとの連携方法を見てきました。今回紹介した機能の詳細については、Vagrant公式サイトのドキュメントも参照してください。

Vagrant Documentation

https://docs.vagrantup.com/v2/

今回は、VagrantとAtlasでbox環境を作成しました。次の課題は、このbox環境を他人と共有したり、クラウド上に展開したりするにはどうしたらよいかということになります。これを解決すべく、次回は手元のPCだけでなく、クラウド環境とVagrantの連携方法や、Packerを使ってマシン・イメージを管理する方法を見ていきます。

※本稿は、2015年3月現在のAtlasおよびVagrant 1.7.2に対して確認を行っています。

【参考文献】

Vagrant

https://www.vagrantup.com/

VAGRANT DOCUMENTATION

https://docs.vagrantup.com/v2/

ATLAS Documentation

https://atlas.hashicorp.com/help/documentation/applications-and-dev-environments

著者
前佛 雅人(ぜんぶつ まさひと)
クリエーションライン株式会社

Technology Evangelist
ホスティングサービスで運用保守サポートに携わった後、現職へ。サポート業務や新技術検証や開発業務を行う傍ら、実家で農作業のため東京と富山を往復する日々。趣味で監視や自動化に関するOSS検証や翻訳を行う。とりわけ運用・監視の省力化・最適化に興味。辛口の日本酒が大好き。
Twitter: @zembutsu (https://twitter.com/zembutsu)

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています