Unable to assign static ip using Vagrant - vagrant

I am using Vagrant and vagrant-vshpere plugin to deploy VM on vCenter. Vagrant deploys the VM but it fails to assign the ip address for the VM. Could any body let me know do i need to make specific changes in order for the ip address to be assigned?
Here are the contents of my Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = 'dummy'
config.vm.box_url = './example_box/dummy.box'
config.vm.network :public_network, ip: "xxx.xxx.xxx.xxx"
config.vm.provider :vsphere do | vsphere |
vsphere.host = '<vSphere_Host>'
vsphere.data_center_name = '<Data_Center_Name>'
vsphere.data_store_name = '<Data_Store_Name>'
vsphere.template_name = '<Template_Name>'
vsphere.name = '<New_Name_Of_The_VM>'
vsphere.user = '<vShpere_User_Name>'
vsphere.password = '<The_Password>'
vsphere.insecure = true
vsphere.compute_resource_name = '<Compute_Resource_IP>'
end
end
Note: The template that i am uploading is a custom template [a linux box with some applications running on top of it]

You can set static ip with a private network..
try with this network configuration
config.vm.network "private_network", ip: "192.168.50.4"

Related

Ruby Vagrant network configuration duplication trouble, some objects references issue

I will say right away - I'm experienced in Python for example, but Ruby is totally new for me so this question may be not related to Vagrant at all, I don't know, sorry.
I want to create two VMs on my host and created Vagrantfile:
Vagrant.configure("2") do |config|
# Image config
config.vm.box = "ubuntu/bionic64"
config.disksize.size = '40GB'
# Nodes specific configs
config.vm.define "node_1_1" do |node|
node.vm.network "public_network", ip: "192.168.3.11", bridge: "enp4s0", netmask: "255.255.248.0"
node.vm.hostname = "vm-ci-node-1-1"
end
config.vm.define "node_1_2" do |node|
node.vm.network "public_network", ip: "192.168.3.12", bridge: "enp4s0", netmask: "255.255.248.0"
node.vm.hostname = "vm-ci-node-1-2"
end
# Nodes generic configs
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus=2
end
end
It works fine.
Then I decided to remove parameters hardcode and optimize it for next case with more than two VMs and for correct work on another machines with another bridge interface names. So I replaced Nodes specific configs section with:
target_interface = nil
for if_addr in Socket.getifaddrs
if if_addr.addr.ipv4? and if_addr.addr.ip_address.include? '192.168'
target_interface = if_addr.name
end
end
hostindex = 8
guestindices = [1, 2]
# Nodes specific configs
for guestindex in guestindices
vm_code = 'node_' + hostindex.to_s() + '_' + guestindex.to_s()
ip = '192.168.3.' + hostindex.to_s() + guestindex.to_s()
hostname = 'vm-ci-node-' + hostindex.to_s() + '-' + guestindex.to_s()
config.vm.define vm_code.dup do |node|
node.vm.network "public_network", ip: ip.dup, bridge: target_interface, netmask: "255.255.248.0"
node.vm.hostname = hostname.dup
end
end
Then I run vagrant up - no errors, but if I try to SSH to these two machines - I get strange behaviour:
node_8_1 IP address is 192.168.3.82, hostname - vm-ci-node-8-2
node_8_2 IP address is 192.168.3.82, hostname - vm-ci-node-8-2
As you see - it is same. Also there are another interface with same IP 10.0.2.15 - and it is trouble too, but it existed on previous version of config too.
I suspected that there are some Ruby references troubles so I used dup (I repeat, I'm totally new to Ruby, sorry). But it does not seem to work.
VM codes are different - node_8_1 and node_8_2, but IP and hostnames are same.
Could anybody please point me where I'm wrong?
I think the for guestindex in guestindices part is the cause of your trouble.
Try using guestindices.each do |i| or shorter (1..2).each do |i| instead.
Vagrant is mentioning this in their documentation for multi-machine provisioning, see https://www.vagrantup.com/docs/vagrantfile/tips.html#loop-over-vm-definitions:
The for i in ... construct in Ruby actually modifies the value of i for each iteration, rather than making a copy. Therefore, when you run this, every node will actually provision with the same [value].

Setting a default value in Vagrantfile if env. variable not set

I'm trying to do something like the following to set a default value if an environment variable is not set:
config.vm.box = ENV['VAGRANT_DEV_BOX'] || "ubuntu/xenial64"
Which causes the following error:
/opt/vagrant/embedded/lib/ruby/2.4.0/rubygems/version.rb:208:in `initialize': Malformed version number string debian-VAGRANTSLASH-jessie64 (ArgumentError)
The VAGRANT_DEV_BOX variable hasn't been set at this point. Confirmed like so:
server 🦄 echo $VAGRANT_DEV_BOX
server 🦄
Is it possible to do this in Ruby and/or Vagrantfile?
This is thanks to double-p on #vagrant, freenode:
<double-p> you cannot just inline ruby.. put this above vagrant-configure, like:
port = ENV["HOST_PORT"] || 8080
Vagrant.configure("2") do |config|
# Ubuntu 14.04 LTS
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 80, host: port
config.vm.provision "shell", path: "vagrant/provision.sh"
end

Vagrant virtualbox provider - provision and customize error with storagectl attach on subsequent "reload"

All - I am setting up a multi-machine environment with Vagrant and the VirtualBox provider on a MacOSX 10.9.5.
PROBLEM: I need to attach a SATA storage controller to a CentOS 7.1 guest VM to add additional vHDDs. I do this with the following customize snippet:
config.vm.define vmName = hostname do |node|
...snip...
node.vm.provider "virtualbox" do |v|
v.customize ['storagectl', :id, '--name', 'SATA Controller', '--add', 'sata']
...
This works perfectly fine on a vagrant up - the SATA controller is attached, and I can subsequently createhd and storageattach them. However - when I do a vagrant reload, the customize is being run - causing the failure error condition:
Stderr: VBoxManage: error: Storage controller named 'SATA Controller' already exists
VBoxManage: error: Details: code VBOX_E_OBJECT_IN_USE (0x80bb000c), component SessionMachine, interface IMachine, callee nsISupports
VBoxManage: error: Context: "AddStorageController(Bstr(pszCtl).raw(), StorageBus_SATA, ctl.asOutParam())" at line 1044 of file VBoxManageStorageController.cpp
Versions:
Vagrant version: 1.7.2
VirtualBox version: 4.3.28r100309
If I comment out the storagectl command prior to running the vagrant reload, then the reload succeeds correctly and there are no issues as an additional controller isn't attached. However - this isn't a sustainable solution.
Is there some option to the Vagrantfile that I haven't been able to dig up yet - to force it to NOT do a customize step? Or is this possibly a bug in the VirtualBox Vagrant provider re-running the customize steps when it shouldn't be?
~~shane
For complete reference - here is my full Vagrantfile (See the "WARNING" comments below for the customize issue):
# vi: set ft=ruby :
###
# set 'num_minions' to the number of minions you'd like built
# set 'num_disks' to the number of disks to build on the minion
# set 'disk_size' to the MB size of the disks to build for the minions
###
num_minions = 5 # number of minions to build
num_disks = 12 # number of vHDDs to attach to minions
disk_size = 256 # size (MB) of each disk to attach to minions
name_prefix = "minion" # minion name prefix to use
cur_dir = Dir.pwd
disks_dir = "#{cur_dir}/disks" # set the storage location for minion disks
int_net1 = "172.16.1" # internal net 1: first 3 octets of IP space
# NOTE "configs/minion" needs to be updated to
# match "master" IP set below - otherwise salt
# will not work
Vagrant.configure("2") do |config|
config.vm.box = "centos71"
config.vm.provider "virtualbox" do |v|
v.memory = 1024
end
config.vm.define "master-01", primary: true do |node|
node.vm.hostname = "master-01"
node.vm.network :private_network, ip: "#{int_net1}.10"
node.vm.provision "shell", inline: "echo master-01 IP set to #{int_net1}.10"
node.vm.synced_folder "~/cpelab/ceph-salt/salt/", "/srv/salt"
node.vm.synced_folder "~/cpelab/ceph-salt/pillar/", "/srv/pillar"
node.vm.provision :salt do |salt|
salt.install_master = true
salt.master_config = "configs/master"
salt.run_highstate = false
salt.master_key = 'keys/master-01.pem'
salt.master_pub = 'keys/master-01.pub'
salt.minion_config = "configs/minion"
salt.minion_key = 'keys/master-01.pem'
salt.minion_pub = 'keys/master-01.pub'
salt.seed_master = { 'dash-01' => 'keys/dash-01.pub', 'master' => 'keys/master-01.pub' }
(1..num_minions).each do |v|
vn = "#{name_prefix}-%03d" % v
salt.seed_master = { "#{vn}" => "keys/#{vn}.pub" }
end
end
end
# MINIONS with additional disk devices
(1..num_minions).each do |i|
hostname = "#{name_prefix}-%03d" % i
minion_ip = (i.to_i + 100)
config.vm.define vmName = hostname do |node|
node.vm.hostname = vmName
node.vm.network :private_network, ip: "#{int_net1}.#{minion_ip}"
node.vm.provision "shell", inline: "echo #{vmName} IP set to #{int_net1}.#{minion_ip}"
node.vm.provider "virtualbox" do |v|
############# WARNING
############# WARNING: can't "vagrant reload" - as the 'customize' snippet is
############# WARNING: re-run on reload, and you can't inject a new controller
############# WARNING: of the same type seems to be a bug in the specific
############# WARNING: provider for vagrant or my usage???
############# WARNING
v.customize ['storagectl', :id, '--name', 'SATA Controller', '--add', 'sata']
(1..num_disks).each do |disk|
diskname = File.expand_path("#{disks_dir}/#{vmName}-#{disk}.vdi")
v.customize ['createhd', '--filename', diskname, '--size', "#{disk_size}"]
v.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', disk, '--device', 0, '--type', 'hdd', '--medium', diskname]
end
end
node.vm.provision :salt do |salt|
salt.minion_config = "configs/minion"
salt.minion_key = "keys/#{vmName}.pem"
salt.minion_pub = "keys/#{vmName}.pub"
end
end
end
# setup Dashing web dashboard
config.vm.define "dash-01" do |node|
node.vm.hostname = "dash-01"
node.vm.network :private_network, ip: "#{int_net1}.11"
node.vm.provision "shell", inline: "echo dash-01 IP set to #{int_net1}.11"
node.vm.network "forwarded_port", guest: 80, host: 8080
node.vm.provision "shell", inline: "echo dash-01 port 80 forwarding: http://127.0.0.1:8080"
node.vm.synced_folder "~/cpelab/ceph-salt/salt/", "/srv/salt"
node.vm.synced_folder "~/cpelab/ceph-salt/pillar/", "/srv/pillar"
node.vm.provision :salt do |salt|
salt.minion_config = "configs/minion"
salt.minion_key = 'keys/dash-01.pem'
salt.minion_pub = 'keys/dash-01.pub'
end
end
end

vagrant sets up duplicate IP addresses; Ansible picks them up?

I've got the following Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
NUM_HOSTS = 3
def hostname(id)
"node#{id}"
end
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-7.0"
config.ssh.forward_agent = true
config.ssh.insert_key = false
config.vm.provider :virtualbox do |vb|
vb.gui = false
vb.memory = 512
vb.cpus = 1
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "vagrant_playbook.yml"
ansible.groups = {
"vagrant" => (1..NUM_HOSTS).collect { |id| hostname(id) }
}
end
NUM_HOSTS.times do |n|
id = n + 1
config.vm.define hostname(id), primary: id == 1 do |host|
host.vm.network :private_network, ip: "10.0.33.1#{id}"
end
end
end
This assigns the private addresses on enp0s8. However, it assigns duplicate IP addresses on enp0s3: 10.0.2.15. Unfortunately, Ansible seems to be picking the duplicate address up in ansible_default_ipv4 instead of the unique address, so services running on these boxes don't work as intended. So, is there a way to:
stop Vagrant from assigning duplicate IPs? (I'm using the virtualbox provider, if that helps)
change which interface ansible_default_ipv4 uses?
some other solution which I haven't thought to search for?
This is a workaround you can use in the meantime:
{{ ansible_all_ipv4_addresses | last }}
Will work assuming it's guaranteed that your ipv4 addresses for the target box will always be sorted in a predictable order.

Vagrant to deploy Salt master

I'm trying to design a relatively complex system, using Vagrant and Salt-Stack to handle control and provisioning. The basic idea is to provision a machine, called master, which runs the Salt-Stack master that all my other machines will connect to.
In a previous attempt to do this, I just had Vagrant set up a Salt minion which was instructed to install the salt master and a dns server package. But I'd like to simplify key transports by using Vagrant's facilities. So what I'd like to do is have Vagrant install a Salt master and a minion, so that the minion can install the dns server, and so that Vagrant can move my keys around for me.
Here is what master's configuration looks like, in the Vagrantfile:
config.vm.define :master do |master|
master.vm.provider "virtualbox" do |vbox|
vbox.cpus = 1
vbox.memory = 384
end
master.vm.network "private_network", ip: "10.47.94.2"
master.vm.network :forwarded_port, guest: 53, host: 53
master.vm.hostname = "master"
master.vm.provision :salt do |salt|
salt.verbose = true
salt.minion_config = "salt/master"
salt.run_highstate = true
salt.install_master = true
salt.master_config = "salt/master"
salt.master_key = "salt/keys/master.pem"
salt.master_pub = "salt/keys/master.pub"
salt.minion_key = "salt/keys/master.pem"
salt.minion_pub = "salt/keys/master.pub"
salt.seed_master = {master: "salt/keys/master.pub"}
salt.run_overstate = true
end
end
But I am getting the message:
Executing job with jid 20140403131604825601
-------------------------------------------
Execution is still running on master
Execution is still running on master
Execution is still running on master
Execution is still running on master
master:
Minion did not return
and when I look at master:/var/log/salt/minion, it's empty.
Is there an obvious error in my Vagrantfile configuration? Any hints?
I see that this has not been answered for a long time. Therefore I post my personal minimal Vagrant salt master file here. This problem occured to me once when I forgot to setup the master: localhost entry to the salt-minion configuration on the master (as default it looks for a host called salt).
Please note that the minion on the master has its own key.
This is running vagrant 1.7.2 and will install a salt master 2015.5.0
# Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "chef/centos-7.0"
# Deployment instance salt master
config.vm.define :master do |master|
master.vm.network :private_network, ip: "192.168.22.12"
master.vm.hostname = 'master'
master.vm.synced_folder "salt/roots/", "/srv/"
master.vm.provision :salt do |config|
config.install_master = true
config.minion_config = "salt/minion"
config.master_config = "salt/master"
config.minion_key = "salt/keys/minion.pem"
config.minion_pub = "salt/keys/minion.pub"
config.master_key = "salt/keys/master.pem"
config.master_pub = "salt/keys/master.pub"
config.seed_master =
{
master: "salt/keys/minion.pub"
}
config.run_highstate = true
end
end
end
Master's configuration file:
# salt/master
# empty, use only defaults
Minion's configuration file on master:
# salt/minion
master: localhost

Resources