问题
Purpose
I want ansible to provision virtual box vm's on my windows 8 machine [via Vagrant]. Everything needs to run locally and since Ansible doesn't run on Windows, I bootstrap a debian vm with ansible as the control machine. This code served as an example. After struggling with the system I got it somewhat working, but not completely (although ansible doesn't tell me).
Question
What configuration is required for a multi-machine setup using ansible [in a vm], vagrant and virtualbox [on windows host] if we want:
ssh acces from the host machine to the ansible-vm as well as all the slaves
ssh acces from the ansible-vm to all the slaves
being able to shield the multi-machine network from the host's network, if possible
Problem
Running ansible -m ping -all -i path-to-hosts
yields ssh errors. It seems ansible tries to reach the machines named web1 and db1, but can't find such hosts.
ESTABLISH CONNECTION FOR USER: vagrant REMOTE_MODULE ping ESTABLISH CONNECTION FOR USER: vagrant REMOTE_MODULE ping EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'ConnectTimeout=10', 'web1', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1398362619.41-142470238612762 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1398362619.41-142470238612762 && echo $HOME/.ansible/tmp/ansible-tmp-1398362619.41-142470238612762'"] EXEC previous known host file not found for web1 EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'ConnectTimeout=10', 'db1', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1398362619.41-4982781019922 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1398362619.41-4982781019922 && echo $HOME/.ansible/tmp/ansible-tmp-1398362619.41-4982781019922'"] EXEC previous known host file not found for db1 web1 | FAILED => SSH encountered an unknown error. The output was: OpenSSH_6.0p1 Debian-4, OpenSSL 1.0.1e 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: auto-mux: Trying existing master debug1: Control socket "/home/vagrant/.ansible/cp/ansible-ssh-web1-22-vagrant" does not exist debug2: ssh_connect: needpriv 0 ssh: Could not resolve hostname web1: Name or service not known
db1 | FAILED => SSH encountered an unknown error. The output was: OpenSSH_6.0p1 Debian-4, OpenSSL 1.0.1e 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: auto-mux: Trying existing master debug1: Control socket "/home/vagrant/.ansible/cp/ansible-ssh-db1-22-vagrant" does not exist debug2: ssh_connect: needpriv 0 ssh: Could not resolve hostname db1: Name or service not known
Code
The following code tries to provision 1. ansible-master: the control machine running ansible 1. db1: a database server 1. web1: a web server
Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "wheezy64"
config.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/debian-70rc1-x64-vbox4210.box"
config.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=777','fmode=666']
config.vm.network :public_network
config.vm.provider "virtualbox" do |v|
v.customize [
"modifyvm", :id,
"--groups", "/Vagrant/Ansible",
# "--natdnshostresolver1", "on"
]
end
config.vm.define :ansiblemaster do |ansiblemaster|
# ansiblemaster.vm.network :private_network, ip: "192.168.111.101"
ansiblemaster.vm.hostname = "ansiblemaster"
# ansiblemaster.vm.network :forwarded_port, guest: 80, host: 8080
ansiblemaster.ssh.forward_agent = true
ansiblemaster.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", 512]
vb.customize ["modifyvm", :id, "--name", "ansible-master"]
vb.name = "ansiblemaster"
end
ansiblemaster.vm.provision :shell, :inline =>
"if [[ ! -f /apt-get-run ]]; then sudo apt-get update && sudo touch /apt-get-run; fi"
ansiblemaster.vm.provision :shell do |sh|
sh.path = "provision.sh"
sh.args = "./ansible provisioning/site.yml provisioning/hosts/dev_hosts"
end
end
config.vm.define :web1 do |slave|
slave.vm.hostname = "web1"
# slave.vm.network :private_network, ip: "192.168.111.201"
slave.vm.synced_folder "./src", "/var/www/site", id: "proj-root"
slave.vm.provider :virtualbox do |vb|
vb.name = "web1"
vb.customize ["modifyvm", :id, "--memory", "512"]
end
end
config.vm.define :db1 do |slave|
slave.vm.hostname = "db1"
#slave.vm.network :private_network, ip: "192.168.111.202"
slave.vm.provider :virtualbox do |vb|
vb.name = "db1"
vb.customize ["modifyvm", :id, "--memory", "512"]
end
end
end
Provision.sh
#!/bin/bash
ANSIBLE_DIR=$1
ANSIBLE_PLAYBOOK=$2
ANSIBLE_HOSTS=$3
TEMP_HOSTS="/tmp/ansible_hosts"
if [ ! -f /vagrant/$ANSIBLE_PLAYBOOK ]; then
echo "Cannot find Ansible playbook"
exit 1
fi
if [ ! -f /vagrant/$ANSIBLE_HOSTS ]; then
echo "Cannot find Ansible hosts"
exit 2
fi
if [ ! -d $ANSIBLE_DIR ]; then
echo "Updating apt cache"
apt-get update
echo "Installing Ansible dependencies and Git"
apt-get install -y git python-yaml python-paramiko python-jinja2
echo "Cloning Ansible"
git clone git://github.com/ansible/ansible.git ${ANSIBLE_DIR}
fi
cd ${ANSIBLE_DIR}
cp /vagrant/${ANSIBLE_HOSTS} ${TEMP_HOSTS} && chmod -x ${TEMP_HOSTS}
echo "Running Ansible"
echo "dir is nu: " $(pwd)
source hacking/env-setup
echo "source ${ANSIBLE_DIR}/hacking/env-setup" >> /home/vagrant/.bashrc
ansible-playbook /vagrant/${ANSIBLE_PLAYBOOK} --inventory-file=${TEMP_HOSTS} --connection=local
rm ${TEMP_HOSTS}
provsioning/hosts/dev_hosts
[webservers]
web1
[dbservers]
db1
回答1:
To answer my own question: the problem was resolved by upgrading ansible and importing the ssh keys of the other machines in Provision.sh
.
# fix permissions on private key file
chmod 600 /home/vagrant/.ssh/id_rsa
# add web/database hosts to known_hosts (IP is defined in Vagrantfile)
ssh-keyscan -H 192.168.51.4 >> /home/vagrant/.ssh/known_hosts
ssh-keyscan -H 192.168.52.4 >> /home/vagrant/.ssh/known_hosts
chown vagrant:vagrant /home/vagrant/.ssh/known_hosts
# reload ssh in order to load the known hosts
/etc/init.d/ssh reload
回答2:
Thats a really long question problem. Ansible cant figure out the dns "ssh: Could not resolve hostname web1: Name or service not known"
Option 1
I like to simplify i boot my vagrant vm with static ip vm.network :private_network, ip: "xxx.xxx.xxx.xxx" and i edit my ansible host file
provsioning/hosts/dev_hosts
[webservers]
web1 ansible_ssh_host=xxx.xxx.xxx.xxx
[dbservers]
db1 ansible_ssh_host=xxx.xxx.xxx.yyy
Option 2
Use DNS or hostsfile
Hope that helps
回答3:
Using "normal" Ansible modules to manage Windows boxes isn´t possible. Instead you have to use one of the windows modules. That´s the same for ping. It tries to connect via SSH to the Windows box, which doesn´t work.
Like skinnedknuckles already said, Ansible uses native Powershell remoting (and WinRM) instead of SSH to communicate with a Windows machine. So the win_ping module is the right way to do a ping with Ansible onto a Windows box:
ansible -m win_ping -all -i path-to-hosts
I assume you prepared your Windows 8 VM, like the docs are describing!?! If not, there´s this blog post explaining how to do all the steps incl. Vagrant setup with winrm
connectivity in quite compact form.
来源:https://stackoverflow.com/questions/23297187/multi-machine-ansible-setup-with-vagrant-on-windows