在 hosts.yaml 文件中创建的分组中执行剧本

Executing playbooks in groupings created in hosts.yaml file

Ansible 版本:2.8.3

我有以下 hosts.yaml 文件用于 Ansible

我有一些应用程序想同时部署在 rp_1rp_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_1rp_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 }}!"

进一步阅读: