举个例子 Vagrantfile 和你的理论 playbook2.yml 仅执行 server2 后 playbook1.yml 上 server1 ,我们将得出以下解决方案:
Vagrantfile
playbook2.yml
server2
playbook1.yml
server1
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/bionic64" config.vm.define "server1" do |server1| // # restrict scope of ansible provisioner to server1 by invoking on its class method off the constructor server1.vm.provision :ansible do |ansible| ansible.playbook = 'playbook1.yml' end end config.vm.define "server2" do |server2| // # perform similarly for server2, which executes after server1 provisioning due to the imperative ruby dsl server2.vm.provision :ansible do |ansible| ansible.playbook = 'playbook2.yml' end end config.vm.define "server3" do |server3| // end end
值得注意的是,如果您想要精确订购,您可以 vagrant up server1 然后 vagrant up server2 而不是一体化 vagrant up 。
vagrant up server1
vagrant up server2
vagrant up
基本上,在内 Vagrant.configure 有一个影响其中所有虚拟机的范围 config.vm 。您可以通过实例化将其范围限制为特定VM config.vm.define 就像你上面那样。使用实例化的对象VM config.vm.define 具有与基础相同的成员/属性 config 。
Vagrant.configure
config.vm
config.vm.define
config
请注意,如果您需要,您也可以执行以下操作:
Vagrant.configure('2') do |config| ... (1..3).each do |i| config.vm.define "server#{i}" do |server| // server.vm.provision :ansible do |ansible| ansible.playbook = "playbook#{i}.yml" end end end end
对于每服务器特定的剧本。这取决于你的确切内容 // 虽然特定于每个VM,如果你想要第三个VM的第三个playbook。
//
以下示例将执行 playbook1.yml 然后在每个服务器上执行 playbook2.yml 仅在server1上(此示例假定为 playbook1.yml 可以并行化):
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| N = 3 (1..N).each do |server_id| config.vm.define "server#{server_id}" do |server| server.vm.box = "ubuntu/bionic64" server.vm.hostname = "server#{server_id}" server.vm.network "private_network", ip: "172.28.128.25#{server_id}" server.vm.provision :shell, inline: "sudo apt install -y python" # only execute once the ansible provisioner, # when all the machines are up and ready. if server_id == N server.vm.provision :ansible do |ansible| # disable default limit to connect to all the machines # execute playbook1 on all hosts ansible.limit = "all" ansible.playbook = "playbook1.yml" ansible.compatibility_mode = "2.0" end server.vm.provision :ansible do |ansible| # limit the connection to server1 and execute playbook2 ansible.limit = "server1" ansible.playbook = "playbook2.yml" ansible.compatibility_mode = "2.0" end end end end end
此示例构建于。中提供的示例之上 技巧和窍门 , ansible-playbook 是并行化和两者的范围 ansible-playbooks 受到了限制 ansible.limit 配置选项(例如a vagrant up 将首先启动虚拟机,然后针对所有主机或主机子集一个接一个地执行剧本。
ansible-playbook
ansible-playbooks
ansible.limit
的 注意 强> : ubuntu/bionic64 (virtualbox, 20190131.0.0) 盒子有 /usr/bin/python3 安装,为了有副本和粘贴示例和使用动态库存我故意保留 server.vm.provision :shell, inline: "sudo apt install -y python" 在这个例子中 ansible-playbook (2.7.6) 不会爆炸 "/bin/sh: 1: /usr/bin/python: not found\r\n 错误(参考 如何在远程机器上处理/ usr / bin / python中没有Python解释器的python? )。例 playbook1.yml 和 playbook2.yml (出现在与目录相同的目录中) Vagrantfile ):
ubuntu/bionic64 (virtualbox, 20190131.0.0)
/usr/bin/python3
server.vm.provision :shell, inline: "sudo apt install -y python"
ansible-playbook (2.7.6)
"/bin/sh: 1: /usr/bin/python: not found\r\n
--- - hosts: all tasks: - debug: msg: 'executing on {{ inventory_hostname }}'
结果是: