次のようなインベントリファイルを想像してみましょう。
node-01 ansible_ssh_Host=192.168.100.101
node-02 ansible_ssh_Host=192.168.100.102
node-03 ansible_ssh_Host=192.168.100.103
node-04 ansible_ssh_Host=192.168.100.104
node-05 ansible_ssh_Host=192.168.100.105
[mainnodes]
node-[01:04]
私のプレイブックでは、グループmainnodes
のIPアドレスを含むいくつかの変数を作成します。
vars:
main_nodes_ips: "192.168.100.101,192.168.100.102,192.168.100.103,192.168.100.104"
main_nodes_ips_with_port: "192.168.100.101:3000,192.168.100.102:3000,192.168.100.103:3000,192.168.100.104:3000"
これは私がこれまでに得たものです:
vars:
main_nodes_ips: "{{groups['mainnodes']|join(',')}}"
main_nodes_ips_with_port: "{{groups['mainnodes']|join(':3000,')}}"
しかし、それはIPアドレスの代わりにホスト名を使用します。
これをどのように行うことができますか?
更新:
しばらくドキュメントを見て、これですべてのIPアドレスをループできると思います:
{% for Host in groups['mainnodes'] %}
{{hostvars[Host]['ansible_ssh_Host']}}
{% endfor %}
しかし、これらのすべてのIPを保持する配列を作成する方法がわかりません。 |join()
コマンドを使用できるように。
pdate2:
私はそれを理解したと思っただけですが...プレイブックで{%%}構文を使用できないことがわかりました...またはできますか? varsセクションではそうではありませんでした。 :/
vars:
{% set main_nodes_ip_arr=[] %}
{% for Host in groups['mesos-slave'] %}
{% if main_nodes_ip_arr.insert(loop.index,hostvars[Host]['ansible_ssh_Host']) %} {% endif %}
{% endfor %}
main_nodes_ips: "{{main_nodes_ip_arr|join(',')}}"
main_nodes_ips_with_port: "{{main_nodes_ip_arr|join(':3000,')}}"
私は今、自分で作業できるようにしました。私は解決策にあまり満足していませんが、それはうまくいきます:
main_nodes_ips: "{% set IP_ARR=[] %}{% for Host in groups['mainnodes'] %}{% if IP_ARR.insert(loop.index,hostvars[Host]['ansible_ssh_Host']) %}{% endif %}{% endfor %}{{IP_ARR|join(',')}}"
main_nodes_ips_with_port: "{% set IP_ARR=[] %}{% for Host in groups['mainnodes'] %}{% if IP_ARR.insert(loop.index,hostvars[Host]['ansible_ssh_Host']) %}{% endif %}{% endfor %}{{IP_ARR|join(':3000,')}
マジックmap extract
here が見つかりました。
main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_Host']) | join(',') }}"
main_nodes_ips_with_port: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_Host']) | join(':3000,') }}:3000"
代替案(アイデアは here から得られます):
main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_eth0', 'ipv4', 'address']) | join(',') }}"
(インターフェースがeth0
であると仮定します)
私はしばらく前にこの問題に遭遇し、これは私が思いついたものです(最適ではありませんが、それは動作します)
---
# playbook.yml
- hosts: localhost
connection: local
tasks:
- name: create deploy template
template:
src: iplist.txt
dest: /tmp/iplist.txt
- include_vars: /tmp/iplist.txt
- debug: var=ip
そしてテンプレートファイルは
ip:
{% for h in groups['webservers'] %}
- {{ hostvars[h].ansible_ssh_Host }}
{% endfor %}
私は、プレイブックでansibleファクトを使用してこれを実行しました。このプレイブックは、ansible_all_ipv4_addressesリストとansible_nodename(実際には完全修飾ドメイン名)を受け取り、すべてのホストを反復処理して、localhostのlocalpath_to_save_ipsファイルにデータを保存します。 localpath_to_save_ipsをローカルホストの絶対パスに変更できます。
---
- hosts: all
become: yes
gather_facts: yes
tasks:
- name: get ip
local_action: Shell echo {{ ansible_all_ipv4_addresses }} {{ ansible_nodename }} >> localpath_to_save_ips
次のいずれかが当てはまる場合、他のグループのIPにアクセスするための「唯一の方法」を見つけました。
以下のとおりであります:
{% set ips=[] %}{% for Host in groups['othergroup'] %}{% if ips.append(lookup('Dig', Host)) %}{% endif %}{% endfor %}{{ ips }}
Ansibleを実行しているマシンでdnspythonが必要です。
Sudo apt-get install python-dnspython
条件を考えれば、だれかがより良い方法を知っているなら、私はこの憎むべきものを取り除きたいです。
- name: Create List of nodes to be added into Cluster
set_fact: nodelist={%for Host in groups['mygroup']%}"{{hostvars[Host].ansible_eth0.ipv4.address}}"{% if not loop.last %},{% endif %}{% endfor %}
- debug: msg=[{{nodelist}}]
- name: Set Cluster node list in config file
lineinfile:
path: "/etc/myfonfig.cfg"
line: "hosts: [{{ nodelist }}]"
結果として、設定ファイルに次の行が含まれます。
hosts: ["192.168.126.38","192.168.126.39","192.168.126.40"]