I have setup a Virtual box with two VMs a) Ubuntu b) Windows 10. I have created vagrant boxes for each of these VMs from scratch. Each of the vagrant box runs good individually. But I want to launch both the VMs at once. So I created a Vagrantfile (shown below) with the help of this documentation: https://docs.vagrantup.com/v2/multi-machine/
With the following Vagrantfile, the box declared first gets launched while the other doesn't. Is there any error in my Vagrantfile?
Any solutions, hints on how to fix this problem? How do I launch both the VMs?
-----------Vagrantfile---------------
Vagrant.configure(2) do |config|
config.vm.define "linux" do |linux|
linux.vm.box = "ubuntu"
linux.vm.box_url = "/Users/xyz/Desktop/vagrant/linux_package.box"
end
config.vm.define "win" do |win|
win.vm.box = "Windows10"
win.vm.box_url = "/Users/xyz/Desktop/vagrant/win_package.box"
end
config.vm.provider "virtualbox" do |v|
v.gui = true
end
end
Output on terminal:
When linux machine is launched first, I get below message on terminal:
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
mkdir -p /vagrant
Stdout from the command:
Stderr from the command:
sudo: no tty present and no askpass program specified
Logging in to the guest (through gui mode) and making sure the vagrant user was set up like so in /etc/sudoers with the fix :
vagrant ALL=(ALL) NOPASSWD: ALL
Run visudo as root in order to edit this file.
Related
I'm trying to create a VM CentOS7 using Vagrant (2.2.3) and Virtual Box (6.0.4), on Windows 10 using the following Vagrant file
Vagrant.configure("2") do |config|
config.vm.box = "bento/centos-7"
config.vm.network "private_network", ip: "192.168.56.3"
config.vm.synced_folder "D://SharedWithVM//CentOS7-Work", "/media/sf_CentOS7-Work", type: "virtualbox"
config.vm.provider "virtualbox" do |vb|
vb.name = "Test"
end
config.vm.provision "shell", path: "./scripts/InstallGuestAdditions.sh"
end
and the InstallGuestAdditions.sh shell script is the follow ..
#!/bin/bash
curl -C - -O http://download.virtualbox.org/virtualbox/6.0.4/VBoxGuestAdditions_6.0.4.iso
sudo mkdir /media/VBoxGuestAdditions
sudo mount -o loop,ro VBoxGuestAdditions_6.0.4.iso /media/VBoxGuestAdditions
sudo sh /media/VBoxGuestAdditions/VBoxLinuxAdditions.run
rm VBoxGuestAdditions_6.0.4.iso
sudo umount /media/VBoxGuestAdditions
sudo rmdir /media/VBoxGuestAdditions
All works fine and the CentOS7 VM is created.
If I check the machine properties about shared directories I can see this
So I'm quite surprised about this path \\?\D:\SharedWithVM\CentOS7-Work.
How should I change my Vagrantfile to obtain a right path?
I've tried to connect at my CentOS 7 VM using vagrant ssh command and all works. Also the command cd /media/sf_CentOS7-Work works fine but no file or directory can be listed or shared between the two systems.
I've tried to create files or directories in Windows 10 and also in CentOS7 VM.
Any suggestion or example will be appreciated.
I know Ansible has issues running on windows. Which is why, I want to avoid using it for my host. I want to provision a local linux vm running in VirtualBox.
I was wondering if anyone can tell me if it is possible, to use vagrant to bring up two independent VMs on the same box. Then install Ansible on one of those VMs, then using SSH log into that VM. From there, use the Linux VM with Ansible as the host, to provision another Linux VM, that was created via the windows host machine. So, this is not a VM inside a VM. It is just two VMs running on windows using vagrant, then SSH to one of those VMs to use Ansible to provision the other VM.
Steps:
Vagrant VM 1 and install Ansible
Vangrant VM 2
SSH to VM 1
Use Ansible to provision VM 2 using VM 1.
Can that be done? Sorry if that sounded confusing.
There is now a new Ansible local provisioner in Vagrant 1.8.0, which you can use in your scenario.
Especially, look at "Tips and Tricks" section of the documentation, there is an exact solution (which worked for me).
Below is my Vagrantfile for this scenario (slightly different from the one in the documentation), which also solves potential problems with the ssh permissions and "executable" inventory file (if you're using Cygwin):
Vagrant.configure(2) do |config|
config.vm.synced_folder "./", "/vagrant",
owner: "vagrant",
mount_options: ["dmode=775,fmode=600"]
config.vm.define "vm2" do |machine|
machine.vm.box = "box-cutter/ubuntu1404-desktop"
machine.vm.network "private_network", ip: "172.17.177.21"
end
config.vm.define 'vm1' do |machine|
machine.vm.box = "ubuntu/trusty64"
machine.vm.network "private_network", ip: "172.17.177.11"
machine.vm.provision :ansible_local do |ansible|
ansible.provisioning_path = "/vagrant"
ansible.playbook = "provisioning/playbook.yml"
ansible.limit = "vm2"
ansible.inventory_path = "inventory"
ansible.verbose = "vvv"
ansible.install = true
end
end
end
and inventory file:
vm1 ansible_connection=local
vm2 ansible_ssh_host=172.17.177.21 ansible_ssh_private_key_file=/vagrant/.vagrant/machines/vm2/virtualbox/private_key
In order to provision a box you don't necessary need to do it using another box, in this windows scenario you could simply write your playbooks, share it to your guest and hit it with ansible-playbook using shell provisioning.
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
$script = <<SCRIPT
sudo apt-get install -y software-properties-common
sudo apt-add-repository -y ppa:ansible/ansible
sudo apt-get update
sudo apt-get install -y ansible
ansible-playbook /home/vagrant/provisioning/playbook.yml
SCRIPT
config.vm.synced_folder "./provisioning", "/home/vagrant/provisioning"
config.vm.provision "shell", inline: $script
end
The first lines will get ansible on your box then it will target the playbook that you have shared to your box and run the playbooks.
This is an example, I once used this approach to provision my working vagrant box, hope this idea can help you.
I am using ubuntu vivid with Vagrant
https://vagrantcloud.com/ubuntu/boxes/vivid64
when i do vagrant up
i get this
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Setting hostname...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
service hostname start
Stdout from the command:
Stderr from the command:
stdin: is not a tty
Failed to start hostname.service: Unit hostname.service is masked.
Is there any way to use vivid64 . i even tried
https://atlas.hashicorp.com/larryli/vivid64
but same result
Seems as though Vagrant is throwing out an error relating to the hostname... try adding this to your vagrant file:
#host.vm.hostname = "[HOSTNAMEVM]"
host.vm.provision :shell, inline: "hostnamectl set-hostname [HOSTNAMEVM]"
Of course, set [HOSTNAMEVM] to your hostname.
What we are doing here is manually asking Vagrant to provision with a specific hostname, to attempt to fix the issue with the hostname service failing to start.
If this doesn't work, a pastebin with your Vagrantfile might help us see what might be the actual cause here.
At first, try disabling the line with "hostname" on Vagrantfile.
change the line like
config.vm.hostname = "abcd"
to
# config.vm.hostname = "abcd"
I’m using Cygwin (CYGWIN_NT-6.3-WOW64) under Windows 8. I’m also running Vagrant (1.7.2) and Ansible (1.8.4). To be complete, my Virtualbox is 4.3.22.
Cygwin and Vagrant have been installed from their respective Windows install packages. I’m running Python 2.7.8 under Cygwin and used ‘pip install ansible’ to install Ansible.
All of these applications work fine in their own right. Cygwin works wonderfully; I use it as my shell all day, every day with no problems.
Vagrant and Virtualbox also work with no problems when I run Vagrant under Cygwin. Ansible works fine under Cygwin as well when I run plays or modules against the servers on my network.
The problem I run into is when I try to use Ansible to provision a Vagrant VM running locally.
For example, I vagrant up a VM and then draft a simple playbook to provision it. Following are the Vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define :drupal1 do |config|
config.vm.box = "centos65-x86_64-updated"
config.vm.hostname = "drupal1"
config.vm.network "forwarded_port", guest: 80, host: 10080
config.vm.network :private_network, ip: "192.168.56.101"
config.vm.provider "virtualbox" do |v|
v.name = "Drupal Server 1"
v.memory = 1024
end
config.vm.provision :ansible do |ansible|
ansible.playbook = "provisioning/gather_facts.yml"
end
end
and playbook:
---
- hosts: all
gather_facts: yes
However, when I run ‘vagrant provision drupal1’, I get the following error:
vagrant provision drupal1
==> drupal1: Running provisioner: ansible... PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false
ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o
ControlMaster=auto -o ControlPersist=60s' ansible-playbook
--private-key=C:/Users/mjenkins/workspace/Vagrant_VMs/Drupal1/.vagrant/machines/drupal1/virtualbox/private_key
--user=vagrant --connection=ssh --limit='drupal1' --inventory-file=C:/Users/mjenkins/workspace/Vagrant_VMs/Drupal1/.vagrant/provisioners/ansible/inventory
provisioning/gather_facts.yml PLAY [all]
GATHERING FACTS
fatal: [drupal1] => private_key_file
(C:/Users/mjenkins/workspace/Vagrant_VMs/Drupal1/.vagrant/machines/drupal1/virtualbox/private_key)
is group-readable or world-readable and thus insecure - you will
probably get an SSH failure PLAY RECAP
to retry, use: --limit #/home/mjenkins/gather_facts.retry
drupal1 : ok=0 changed=0 unreachable=1
failed=0 Ansible failed to complete successfully. Any error output
should be visible above. Please fix these errors and try again.
Looking at the error, its plainly obvious that it has something to do
with Ansible’s interpretation of my key and the file permissions on
either it or the folder its in.
Here are a few observations and steps I’ve tried:
I tried setting the permissions on the file and all the directories leading up to the file in Cygwin. That is chmod -R 700 .vagrant in the project directory. Still got the same error.
The key file is being referenced using a Windows path, not a Cygwin path (odd, though, that the file in the limit output has a Cygwin path). So I checked the permissions from the Windows side and changed it so that ‘Everyone’ has no access to .vagrant and all files/folders under it. Still got the same error.
Then I thought there might still be some problems with the file permissions/paths between my Cygwin based Ansible so I installed Python for Windows; used that pip to install Ansible, set my paths to that location, created an ansible-playbook.bat file, and ran Vagrant from a Windows cmd shell. Glad to say that tool chain worked….but I still got the same problem.
At this point I’m just about out of ideas so I turn to you, friends of Stackoverflow, for your input.
Any thoughts on solving this problem?
Your private key is very open and accessible by anyone. A check in SSH client prevents using such keys.
Try changing permissions with chmod from your cygwin or git bash, on your private and public keys.
On C:/Users/mjenkins/workspace/Vagrant_VMs/Drupal1/.vagrant/machines/drupal1/virtualbox/private_key
with chmod 700 private_key and ensure you have -rwx------ with ls -la
BAAAH! I just commented out the check in lib/ansible/runner/connection.py
Then I had to add in ansible.cfg
[ssh_connection]
control_path = /tmp
My solution to this was to override synced folder's permissions settings in the VagrantFile with the following ones:
Vagrant.configure(2) do |config|
config.vm.synced_folder "./", "/vagrant",
owner: "vagrant",
mount_options: ["dmode=775,fmode=600"]
...
I had similar issue and figured out a solution. I added following entries in my vagrant file
config.ssh.insert_key = false
config.ssh.private_key_path = "~/.vagrant.d/insecure_private_key"
and copied the insecure_private_key from my windows user folder to cygwin home as the path above. afterwards I did a
chmod 700 ~/.vagrant.d/insecure_private_key
and as a last step I removed the content of this file in cygwin home
~/.ssh/known_hosts
once I rerun the ansible-playbook command, I confirmed to add my localhost back to the known_hosts and the ssh connection worked.
truly saying it is much simpler if you understand what is happening.
Vagrant keep one folder for sharing file with host and other VM, that is /vagrant . Anything into that will be having mode 777 nothing can be done for that. sudo chmod too will not help , and you cannot change the mode.
Ansible is asking you to reduce the mode so that is not readable by group or all
so it is as simple as making a copy of the private key from
/vagrant/.vagrant/machines/yourmachine/virtualbox or any provisioner/
to may be home i.e ~ or /root
and then change chmod to 700 and use it in the inventory list in hosts file.
You could use the ansible_local provisioner for Vagrant. That will install Ansible into the VM. If you work with multiple vagrant virtual machines, then is is useful to let one be the ansible controller. This would then need the private SSH key. That can be done in the Vagrantfile with:
config.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "/home/vagrant/.ssh/id_rsa"
config.vm.provision "shell", inline: "chmod 600 /home/vagrant/.ssh/id_rsa"
Vagrant creates a development environment using VirtualBox and then provisions it using ansible. As part of the provisioning, ansible runs a reboot and then waits for SSH to come back up. This works as expected but because the vagrant machine is not being started from a "vagrant up" command the synced folders are not mounted properly when the box comes back up from the reboot.
Running "vagrant reload" fixes the machine and mounts the shares again.
Is there a way of either telling vagrant to reload the server or to do all the bits 'n bobs that vagrant would have done after a manual restart?
Simply running "sudo reboot" when SSH-ed into the vagrant box also produces the same problem.
There is no way for Vagrant to know that the machine is being rebooted during the provisioning.
If possible, the best would be to avoid rebooting here altogether. For example kernel updates should be already done when building the base box.
Another easy (but not very convenient) way is to handle it with log output or documentation, or with a wrapper script which invokes vagrant up && vagrant reload.
And finally, you could write a plugin which injects all the needed mounting etc. actions to Vagrant middleware stack after the provisioning, but you would still need to think how to let the plugin know that the machine has been booted. Other challenge is that this easily gets provider specific.
You should be able to add the filesystems to /etc/fstab to mount on boot.
Here's my example:
vagrant /vagrant vboxsf defaults 0 0
home_vagrant_src /home/vagrant/src vboxsf defaults 0 0
home_vagrant_presenter-src /home/vagrant/presenter-src vboxsf defaults 0 0
Your vagrant directory should have a .vagrant hidden directory in it, and in there you should find a path to the "synced_folders" file (in my case: /vagrant/.vagrant/machines/default/virtualbox/synced_folders).
That file should help you figure out what the labels are and their mount points:
{"virtualbox":{"/home/vagrant/src":{"guestpath":"/home/vagrant/src","hostpath":"/home/rkomorn/src","disabled":false,"__vagrantfile":true},"/home/vagrant/presenter-src":{"guestpath":"/home/vagrant/presenter-src","hostpath":"/home/presenter/src","disabled":false,"__vagrantfile":true},"/vagrant":{"guestpath":"/vagrant","hostpath":"/home/rkomorn/vagrant","disabled":false,"__vagrantfile":true}}}
It's not the easiest to read but, using python terminology, the labels appear to be the inner dictionary's keys, with / translated to _ (eg: the /home/vagrant/presenter-src key became the home_vagrant_presenter-src label).
I'm actually not sure why vagrant doesn't just use /etc/fstab for shared folders but I'm guessing there's a good reason.
Split your provisioners into two separate steps and use the vagrant-reload plugin as additional provisioner between.
Example Vagrantfile:
config.vm.provision "Step 1 - requires reboot", type: "shell", path: "scripts/part1.sh"
config.vm.provision :reload
config.vm.provision "Step 2 - happens after reboot", type: "shell", path: "scripts/part2.sh"
In case anyone else runs into this issue and finds this question like I did here's how I worked around the issue:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "..."
# create a shared folder for the top-level project directory at /vagrant
# normally already configured but for some reason it isn't on these boxes
# https://www.vagrantup.com/docs/synced-folders/virtualbox.html#automount
# http://www.virtualbox.org/manual/ch04.html#sf_mount_auto
config.vm.synced_folder ".", "/mnt/vagrant", id: "vagrant", automount: true
config.vm.provision "shell", inline: "usermod -a -G vboxsf vagrant"
config.vm.provision "shell", inline: "ln -sfT /media/sf_vagrant /vagrant"
# More settings omitted...
end
There's a few parts to this solution:
The first line assigns a specific id of vagrant to the shared folder. This is important because the automatic mount functionality in VIrtualBox uses /mnt/sf_<id> by default. It also mounts the folder at /mnt/vagrant to keep it out of the way. Ideally you'd pick a more obscure location that's present on all of your VMs or just document not to use it there.
The third line creates a symbolic link from the automatic mount location at /mnt/sf_vagrant to the usual place users expect the shared folder at /vagrant.
The second line adds the vagrant user in the virtual machine to the vboxsf group. This is necessary to access files inside /mnt/sf_vagrant because the guest utilities mount the folder with root:vboxsf ownership. They also set appropriate file and directory modes so it works fine in practice but you do need to be a member of the vboxsf group.
This solution has the following benefits:
The mount at /mnt/sf_vagrant is automatically mounted by the virtualbox guest utilities after a reboot so /vagrant should always be available.
It does not require installing plugins or using any outside tools.
It has the following drawbacks:
Potential for unexpected behavior if users find and use the /mnt/vagrant mount. That mount will only be present if the virtual machine was most recently booted / rebooted through the vagrant console client otherwise it will not be present.
It requires a relatively recent version of VirtualBox and Vagrant.
EDIT: Added -T option to ln to avoid the corner case where it creates /vagrant/sf_vagrant as a symlink.
I had a same issue. This is what I had in my /etc/fstab.
#VAGRANT-BEGIN
# The contents below are automatically generated by Vagrant. Do not modify.
vagrant_data /vagrant_data vboxsf uid=1000,gid=1000,_netdev 0 0
vagrant /vagrant vboxsf uid=1000,gid=1000,_netdev 0 0
#VAGRANT-END
So if you see fstab entry is still there, all you have to do is run sudo mount -a to trigger mount again. Or you can copy this lines.