如何 运行 特定流浪主机上的 ansible 剧本
How to run an ansible playbook on a specific vagrant host
我有一个创建 3 个服务器的 Vagrantfile。我有两本可靠的剧本。 playbook1 应该首先在每台服务器上执行。第二个 playbook2 只能在 server1 上执行,而不能在 server2 和 server3 上执行。
如何使用我的 Vagrantfile 管理它?
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.define "server1" do |server1|
//
end
config.vm.define "server2" do |server2|
//
end
config.vm.define "server3" do |server3|
//
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook1.yml"
end
end
以上在所有服务器上执行playbook1。如何为 playbook2.yml 添加配置以仅在 server1 和 AFTER playbook1 上执行?
鉴于您的示例 Vagrantfile
和理论上的 playbook2.yml
在 server1
上 playbook1.yml
之后仅在 server2
上执行,我们将得出以下解决方案:
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.configure
内有一个范围影响 config.vm
内的所有虚拟机。您可以像上面那样通过 config.vm.define
实例化来将其范围限制在特定的 VM 中。使用 config.vm.define
实例化的对象 VM 与基础 config
.
具有相同的 members/attributes
请注意,如果需要,您也可以这样做:
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 的第三个剧本。
下面的示例将首先在每个服务器上执行 playbook1.yml
,然后仅在服务器 1 上执行 playbook2.yml
(此示例假设 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
此示例建立在 Tips and Tricks 中提供的示例之上,ansible-playbook
是并行化的并且两个 ansible-playbooks
的范围都受限于 ansible.limit
配置选项(例如 vagrant up
将首先启动虚拟机,然后对所有主机或主机子集一个接一个地执行剧本)。
注意: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
错误而爆炸(参考 How do I handle python not having a Python interpreter at /usr/bin/python on a remote machine?)。示例 playbook1.yml
和 playbook2.yml
(与 Vagrantfile
在同一目录中):
---
- hosts: all
tasks:
- debug:
msg: 'executing on {{ inventory_hostname }}'
结果:
我有一个创建 3 个服务器的 Vagrantfile。我有两本可靠的剧本。 playbook1 应该首先在每台服务器上执行。第二个 playbook2 只能在 server1 上执行,而不能在 server2 和 server3 上执行。
如何使用我的 Vagrantfile 管理它?
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.define "server1" do |server1|
//
end
config.vm.define "server2" do |server2|
//
end
config.vm.define "server3" do |server3|
//
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook1.yml"
end
end
以上在所有服务器上执行playbook1。如何为 playbook2.yml 添加配置以仅在 server1 和 AFTER playbook1 上执行?
鉴于您的示例 Vagrantfile
和理论上的 playbook2.yml
在 server1
上 playbook1.yml
之后仅在 server2
上执行,我们将得出以下解决方案:
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.configure
内有一个范围影响 config.vm
内的所有虚拟机。您可以像上面那样通过 config.vm.define
实例化来将其范围限制在特定的 VM 中。使用 config.vm.define
实例化的对象 VM 与基础 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 的第三个剧本。
下面的示例将首先在每个服务器上执行 playbook1.yml
,然后仅在服务器 1 上执行 playbook2.yml
(此示例假设 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
此示例建立在 Tips and Tricks 中提供的示例之上,ansible-playbook
是并行化的并且两个 ansible-playbooks
的范围都受限于 ansible.limit
配置选项(例如 vagrant up
将首先启动虚拟机,然后对所有主机或主机子集一个接一个地执行剧本)。
注意: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
错误而爆炸(参考 How do I handle python not having a Python interpreter at /usr/bin/python on a remote machine?)。示例 playbook1.yml
和 playbook2.yml
(与 Vagrantfile
在同一目录中):
---
- hosts: all
tasks:
- debug:
msg: 'executing on {{ inventory_hostname }}'
结果: