2017-11-07 14 views
3

誰かが環境変数について述べました。これについて詳しく説明できますか?すべての再生/ホストにAnsible変数を設定するにはどうすればよいですか?

これは単純な問題のようですが、不可能です。それはやってくる。特にエラーが発生した場合。私はグローバル変数が必要です。 1つのホストの再生を処理するときに設定できるものとし、後で別のホストでチェックします。不可能な場合、分岐ははるかに単純になります。

変数のスコープは、現在のansible_hostnameにのみ関連しています。はい、私たちはグローバルとしてgroup_vars/all.ymlを持っていますが、演劇ではそれらを設定することはできません。変数を設定した場合、他のホストの再生/タスクはそれを見ることができません。私は変数の範囲を理解していますが、私はすべてのプレイブックのプレイを通して読むことができるグローバル変数を設定したいと思います。 実際の実装は重要ではありませんが、可変アクセスは重要です(重要)。

私の質問:別のホストで別のタスクを実行しているときにチェックできる変数を設定する方法はありますか? setGlobalSpaceVar(myvar、true)のようなもの?私はそのような方法がないことを知っていますが、私は回避策を探しています。言い換えると、あるホストのためにあるタスクで変数を設定し、後で別のホストの別のタスクで変数を読み込みます。

私が考えることができる唯一の方法は、コントローラ上のファイルを変更することですが、それは偽のようです。

次に、Oracleのバックアップと私たちの地元の実行に関連するが、私は一般的なそれを維持しています。下に - はい、私はrun_onceを行うことができますが、それは私の質問に答えることはありません。この可変的なアクセスの問題は、さまざまなコンテキストで引き続き発生します。

私は4つのxyzサーバーを持っています。実行する必要のあるプログラムは2つありますが、2つの異なるマシンにしかありません。私はどちらが分かりません。設定は、異なるVM環境で変更される可能性があります。

私たちのprogramOneは、ドライブEを持つサーバー上で実行されます。私は、ドライブEを持つサーバーを見つけることができます、私は変数(driveEmachine)を設定するたびに再生を行います。そのホストにのみ適用されます。そのため、他の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 

別のホスト上でタスクを実行する際にチェックすることができる変数を設定する方法はありますか?

+0

私は確かに、これは設計上許されないことを確信しています - 共有可能な可変状態は悪いためです:https://stackoverflow.com/questions/19158339/why-are-global-variables-evil – stefreak

+0

@stefreakはいグローバルは悪ですが、1これはプログラムではなく、フレームワークです。私たちはフレームワークを回避する必要があります。 2.私は異なるホストとの橋渡しのための道を必要とし、変数なしでは、これは非常に困難になることがあります。この恩恵は終わったが、誰もそれに答えなかった。 –

答えて

0

ありませんあなたが実際に何をしたいことを確認していますが、シングルループのタスク(グローバル変数のいくつかのシミュレーション)でプレーしてすべてのホストのための事実を設定することができます。

playbook.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" 
} 
+0

しかし、あなたは 'run_once'を使用します...それはOPによって禁じられています! – techraf

+0

私はそれが他の方法で使用されていると信じています:) –

+0

私は特にrun_onceについて心配していません。変数の設定/読み込みが心配です。 –

0

唯一*グローバルスコープの変数を作成する方法は、インメモリインベントリを作成し、変数を渡し、そのインベントリに対して再生を実行することですが、問題の問題を解決する必要はないようです。

registerを使って保存された値が事実でない、つまり各ホストごとに値が別々に保存されているという事実が欠落していると思います。

adminPageは、タスクを実行した各ホストで常に使用できるため、コマンドが成功した場所に情報を別途作成して保存する必要はありません。その値は各ターゲットごとに個別に格納されます。

あなたはおそらく次のコードをしたい:

--- 
- 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 

    - name: run program 1 
     include_tasks: tasks/program1.yml 
     when: adminPage.rc == 0 

    - name: run program 2 
     include_tasks: tasks/program2.yml 
     when: adminPage.rc != 0 
     run_once: true 

(予告もinclude directive is being deprecated


*使用することができるいくつかのハックの回避策は、変数の値を保存するために、たとえば、あります制御マシン上のファイルに書き込んで、include_varsで読み取ります。

+0

このソリューションにはrun_onceがあります。私は変数を取得する方法を探しています –

+0

私は問題についてコメントしました:それは実装を望んでいないと述べたが、変数を設定する方法。私はrun_onceが欲しくないと述べた。 –

+0

あなたは答えを編集していました。それは私の上で変わり、最後にリンクがありました。 –

関連する問題