使用 delegate_to

时间:2021-05-03 14:05:10

标签: ansible

场景是:我有几个服务在多个主机上运行。有一项特殊服务 - 反向代理/负载均衡器。任何服务都需要在运行 rp/lp 服务的主机上配置该特殊服务。在安装/更新/删除一个带有Ansible角色的随机服务时,我需要调用特定主机上的ReverseProxy角色来配置对应的vhost。

目前,我调用反向代理角色中的特定任务文件,通过 include_role 服务添加或删除虚拟主机并设置一些变量(非常简单的示例,没有服务和库存特定变量)。

- name: "Configure ReverseProxy"
  include_role:
    name: reverseproxy
    tasks_from: vhost_add
    apply:
      delegate_to: "{{ groups['reverseproxy'][0] }}"
  vars:
    reverse_proxy_url: "http://{{ ansible_fqdn }}:{{ service_port }}/"
    reverse_proxy_domain: "sub.domain.tld"

我有三个问题。

  • 我知道,在角色和不同主机之间构建这种依赖关系并不是一个好主意。我不知道更好的方法,特别是如果您考虑在创建 vhost 后需要做一些额外事情的情况(例如,通过 REST API 配置服务,这需要外部 fqdn)。如果有两个带有“后端”服务和“反向代理”服务的独立剧本,那么我需要第三本剧本来配置“挂起”服务。此外,我不确定是否可以在反向代理角色中检索正确的后端 URL(仅考虑 HTTP 方案或路径)。这听起来并不容易,或者?
  • 早些时候,我有单独的角色来向反向代理添加/删除虚拟主机。这个角色没有依赖关系,但我需要复制几个默认值、模板和变量等,这也不好。然后我将其更改为单一角色。当然 - 在我看来,这并不是真正的“角色”应该是什么。角色类似于“网络服务器”或“反向代理”(一种状态)。但不是像“add_vhost_to_reverseproxy”(动词)这样的东西。这有点像剧本 - 但是通过角色调用参数化剧本是个好主意/可能吗?主要问题是,reverseproxy 的状态是清单中所有服务的总和。
  • 对于单个包含的角色,包括它,也会启动所有依赖角色(配置自定义、防火墙等)。尽管如此,在那种情况下我发现,代表团没有使用受托东道主的事实。

我使用以下示例进行了测试 - 库存:

all:
  hosts:
    server1:
      my_var: a
    server2:
      my_var: b
  children:
    service:
      hosts:
        server1:
    reverseproxy:
      hosts:
        server2:

以及将 role-a 分配给组 webserver 的剧本。 role-a 有一个类似的任务:

- block:
    - setup:
    - name: "Include role b on delegated {{ groups['reverseproxy'][0] }}"
      include_role:
        name: role-b
  delegate_to: "{{ groups['reverseproxy'][0] }}"
  delegate_facts: true # or false or omit - it has no effect on Ansible 2.9 and 2.10

而在角色-b 中只输出库存的 my_var 才会输出

TASK [role-b : My_Var on server1] *******************
ok: [server1 -> <ip-of-server2>] => 
  my_var: a

我说,应该在 role-b 上运行的 server2 具有 server1 的事实。所以 - 配置“反向代理”服务是在“后端”服务的上下文中完成的。这还会有其他几个问题 - 当你考虑防火墙依赖等时。我可以通过使用标签来避免这种情况 - 但是我不仅需要使用服务的标签运行剧本,还需要使用我想要的所有标签配置,并且我不能再在还包含其他角色的角色中使用 include_tasks 和 args-apply-tags(标签将应用于所有子任务......)。我想念诸如 include_role 之类的东西,但只有特定标签或忽略依赖项。这不是错误,但在 delegate_to 的情况下可能会产生副作用。

我不太确定,有什么问题吗?问题是 - 在 Ansible 中处理主机和角色之间的依赖关系的好方法是什么 - 特别是当它们不在同一主机上时?

1 个答案:

答案 0 :(得分:0)

我确定我没有完全理解您的确切问题,但是当我处理负载均衡器时,我使用了一个模板。所以这是我的disable_workers剧本:

---
- hosts: "{{ ip_list | default( 'jboss' ) }}"
  tasks:
  - name: Tag JBoss service as 'disabled'
    ec2_tag:
      resource: "{{ ec2_id }}"
      region: "{{ region }}"
      state: present
      tags:
        State: 'disabled'
    delegate_to: localhost

  - action: setup

- hosts: httpd
  become: yes
  become_user: root
  vars:
    uriworkermap_file: "{{ httpd_conf_dir }}/uriworkermap.properties"
  tasks:
 
  - name: Refresh inventory cache
    ec2_remote_facts:
      region: "{{ region }}"
    delegate_to: localhost

  - name: Update uriworkermap.properties
    template:
      backup: yes
      dest: "{{ uriworkermap_file }}"
      mode: 0644
      src: ./J2/uriworkermap.properties.j2

不要指望这会按原样工作。 AWS 主机上是 v1.8,情况可能已经改变。

但重点是在每个主机上为该主机的所需状态(启用、禁用、停止)设置用户定义的事实,重新加载事实,然后运行使用这些事实的 Jinja 模板。