Help us understand the problem. What is going on with this article?

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

More than 3 years have 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

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

0Delta
インフラエンジニアからプログラマーへ再転生したひと。 Golangはいいぞ
infra-workshop
インフラ技術を勉強したい人たちのためのオンライン勉強会です
https://wp.infra-workshop.tech/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away