LoginSignup
2
2

More than 5 years have passed since last update.

vagrant-cloudstackで複数VMの起動&Boxの作成

Last updated at Posted at 2014-12-06

Vagrantでは1つのVagrantfileから複数の仮想マシンを起動することができます。この機能を利用すると複数台の仮想マシンのクラスタで構成されるような環境も簡単に構築することができて便利です。

dummy boxで複数VMを作成

複数VMを1つのVagrantfileから作成できるのは便利ですが、dummy boxを利用している場合プロバイダの設定など同じ設定を何度も書いてしまうとVagrantfileが冗長になってしまいます。
例えば、vm01, vm02の2台のVMを起動するVagrantfileはvagrant-cloudstackでは以下のようになります。

vm01, vm02それぞれにプロバイダ・テンプレート・スペックの設定が書かれており非常に長くなっています。vm01, vm02で実際に違いがあるのは名前とポートフォワーディングのポートだけですが把握するのは困難です。

Vagrantfile
Dotenv.load

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

  config.ssh.username         = "#{ENV['VAGRANT_SSH_USERNAME']}"
  config.ssh.private_key_path = "#{ENV['VAGRANT_SSH_PRIVATE_KEY']}"
  config.vm.box = "dummy"
  config.vm.box_url = "https://github.com/klarna/vagrant-cloudstack/raw/master/dummy.box"

  config.vm.define "vm01", primary: true do |vm01|
    vm01.vm.provider :cloudstack do |cloudstack, override|

      cloudstack.host    = "compute.jp-east.idcfcloud.com"
      cloudstack.path    = "/client/api"
      cloudstack.port    = "443"
      cloudstack.scheme  = "https"

      cloudstack.api_key    = "#{ENV['CLOUDSTACK_API_KEY']}"
      cloudstack.secret_key = "#{ENV['CLOUDSTACK_SECRET_KEY']}"

      cloudstack.zone_name             = "tesla"
      cloudstack.template_name         = "CentOS 6.5 64-bit for Vagrant"
      cloudstack.service_offering_name = "light.S1"
      cloudstack.network_type          = "Advanced"
      cloudstack.network_name          = "network1"

      cloudstack.name = "vm01"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2201"
      override.ssh.port           = "2201"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end

  config.vm.define "vm02" do |vm02|
    vm02.vm.provider :cloudstack do |cloudstack, override|

      cloudstack.host    = "compute.jp-east.idcfcloud.com"
      cloudstack.path    = "/client/api"
      cloudstack.port    = "443"
      cloudstack.scheme  = "https"

      cloudstack.api_key    = "#{ENV['CLOUDSTACK_API_KEY']}"
      cloudstack.secret_key = "#{ENV['CLOUDSTACK_SECRET_KEY']}"

      cloudstack.zone_name             = "tesla"
      cloudstack.template_name         = "CentOS 6.5 64-bit for Vagrant"
      cloudstack.service_offering_name = "light.S1"
      cloudstack.network_type          = "Advanced"
      cloudstack.network_name          = "network1"

      cloudstack.name = "vm02"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2202"
      override.ssh.port           = "2202"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end
end
.env
CLOUDSTACK_API_KEY          = 'YOUR_API_KEY'
CLOUDSTACK_SECRET_KEY       = 'YOUR_SECRET_KEY'
CLOUDSTACK_PF_IP_ADDRESS_ID = 'YOUR_IP_ADDRESS_ID'
CLOUDSTACK_SSH_KEYPAIR      = 'YOUR_KEYPAIR_NAME'
VAGRANT_SSH_USERNAME        = 'vagrant'
VAGRANT_SSH_PRIVATE_KEY     = 'YOUR_SSH_KEY_PATH'

up, ssh, destroyといったコマンドは基本的に1台の場合と同じです。SSHする際にはVM名を指定します。修正したVagrantfileについてもコマンドは同じなので以降コマンドについての説明は割愛します。

$ vagrant up --provider=cloudstack
$ vagrant ssh vm01
$ vagrant ssh vm02
$ vagrant destroy

共通部分をまとめてみる

vm01とvm02のプロバイダ・テンプレート・スペックは共通なのでまとめてみます。

vm01、vm02の個別の設定が分離されて大分読みやすくなりました。

Vagrantfile
Dotenv.load

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

  config.ssh.username         = "#{ENV['VAGRANT_SSH_USERNAME']}"
  config.ssh.private_key_path = "#{ENV['VAGRANT_SSH_PRIVATE_KEY']}"

  config.vm.box = "dummy"
  config.vm.box_url = "https://github.com/klarna/vagrant-cloudstack/raw/master/dummy.box"

  config.vm.provider :cloudstack do |cloudstack|

    cloudstack.host    = "compute.jp-east.idcfcloud.com"
    cloudstack.path    = "/client/api"
    cloudstack.port    = "443"
    cloudstack.scheme  = "https"

    cloudstack.api_key    = "#{ENV['CLOUDSTACK_API_KEY']}"
    cloudstack.secret_key = "#{ENV['CLOUDSTACK_SECRET_KEY']}"

    cloudstack.zone_name             = "tesla"
    cloudstack.template_name         = "CentOS 6.5 64-bit for Vagrant"
    cloudstack.service_offering_name = "light.S1"
    cloudstack.network_type          = "Advanced"
    cloudstack.network_name          = "network1"
  end

  config.vm.define "vm01", primary: true do |vm01|
    vm01.vm.provider :cloudstack do |cloudstack, override|
      cloudstack.name = "vm01"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2201"
      override.ssh.port           = "2201"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end

  config.vm.define "vm02" do |vm02|
    vm02.vm.provider :cloudstack do |cloudstack, override|
      cloudstack.name = "vm02"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2202"
      override.ssh.port           = "2202"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end
end

Boxの作成

共通部分をまとめることで大分読みやすくなりました。この共通部分をよく見てみると、プロバイダやテンプレート・スペックといった設定は他のVagrantfileでも使えそうです。そこでこの設定をBox化し再利用できるようにしてみます。

ここでは「idcfcloud_centos_6.5」というBoxを作成します。

まず、Box作成用にディレクトリを作成しておきます。どこでも良いのですが今回はVagrantfileと同じディレクトリにボックス名と同じ名前のディレクトリを作ります。

$ mkdir idcfcloud_centos_6.5

作成したディレクトリの中に以下の2つのファイルを作成します。
Vagrantfileでは先ほどまとめた共通部分の設定内容を指定しています。

Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.provider :cloudstack do |cloudstack|

    cloudstack.host    = "compute.jp-east.idcfcloud.com"
    cloudstack.path    = "/client/api"
    cloudstack.port    = "443"
    cloudstack.scheme  = "https"

    cloudstack.api_key    = "#{ENV['CLOUDSTACK_API_KEY']}"
    cloudstack.secret_key = "#{ENV['CLOUDSTACK_SECRET_KEY']}"

    cloudstack.zone_name             = "tesla"
    cloudstack.template_name         = "CentOS 6.5 64-bit for Vagrant"
    cloudstack.service_offering_name = "light.S1"
    cloudstack.network_type          = "Advanced"
    cloudstack.network_name          = "network1"
  end
end
metadata.json
{
    "provider": "cloudstack"
}

作成できたら以下のコマンドで固めてBoxにします。

$ cd idcfcloud_centos_6.5
$ tar cfvz idcfcloud_centos_6.5.box  Vagrantfile metadata.json

うまく作成できたらBoxの追加を行います。

$ vagrant box add --name idcfcloud_centos_6.5 idcfcloud_centos_6.5.box

成功すると以下のようなメッセージが表示されます。

==> box: Successfully added box 'idcfcloud_centos_6.5' (v0) for 'cloudstack'!

Boxを使って複数VMを作成する

作成したBoxを利用してVagrantfileを書き直してみます。dummy boxを作成したBoxに書き換え、Boxに記述した共通部分を削除すればOKです。

最初のVagrantfileと比べると大分すっきりしました。Boxの設定はVM毎にできるのでBoxさえ作成しておけば異なる構成のVMからなるクラスタも簡単に記述できます。

Vagrantfile
Dotenv.load

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

  config.ssh.username         = "#{ENV['VAGRANT_SSH_USERNAME']}"
  config.ssh.private_key_path = "#{ENV['VAGRANT_SSH_PRIVATE_KEY']}"
  config.vm.box = "idcfcloud_centos_6.5"

  config.vm.define "vm01", primary: true do |vm01|
    vm01.vm.provider :cloudstack do |cloudstack, override|
      cloudstack.name = "vm01"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2201"
      override.ssh.port           = "2201"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end

  config.vm.define "vm02" do |vm02|
    vm02.vm.provider :cloudstack do |cloudstack, override|
      cloudstack.name = "vm02"
      cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
      cloudstack.pf_public_port   = "2202"
      override.ssh.port           = "2202"
      cloudstack.pf_private_port  = "22"
      cloudstack.keypair          = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
    end
  end
end

まとめ

Boxを使用すると複数台の仮想マシンを1つのVagrantfileから作成する場合にも簡潔な記述で済ますことができます。作成したBoxは他のVagrantfileで再利用できるのでよく使う設定についてはBoxを作成しておくと管理が楽になると思います。

資料

今回作成したVagrantfile等は以下にあります。
* https://github.com/atsaki/vagrant-examples/tree/master/multivm

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2