인벤토리를 지정하지 않고 호스트를 직접 지정하지 않고 Ansible을 실행하는 방법은 무엇입니까?


80

(ANSIBLE_HOST)를 통해 인벤토리 파일을 지정하지 않고 Python에서 Ansible을 실행하고 싶습니다.

ansible.run.Runner(
  module_name='ping',
  host='www.google.com'
)

실제로 패브릭에서 쉽게 할 수 있지만 파이썬에서 어떻게할지 궁금합니다. 반면에 Python 용 Ansible API 문서는 실제로 완전하지 않습니다.

답변:


176

놀랍게도 트릭은 ,

# Host and IP address
ansible all -i example.com,
ansible all -i 93.184.216.119,

또는

# Requires 'hosts: all' in your playbook
ansible-playbook -i example.com, playbook.yml

앞의 호스트 매개 변수 ,는 호스트 이름 또는 IPv4 / v6 주소 일 수 있습니다.


1
Ansible 1.9.1에서 ansible-playbook을 호출 할 때 명령 줄에서 "all"을 제거하고 playbook.yml에 그대로 둡니다. 이것이 정답입니다. "ansible-playbook -i example.com, playbook.yml"
PinoSan

1
그렇다면 어떤 서버에서든 작동하도록 플레이 북에서 "호스트"로 무엇을 설정해야합니까?
azmeuk azmeuk

2
플레이 북의 @azmeuk, "호스트 : 모두"가 제대로 작동합니다. 일반적으로 그런 다음 명령 줄에서 -i 또는 --limit를 사용하여 호스트를 지정합니다.
Dave

플레이 북에 서로 다른 호스트 / ip에 대한 연결이있는 두 단계가있는 경우 어떻게됩니까? 하나의 섹션을 여러 IP에 대해 다시 실행하는 것이 아니라 다른 IP에 대해 2 개의 다른 섹션을 실행한다는 의미입니까?
openCivilisation

1
아마도 파이썬 프로그래머에게는 그렇게 놀랍지 않을 것입니다.
x-yuri

53

이 질문이 정말 오래되었다는 것을 알고 있지만이 작은 트릭이 도움이 필요한 미래의 사용자에게 도움이 될 것이라고 생각합니다.

ansible-playbook -i 10.254.3.133, site.yml

로컬 호스트에 대해 실행하는 경우 :

ansible-playbook -i localhost, --connection=local site.yml

트릭은 IP 주소 / DNS 이름 뒤에 쉼표를 따옴표 안에 넣고 hosts: all플레이 북에 ' '가 필요하다는 것 입니다.

이것이 도움이되기를 바랍니다.


6
그만한 가치가 있기 때문에 따옴표는 여기에서 작동하지 않습니다. 당신이 사용하는 경우 'localhost,'또는 localhost,두 경우 모두 ansible-playbook쉘에서 같은 주장을 받게됩니다. 그리고 'localhost',같은 방식으로 평가할 것입니다 (여기서 핵심은 따옴표가 명령에 인수를 전달하기 전에 쉘에 의해 해석된다는 것입니다).
larsks

7
이것은 효과가 있지만 Merlin의 턱수염의 이름에서 ansible의 허용 가능한 행동은 왜입니까?! 사람들이 이것을 얼마나 정확히 알 것으로 예상됩니까? 나는 머리를 찢어서 말한 수정을 찾았다.
ffledgling dec. 07

1
내가 늦었 음을 알고 있지만 귀하의 의견을 우연히 발견하고 여기에 통찰력을 제공하고 싶었습니다. 이것이 작동하는 이유는 -i 플래그가 INI 파일, Ansible-valid 인벤토리 실행 파일 또는 Ansible 인벤토리 플러그인에서 처리 할 수있는 임의의 문자열 일 수있는 유효한 인벤토리 대상을 전달하도록 요구하기 때문입니다. 쉼표로 구분 된 호스트 목록을 가져와이 정보를 사용하여 알 수없는 호스트에서 임시 명령을 실행할 수 있도록 즉석 인벤토리를 생성하는 "host_list"라는 Ansible 플러그인이 있습니다. 이 플러그인은 기본적으로 Ansible에 포함되어 있습니다.
Héctor Luaces Novo

hosts: all한 번에 하나의 호스트에서만 실행하려고 할 때 플레이 북을 사용하는 것이 약간 위험하다고 생각합니다 . 동료는 -i. 이것은 좋은 해결책이지만 더 안전한 것을 계속 찾고 있습니다. 그럼에도 불구하고 ... 검색
멋있지 리

7

다음과 같이 할 수 있습니다.

hosts = ["webserver1","webserver2"]

webInventory = ansible.inventory.Inventory(hosts)

webPing = ansible.runner.Runner(
    pattern='webserver*',
    module_name='ping',
    inventory = webInventory
).run()

호스트에있는 것이 무엇이든 인벤토리가되고 패턴으로 검색 할 수 있습니다 (또는 "모두"수행).


예를 들어 ec2 모듈은 localhost (127.0.0.1) 및 local_action으로 다시 호출되어야합니다. 감사합니다
kamiseq

신경 쓰지 마세요. 내 질문에 답합니다. :-) runner = ansible.Runner (module_name = "ec2_group", complex_args = {}, forks = paralel, # private_key_file = "~ / .ssh / office.pem", inventory = Inventory ([ "127.0.0.1"]), transport = "local") return runner.run ()
kamiseq

6

제 경우에는 hosts: all플레이 북에 포함 하고 싶지 않았습니다. 누군가가 플레이 북을 실행하고 포함하는 것을 잊어 버리면 나쁠 것이기 때문입니다.-i 10.254.3.133,

이것은 내 솔루션이었습니다 (ansible 2.6).

$ ansible-playbook myplaybook.yml -e "{target: 10.1.1.1}" -i 10.1.1.1, ...

그런 다음 플레이 북에서 :

- hosts: "{{ target }}"
  remote_user: donn
  vars_files:
    - myvars
  roles:
    - myrole

이것은 호스트를 프로비저닝해야하고 인벤토리에 추가하기를 원치 않거나 필요로하지 않는 특별한 사용 사례입니다.


1

또한 Ansible Python API 를 구동 해야했으며 인벤토리를 유지하는 대신 호스트를 인수로 전달하는 것이 좋습니다. Ansible의 요구 사항을 우회하기 위해 임시 파일을 사용했는데, 이는 다른 사람들에게 도움이 될 수 있습니다.

from tempfile import NamedTemporaryFile

from ansible.inventory import Inventory
from ansible.runner import Runner

def load_temporary_inventory(content):
    tmpfile = NamedTemporaryFile()
    try:
        tmpfile.write(content)
        tmpfile.seek(0)
        inventory = Inventory(tmpfile.name)
    finally:
        tmpfile.close()
    return inventory

def ping(hostname):
    inventory = load_temporary_inventory(hostname)
    runner = Runner(
        module_name='ping',
        inventory=inventory,
    )
    return runner.run()

당신은 또한 당신이 그것을 사용하는 방법을 한 예 줄 수
Arbab 나자르

0

이것은 완전한 대답은 아니지만 이 토론 스레드 에이 주제에 대한 토론이 있습니다. 해당 스레드의 첫 번째 게시물이 끝나면 ansible-playbook에 대한 래퍼 bash 스크립트를 만들라는 제안이 있습니다. 이는 약간의 해킹이지만 실행 가능합니다.

제가 고려하고있는 다른 것들은 'ansible-pull'의 사용과 ansible 인벤토리 플러그인의 생성입니다. 또한이 질문에 대한 답을 찾는 데 관심이 있으며 더 많은 정보를 찾을 때마다이 답변을 계속 업데이트하겠습니다.


0

내 이해에 따라 매우 간단한 해결책은 산만하다면 사과하십시오.

여기에 3 가지 주요 단계가 있습니다.

  1. 명령 줄 옵션
  2. playbook.yml에 노출되어야하는 것
  3. 그것이 말하는 것

1. 명령 줄 옵션

ansible-playbook -l "host-name"<playbook.yml>

host-name은 노드의 $ hostname입니다.

2. playbook.yml 내부에 노출되어야하는 항목

- hosts: webservers
  tasks:
    - debug:
        msg: "{{ ansible_ssh_host }}"
      when: inventory_hostname in groups['webservers']

3. 무슨 말인가? 보세요 :)

TASK [debug] ***********************************************************************************************************************************************************
Thursday 10 December 2020  13:01:07 +0530 (0:00:03.153)       0:00:03.363 *****
ok: [node1] => {
    "msg": "192.168.1.186"
}

이것이 --limit 또는 -l 옵션을 사용하여 특정 노드에서 작업을 실행할 수있는 방법입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.