この質問には回答がありません。誰かが環境変数について言及していました。これについて詳しく説明していただけますか?
2024 年 5 月 28 日 - 質問を簡略化しました (以下): これは Oracle の問題です。PC が 4 台あります。ドライブ E がある 1 台のマシンでプログラム 1 を実行する必要があります。ドライブ E がない残りの 3 台のうち、3 台のうち 1 台でのみプログラム 2 を実行する必要があります。他の 2 台では、何も実行しないでください。
これは単純な問題のように思えますが、Ansible ではそうではありません。この問題は繰り返し発生します。特にエラー状態では顕著です。グローバル変数が必要です。1 つのホスト プレイを処理するときに設定し、後で別のホストで確認できる変数です。簡単に言えば、変数に応じてプレイブックの後で分岐できるようにするためです。
カスタム ソフトウェアのインストールを制御することはできませんが、インストールした場合は、他のマシンに別のソフトウェアをインストールする必要があります。さらに、VM フォルダーに応じてインストールが異なります。グローバル変数のために喜んで協力します。
変数のスコープは、現在の ansible_hostname にのみ関連します。はい、group_vars/all.yml はグローバルとしてありますが、プレイで設定することはできません。変数を設定しても、他のホストのプレイ/タスクではそれを参照できません。変数のスコープは理解していますが、すべてのプレイブック プレイで読み取ることができるグローバル変数を設定したいと考えています。実際の実装は重要ではありませんが、変数アクセスは重要です (重要)。
私の質問:別のホストで別のタスクを実行するときにチェックできる変数を設定する方法はありますか? setGlobalSpaceVar(myvar, true) のようなものですか? そのような方法はないことはわかっていますが、回避策を探しています。言い換えると、あるホストの 1 つのタスクで変数を設定し、後で別のホストの別のタスクでその変数を読み取ります。
考えられる唯一の方法は、コントローラー上のファイルを変更することですが、それは間違っているようです。
例
以下はOracleのバックアップとローカル実行可能ファイルに関するものですが、一般的な内容に留めています。以下について -はい、run_once を実行することはできますが、それでは私の質問に対する答えにはなりません。この変数アクセスの問題は、さまざまな状況で繰り返し発生します。
私は 4 台の xyz サーバーを持っています。実行する必要があるプログラムは 2 つありますが、2 台の異なるマシンでのみ実行する必要があります。どちらが実行する必要があるかはわかりません。設定は VM 環境によって異なる可能性があります。
私たちのプログラム 1 は、ドライブ E があるサーバーで実行されます。Ansible を使用して、どのサーバーにドライブ E があるかを調べ、変数 (driveE_machine) を設定するたびにそれに応じてプレイを実行できます。これは、そのホストにのみ適用されます。そのため、他の 3 台のマシンには driveE_machine が設定されません。後のプレイでは、他の 3 台のマシンのうち 1 台のみで別のプログラムを実行する必要があります。つまり、2 番目のプログラムを実行していない他の 2 台のホストが読み取ることができる変数を設定する必要があります。その方法がわかりません。
インベントリファイル:
[xyz]
serverxyz[1:4].private.mystuff
プレイブックの例:
---
- name: stackoverflow variable question
hosts: xyz
gather_facts: no
serial: 1
tasks:
- name: find out who has drive E
win_shell: dir e:\
register: adminPage
ignore_errors: true
# This sets a variable that can only be read for that host
- name: set fact driveE_machine when rc is 0
set_fact:
driveE_machine: "{{inventory_hostname}}"
when: adminPage.rc == 0
- name: run program 1
include: tasks/program1.yml
when: driveE_machine is defined
# program2.yml executes program2 and needs to set some kind of variable
# so this include can only be executed once for the other 3 machines
# (not one that has driveE_machine defined and ???
- name: run program 2
include: tasks/program2.yml
when: driveE_machine is undefined and ???
# please don't say run_once: true - that won't solve my variable access question
別のホストでタスクを実行するときにチェックできる変数を設定する方法はありますか?
ベストアンサー1
実際に何が必要かはわかりませんが、単一のループ タスク (グローバル変数のシミュレーション) を使用して、プレイ内のすべてのホストにファクトを設定できます。
プレイブック.yml
---
- hosts: mytest
gather_facts: no
vars:
tasks:
# Set myvar fact for every host in a play
- set_fact:
myvar: "{{ inventory_hostname }}"
delegate_to: "{{ item }}"
with_items: "{{ play_hosts }}"
run_once: yes
# Ensure that myvar is a name of the first host
- debug:
msg: "{{ myvar }}"
ホスト
[mytest]
aaa ansible_connection=local
bbb ansible_connection=local
ccc ansible_connection=local
結果
PLAY [mytest] ******************
META: ran handlers
TASK [set_fact] ******************
ok: [aaa -> aaa] => (item=aaa) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "aaa"}
ok: [aaa -> bbb] => (item=bbb) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "bbb"}
ok: [aaa -> ccc] => (item=ccc) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "ccc"}
TASK [debug] ******************
ok: [aaa] => {
"msg": "aaa"
}
ok: [bbb] => {
"msg": "aaa"
}
ok: [ccc] => {
"msg": "aaa"
}