Posted at

VagrantFileをちょっとだけわかりやすくする

More than 1 year has passed since last update.


概要

vagrantfileがrubyで動いているという話。

rubyで動いてるなら、関数とか使えるんじゃ…と思って使ったら動いたというお話。


産物

# -*- mode: ruby -*-

# vi: set ft=ruby :
def VMconf(config ,hostname ,ip:nil ,cpu:1 ,cpulimit:100 ,memory:1024 ,customCode:nil, **var)
config.vm.define hostname do |vh|
if ip == nil then
vh.vm.hostname = hostname
vh.vm.network "private_network",type: "dhcp", virtualbox__intnet: "VMNet_Vagrant", auto_config: true
else
vh.vm.hostname = hostname
vh.vm.network "private_network",ip: ip, virtualbox__intnet: "VMNet_Vagrant", auto_config: true
end
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.cpus = cpu.to_s
vb.memory = memory.to_s
vb.customize [
"modifyvm", :id,
"--cpuexecutioncap", cpulimit.to_s,
"--groups", "/Vagrant/Vpractice"
]
vb.linked_clone = true
end

# yum update とかの共通処理があれば追加
# config.vm.provision :shell, :path => "./common_setup.sh",:privileged => true
if customCode != nil then
customCode.call(config,vh)
end
end
end

def DumpPack(config)
config.vm.provision "shell",inline: <<SCRIPT
yum install tcpdump -y
echo "SELINUX=permissive" > /etc/sysconfig/selinux
setenforce 0
SCRIPT
end

def WebKit(config)
config.vm.provision :shell,inline: <<SCRIPT
yum install httpd -y
echo '<http><body><h1>' > /var/www/html/index.html
hostname >> /var/www/html/index.html
echo '</h1></body></html>' >> /var/www/html/index.html
service httpd start
chkconfig httpd on

iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
service iptables save
SCRIPT
end

def HostOnlyInterface(vmhandle,ip)
vmhandle.vm.network "private_network",
name:"VirtualBox Host-Only Ethernet Adapter #1",
ip: ip,
netmask: "255.255.255.0",
auto_config: true
end

fuga_scripts = ::Kernel.lambda{ |config,vmhandle|
# DumpPack(config) # ダンプする場合に使う
WebKit(config)
HostOnlyInterface(vmhandle,"172.16.0.12")
}

box = "CentOS6.9_min_customed"
Vagrant.configure(2) do |config|
config.vm.box = box
VMconf(config, "hoge", :ip=>"192.168.254.130", :cpu=>2, :cpulimit=>50, :memory=>8192)
VMconf(config, "fuga", :ip=>"192.168.254.131", :customcode=>fuga_scripts)
end


このコードでできたこと


簡単なVMなら一行で定義できる

# VCPUx2、CPU制限50%、メモリ8GBのVM"hogehoge1"を作る。 eth1には192.168.254.140を割り当てる

VMconf(config, "hogehoge1", :ip=>"192.168.254.140", :cpu=>2, :cpulimit=>50, :memory=>8192)

# VM"hogehoge2"を作る。VCPUx1で使用率制限なし、メモリ1GB、eth1はDHCP。
VMconf(config, "hogehoge2")


機能を関数にまとめて使いまわせる

# httpサーバのタネ作る関数

def WebKit(config)
config.vm.provision :shell,inline: <<SCRIPT
yum install httpd -y
echo '<http><body><h1>' > /var/www/html/index.html
hostname >> /var/www/html/index.html
echo '</h1></body></html>' >> /var/www/html/index.html
service httpd start
chkconfig httpd on

iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
service iptables save
SCRIPT
end

# ホストオンリーアダプタを追加する関数
def HostOnlyInterface(vmhandle,ip)
vmhandle.vm.network "private_network",
name:"VirtualBox Host-Only Ethernet Adapter #1",
ip: ip,
netmask: "255.255.255.0",
auto_config: true
end

###----これより上は使いまわせる。別ファイル化しても良いかも。----###

# 各VM用の関数を定義。
fuga1_scripts = ::Kernel.lambda{ |config,vmhandle|
WebKit(config)
HostOnlyInterface(vmhandle,"172.16.0.11")
}
fuga2_scripts = ::Kernel.lambda{ |config,vmhandle|
WebKit(config)
HostOnlyInterface(vmhandle,"172.16.0.12")
}
~~ 中略 ~~
# 作ったラムダ関数を渡す。
VMconf(config, "fugafuga1", :customcode=>fuga1_scripts)
VMconf(config, "fugafuga2", :customcode=>fuga2_scripts)


このコードのダメなところ


IPに関しては事前準備が必要


  • 「VMNet_Vagrant」という内部ネットワークがVirtualBoxに存在する

  • 「VMNet_Vagrant」内部ネットワーク内でDHCPが利用可能

これが前提になってしまっている。

vagrant connectで繋ぐからそんなの要らない! って人は下記部分を削除する必要がある。

  if ip == nil then

vh.vm.hostname = hostname
vh.vm.network "private_network",type: "dhcp", virtualbox__intnet: "VMNet_Vagrant", auto_config: true
else
vh.vm.hostname = hostname
vh.vm.network "private_network",ip: ip, virtualbox__intnet: "VMNet_Vagrant", auto_config: true
end

その他、ダメなところはコメントで募集中です。(良いところも募集中です)