Ansible 将任务的当前主机用作变量

Ansible use current hosts for task as a variable

我有以下连接到记录器服务 haproxies 并耗尽第一个记录器 VM 的代码。

然后在一个单独的任务中连接到主机的记录器列表,其中第一个主机被耗尽并重新加载服务。

- name: Haproxy Warmup
  hosts: role_max_logger_lb
  tasks:
    - name: analytics-backend 8300 range
      haproxy: 'state=disabled host=maxlog-rwva1-{{ env }}-1.example.com backend=analytics-backend socket=/var/run/admin.sock'
      become: true
      when: warmup is defined and buildnum is defined
    - name: logger-backend 8200
      haproxy: 'state=disabled host=maxlog-rwva1-prod-1.example.com :8200 backend=logger-backend socket=/var/run/admin.sock'
      become: true
      when: warmup is defined and buildnum is defined

- name: Warmup Deploy
  hosts: "role_max_logger"
  serial: 1
  tasks:
    - shell: pm2 gracefulReload max-logger
      when: warmup is defined and buildnum is defined
    - pause: prompt="First host has been deployed to. Please verify the logs before continuing. Ctrl-c to exit, Enter to continue deployment."
      when: warmup is defined and buildnum is defined

此代码非常糟糕,当我尝试将其扩展为使用多个 haproxies 对多个服务进行滚动重启时无法正常工作。我需要以某种方式从 haproxy 后端耗尽所有应用程序 VM 的 33%,然后连接到另一个列表并在那里执行 33% 的重启过程。然后在排空列表的 34-66% 恢复,然后在重启列表的 34% 和 66% 恢复。

- name: 33% at a time drain
  hosts: "role_max_logger_lb"
  serial: "33%"
  tasks:
    - name: analytics-backend 8300 range
      haproxy: 'state=disabled host=maxlog-rwva1-prod-1.example.com 
      backend=analytics-backend socket=/var/run/admin.sock'
      become: true
      when: warmup is defined and buildnum is defined
    - name: logger-backend 8200
      haproxy: 'state=disabled host=maxlog-rwva1-prod-1.example.com:8200 backend=logger-backend socket=/var/run/admin.sock'
      become: true
      when: buildnum is defined and service is defined

- name: 33% at a time deploy
  hosts: "role_max_logger"
  serial: "33%"
  tasks:
    - shell: pm2 gracefulReload {{ service }}
      when: buildnum is defined and service is defined
    - pause: prompt="One third of machines in the pool have been deployed to. Enter to continue"

我可以在 Chef 中更轻松地做到这一点,只需查询 Chef 服务器以获取在给定角色中注册的所有节点,然后真正执行我的所有逻辑 ruby。如果重要的话,我在这里调用的主机列表实际上是从我的 Chef 服务器中提取的,并以 json.

的形式输入

我不知道这样做的正确 Ansible 方法是什么,而不能放入任意脚本来完成所有肮脏的工作。

我在想也许我可以在部署下的 Ansible 中的 shell 命令中做一些像这样超级 hacky 的事情,如果有办法拉出正在运行的当前主机,这可能会起作用从主机列表中处理出来,就像 Chef.

中 node['fqdn'] 的 Ansible 等价物
ssh maxlog-lb-rwva1-food-1.example.com 'echo "disable server logger-backend/maxlog-rwva1-food-1.example.com:8200" | socat stdio /run/admin.sock'

或者也许有一种方法可以将我的整个内容打包成连续的 33%,并包括执行某些操作的子剧。有点像这样,但我还是不知道如何在子播放中正确传递我的应用程序服务器的第三个列表

- name: Deployer
 hosts: role_max_logger
 serial: "33%"
   - include: drain.yml
   - include: reboot.yml

基本上我不知道我在做什么,我可以想出很多方法来尝试做到这一点,但它们看起来都很糟糕而且过于迟钝。如果我要沿着这些 hacky 道路走下去,我可能最好只写一个大 shell 脚本或实际 ruby 来做到这一点。

为此阅读了大量官方 Ansible 文档,其中的示例过于简化,并不真正符合我的情况。 特别是这里负载均衡器与应用程序服务器位于同一主机上。

- hosts: webservers
  serial: 5
  tasks:
  - name: take out of load balancer pool
    command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
    delegate_to: 127.0.0.1

http://docs.ansible.com/ansible/playbooks_delegation.html

我想我的问题是:

Is there an Ansible equivalent of Chef's node['fqdn'] to use the currently being processed host as a variable

ansible_hostnameansible_fqdn(均取自实际机器设置)或 inventory_hostname(在清单文件中定义),具体取决于您要使用哪个。

正如您正确指出的那样,您需要为此任务使用委派。

这里有一些伪代码供您开始使用:

- name: 33% at a time deploy
  hosts: role_max_logger
  serial: 33%
  tasks:
    - name: take out of lb
      shell: take_out_host.sh --name={{ inventory_hostname }}
      delegate_to: "{{ item }}"
      with_items: "{{ groups['role_max_logger_lb'] }}"
    - name: reload backend
      shell: reload_service.sh
    - name: add back to lb
      shell: add_host.sh --name={{ inventory_hostname }}
      delegate_to: "{{ item }}"
      with_items: "{{ groups['role_max_logger_lb'] }}"

我假设组 role_max_logger 定义了具有要重新加载的后端服务的服务器,组 role_max_logger_lb 定义了具有负载平衡器的服务器。

这个游戏从 role_max_logger 中获取所有主机,将它们分成 33% 的批次;然后对于批处理中的每个主机,它在每个负载均衡器上执行 take_out_host.sh,将当前后端主机名作为参数传递;在负载均衡器上禁用当前批次中的所有主机后,重新加载后端服务;之后,像第一个任务一样将主机添加回 LB。然后对每个批次重复此操作。