根据给定条件不同地设置ansable连接

时间:2019-05-19 14:17:59

标签: ssh ansible connection

我有一本剧本,对于其中一位主持人,我需要的连接方式根据先前是否成功完成某些任务而有所不同。

在这种特定情况下,两个之间有一条隧道,一个将所有流量路由通过该隧道,因此一旦配置,我需要使用另一个作为跳转框来进行连接-但我可以想象很多其他情况在这里,您可能希望从修改用户/密码的简单过程中更改连接方法(在剧本中)。

如何有条件连接方法?

我不能简单地用set_fact更新,因为当我完成该任务时,ansible在开始时就已经尝试并可能无法“收集事实”,并且将无法继续。

2 个答案:

答案 0 :(得分:1)

毫无疑问,这个问题的细节在于魔鬼,但总的来说,我认为使用add_host将是您要做的最清晰的方法。您还可以基于每个任务更改connection,或针对该主机有条件地更改整个剧本的connection

- hosts: all
  connection: ssh  # <-- or whatever bootstrap connection plugin
  gather_facts: no
  tasks:
    - command: echo "do something here"
      register: the_thing

    # now, you can either switch to the alternate connection per task:
    - command: echo "do the other thing"
      connection: lxd  # <-- or whatever
      when: the_thing is success

    # OR, you can make the alternate connection the default
    # for the rest of the current playbook
    - name: switch the rest of the playbook
      set_fact:
        ansible_connection: chroot
      when: the_thing is success

    # OR, perhaps run another playbook using the alternate connection
    # by adding the newly configured host to a special group
    - add_host:
        name: '{{ ansible_host }}'
        groups:
          - configured_hosts
      when: the_thing is success

# and then running the other playbook against configured hosts
- hosts: configured_hosts
  connection: docker   # <-- or whatever connection you want
  tasks:
    - setup:

答案 1 :(得分:0)

我使用以下代码片段作为角色,并根据情况是否需要Jumphost(堡垒或代理)调用该角色。注释中还提供了一个示例。该角色可以同时添加多个主机。将以下内容放入roles/inventory/tasks/main.yml

# Description: |
#   Adds given hosts to inventory.
# Inputs:
#   hosts_info:  |
#     (mandatory)
#     List of hosts with the structure which looks like this:
#
#     - name: <host name>
#       address: <url or ip address of host>
#       groups: [] list of groups to which this host will be added.
#       user: <SSH user>
#       ssh_priv_key_path: <private key path for ssh access to host>
#       proxy: <define following structure if host should be accessed using proxy>
#         ssh_priv_key_path: <priv key path for ssh access to proxy node>
#         user: <login user on proxy node>
#         host: <proxy host address>
#
# Example Usage:
#   - include_role:
#        name: inventory
#     vars:
#       hosts_info:
#         - name: controller-0
#           address: 10.100.10.13
#           groups:
#             - controller
#           user: user1
#           ssh_priv_key_path: /home/user/.ssh/id_rsa
#         - name: node-0
#           address: 10.10.1.14
#           groups:
#             - worker
#             - nodes
#           user: user1
#           ssh_priv_key_path: /home/user/.ssh/id_rsa
#           proxy:
#             ssh_priv_key_path: /home/user/jumphost_key.rsa.priv
#             user: jumphost-user
#             host: 10.100.10.13

- name: validate inventory input
  assert:
    that:
      - "single_host_info.name is defined"
      - "single_host_info.groups is defined"
      - "single_host_info.address is defined"
      - "single_host_info.user is defined"
      - "single_host_info.ssh_priv_key_path is defined"
  loop: "{{ hosts_info }}"
  loop_control:
    loop_var: single_host_info

- name: validate inventory proxy input
  assert:
    that:
      - "single_host_info.proxy.host is defined"
      - "single_host_info.proxy.user is defined"
      - "single_host_info.proxy.ssh_priv_key_path is defined"
  when: "single_host_info.proxy is defined"
  loop: "{{ hosts_info }}"
  loop_control:
    loop_var: single_host_info

- name: Add hosts to inventory without proxy
  add_host:
    groups: "{{ single_host_info.groups | join(',') }}"
    name: "{{ single_host_info.name }}"
    host: "{{ single_host_info.name }}"
    hostname: "{{ single_host_info.name }}"
    ansible_host: "{{ single_host_info.address }}"
    ansible_connection: ssh
    ansible_ssh_user: "{{ single_host_info.user }}"
    ansible_ssh_extra_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
    ansible_ssh_private_key_file: "{{ single_host_info.ssh_priv_key_path }}"
  loop: "{{ hosts_info | json_query(\"[?contains(keys(@), 'proxy') == `false`]\") | list }}"
  loop_control:
    loop_var: single_host_info

- name: Add hosts to inventory with proxy
  add_host:
    groups: "{{ single_host_info.groups | join(',') }}"
    name: "{{ single_host_info.name }}"
    host: "{{ single_host_info.name }}"
    hostname: "{{ single_host_info.name }}"
    ansible_host: "{{ single_host_info.address }}"
    ansible_connection: ssh
    ansible_ssh_user: "{{ single_host_info.user }}"
    ansible_ssh_extra_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
    ansible_ssh_private_key_file: "{{ single_host_info.ssh_priv_key_path }}"
    ansible_ssh_common_args: >-
      -o ProxyCommand='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
      -W %h:%p -q -i {{ single_host_info.proxy.ssh_priv_key_path }}
      {{ single_host_info.proxy.user }}@{{ single_host_info.proxy.host }}'
  loop: "{{ hosts_info | json_query(\"[?contains(keys(@), 'proxy') == `true`]\") }}"
  loop_control:
    loop_var: single_host_info