在 hosts.yaml 文件中创建的分组中执行剧本
Executing playbooks in groupings created in hosts.yaml file
Ansible 版本:2.8.3
我有以下 hosts.yaml
文件用于 Ansible
我有一些应用程序想同时部署在 rp_1 和 rp_2[=22 上=]
---
all:
vars:
docker_network_name: devopsNet
http_protocol: http
http_host: ansiblenode01_new.example.com
http_url: "{{ http_protocol }}://{{ http_host }}:{{ http_port }}/{{ http_context }}"
hosts:
ansiblenode01_new.example.com:
ansiblenode02_new.example.com:
children:
##################################################################
rp_1:
children:
httpd:
hosts:
ansiblenode01_new.example.com:
vars:
number_of_tools: 6
outside_port: 443
jenkins:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 4444
http_context: jenkins
artifactory:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 8000
http_context: artifactory
rp_2:
children:
httpd:
hosts:
ansiblenode02_new.example.com:
vars:
number_of_tools: 4
outside_port: 7090
jenkins:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 7990
http_context: jenkins
artifactory:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 8000
http_context: artifactory
以下 python 包装器脚本在循环中调用 ansible-playbook 来部署应用程序
#!/usr/bin/python
import yaml
import os
import getpass
with open('hosts.yaml') as f:
var = yaml.load(f)
sudo_pass = getpass.getpass(prompt="Please enter sudo password: ")
# Running individual ansible-playbook deployment for each application listed and uncommented under 'applications' object.
for network in var['all']['children']:
for app in var['all']['children'][network]['children']:
os.system('ansible-playbook deploy.yml --extra-vars "application='+app+' ansible_sudo_password='+sudo_pass+'"')
我认识到的问题是 Ansible 和 Python 都将使用 hosts.yaml 文件,但不会按照我认为的方式使用它,因为我对 Ansible 不太熟悉。
hosts.yaml 是以 Ansible 要求的格式编写的。
Python 脚本将打开 yaml 文件,从中创建一个字典,然后单步执行字典并查找要传递给命令行调用的应用程序名称。问题是 Python 仅将应用程序的名称作为字符串传递给 ansible-playbook
的调用,字典结构显然没有传递,因此 Ansible 然后将打开 hosts.yaml
文件,但它所做的只是遍历 yaml 并查找在调用 ansible-playbook
时作为参数传递的应用程序名称的第一次出现,完全无视我在 yaml 中创建的结构文件。
所以基本上只有 yaml 文件中的 rp_1
组会被执行,因为 Ansible,我认为从上到下读取 yaml 并在第一次出现时停止,因此 [=18 的全部或部分=] 如果组包含所有或部分与 rp_1
相同的应用程序,Ansible 将永远不会处理该组,因此 运行 相同的部署两次。
有没有一种方法可以调用 Ansible 或一些方法来设置 playbook,以便 Ansible 在我的主机文件中识别出我想要的网络(rp_1
、rp_2
)设置并执行我在 yaml 文件中创建的分组中的剧本?
Ansible 已经内置了这个。您不需要包装器脚本。
要运行 hosts.yaml
中所有主机上的 deploy.yml
剧本(顺便说一下,这称为“清单”。)请执行以下操作:
ansible-playbook -i hosts.yaml deploy.yml -bK
要在 rp_1
上仅 运行,请执行以下操作:
ansible-playbook -i hosts.yaml deploy.yml --limit rp_1 -bK
-b
使 ansible 变成 root
-K
会让 ansible 要求输入密码变成 root
-i <file>
指定库存文件
--limit <host/group>
将执行限制在某些主机或组,您也可以添加多个,以逗号分隔的列表(例如,pr_1,rp_2
)
您还可以在剧本中指定 hosts/groups 的列表,如下所示:
- name: do whatever you like
hosts:
- rp_1
- rp_2
become: yes
tasks:
- debug:
msg: "I'm running on {{ inventory_hostname }}!"
进一步阅读:
Ansible 版本:2.8.3
我有以下 hosts.yaml
文件用于 Ansible
我有一些应用程序想同时部署在 rp_1 和 rp_2[=22 上=]
---
all:
vars:
docker_network_name: devopsNet
http_protocol: http
http_host: ansiblenode01_new.example.com
http_url: "{{ http_protocol }}://{{ http_host }}:{{ http_port }}/{{ http_context }}"
hosts:
ansiblenode01_new.example.com:
ansiblenode02_new.example.com:
children:
##################################################################
rp_1:
children:
httpd:
hosts:
ansiblenode01_new.example.com:
vars:
number_of_tools: 6
outside_port: 443
jenkins:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 4444
http_context: jenkins
artifactory:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 8000
http_context: artifactory
rp_2:
children:
httpd:
hosts:
ansiblenode02_new.example.com:
vars:
number_of_tools: 4
outside_port: 7090
jenkins:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 7990
http_context: jenkins
artifactory:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 8000
http_context: artifactory
以下 python 包装器脚本在循环中调用 ansible-playbook 来部署应用程序
#!/usr/bin/python
import yaml
import os
import getpass
with open('hosts.yaml') as f:
var = yaml.load(f)
sudo_pass = getpass.getpass(prompt="Please enter sudo password: ")
# Running individual ansible-playbook deployment for each application listed and uncommented under 'applications' object.
for network in var['all']['children']:
for app in var['all']['children'][network]['children']:
os.system('ansible-playbook deploy.yml --extra-vars "application='+app+' ansible_sudo_password='+sudo_pass+'"')
我认识到的问题是 Ansible 和 Python 都将使用 hosts.yaml 文件,但不会按照我认为的方式使用它,因为我对 Ansible 不太熟悉。
hosts.yaml 是以 Ansible 要求的格式编写的。
Python 脚本将打开 yaml 文件,从中创建一个字典,然后单步执行字典并查找要传递给命令行调用的应用程序名称。问题是 Python 仅将应用程序的名称作为字符串传递给 ansible-playbook
的调用,字典结构显然没有传递,因此 Ansible 然后将打开 hosts.yaml
文件,但它所做的只是遍历 yaml 并查找在调用 ansible-playbook
时作为参数传递的应用程序名称的第一次出现,完全无视我在 yaml 中创建的结构文件。
所以基本上只有 yaml 文件中的 rp_1
组会被执行,因为 Ansible,我认为从上到下读取 yaml 并在第一次出现时停止,因此 [=18 的全部或部分=] 如果组包含所有或部分与 rp_1
相同的应用程序,Ansible 将永远不会处理该组,因此 运行 相同的部署两次。
有没有一种方法可以调用 Ansible 或一些方法来设置 playbook,以便 Ansible 在我的主机文件中识别出我想要的网络(rp_1
、rp_2
)设置并执行我在 yaml 文件中创建的分组中的剧本?
Ansible 已经内置了这个。您不需要包装器脚本。
要运行 hosts.yaml
中所有主机上的 deploy.yml
剧本(顺便说一下,这称为“清单”。)请执行以下操作:
ansible-playbook -i hosts.yaml deploy.yml -bK
要在 rp_1
上仅 运行,请执行以下操作:
ansible-playbook -i hosts.yaml deploy.yml --limit rp_1 -bK
-b
使 ansible 变成root
-K
会让 ansible 要求输入密码变成root
-i <file>
指定库存文件--limit <host/group>
将执行限制在某些主机或组,您也可以添加多个,以逗号分隔的列表(例如,pr_1,rp_2
)
您还可以在剧本中指定 hosts/groups 的列表,如下所示:
- name: do whatever you like
hosts:
- rp_1
- rp_2
become: yes
tasks:
- debug:
msg: "I'm running on {{ inventory_hostname }}!"
进一步阅读: