4

ホスト名をサーバーに割り当てる前に、ホスト名を使用してインスタンスを構成するためのより良い解決策はありますか?

AWS を使用していて、インスタンスec2-1-2-3-4.compute-1.amazonaws.comをインスタンス化するとしましょう。構成が完了したら、最終的にnew-instance.example.comの DNS で CNAME を割り当てて、既に運用されている既存のインスタンスを置き換えます。

new-instance.example.comはすでに存在し、本番環境にあるためマシンが適切に構成され、切り替える準備ができました。ただし、DNS の変更に備えて、インスタンスの内部構成ファイルとホスト名をnew-instance.example.comにする必要があります。ec2-1-2-3-4.compute-1.amazonaws.comになるため、 inventory_hostname変数は使用できません。また、新しいホスト名を使用する必要のない通常の運用サーバーもあるため、既存のinventory_hostnameを使用できるようにしたいと考えています。

これまでの私の最善のアイデアは、インベントリ ファイルに変数を割り当てることでした。

[production]
ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com

Playbook では、 new_hostnameの存在をテストできます。new_hostnameが存在する場合はそれが使用され、存在しない場合はinventory_hostnameが使用されます。error_on_undefined_varsfalseに設定されていない限り、これは致命的なエラーを引き起こします。タイプミスを防ぐという利点のために、これを設定しないことをお勧めします。以下失敗例。

テスト プレイブック:

- hosts: all
  tasks:
    - name: "Debug hostname"
      debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
      ignore_errors: yes

結果:

TASK: [Debug hostname] ********************************************************
fatal: [ec2-1-2-3-4.compute-1.amazonaws.com] => One or more undefined variables: 'new_hostname' is undefined

すべての単一サーバーにnew_hostnameを設定すると機能しますが、すべてのサーバーに設定するのではなく、新しいホスト名が必要なサーバーだけに設定します。また、次のようなホスト名のグループ化も中断します。

ec2-1-2-3-[4:5].compute-1.amazonaws.com

new_hostnameが存在する場合、これは機能します。

- name: "set hostname fact"
  set_fact: testvar1={{ new_hostname }} || {{ inventory_hostname }}

- name: "show hostname fact"
  debug: msg="testvar1={{ testvar1 }}"

結果:

TASK: [set hostname fact] *****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com]

TASK: [show hostname fact] ****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com] => {"msg": "testvar1=new-instance.example.com"}

ただし、error_on_undefined_vars がデフォルトの true に設定されていて、new_hostnameが設定されていない場合、失敗します。

この戦略のベストプラクティスは?

4

4 に答える 4

7

私もansibleに慣れていないので、これに非常に恥ずかしがり屋であり、あなたの問題を理解している場合、1つの方法はwhen: something is definedタスクで使用することです。

例:

  tasks:
    - name: "Debug hostname"
      debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
      when: new_hostname is defined

これが1つのアプローチです。もう 1 つは、その役割を作成し、インベントリに追加されたエントリとは別に、ターゲット マシンに対してその役割 (スピンアップ手順) のみを実行することです。追加の読み物として、必要に応じてベスト プラクティスも参照してください。

于 2014-02-12T22:26:29.997 に答える
3

DNS 名にパターンがある場合、常に変数whenを定義する場合の1 つのアプローチは次のとおりです。new_hostname

- include: tasks/sometasks.yml
  when: "'new' in new_hostname"

次に、new_hostname前述のようにインベントリで変数を定義できます。

[production]
ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com
ec2-5-6-7-8.compute-1.amazonaws.com new_hostname=nada

ここで重要なのは、常に変数を定義し、一致するパターンまたは一致しないパターンを探すことです。インベントリーとコマンドライン変数は、プレイブック変数をオーバーライドする必要があります。

それをあなたのケースにさらに適用するには:

tasks:
  - name: "set hostname fact"
    set_fact: testvar1={{ new_hostname }}
    when: "'new' in new_hostname"

  - name: "set hostname fact"
    set_fact: testvar1={{ inventory_hostname }}
    when: "'nada' in new_hostname"

覚えておくべきことはnew_hostname、プレイブックで変数を定義しないことです。そうしないと、インベントリ変数がオーバーライドされます。

また、(すべてのサーバーに対して) インベントリ ファイルで定義されているものもオーバーライドするコマンド ラインを介して渡す必要はありません。

ansible-playbook -i <your-inventory> -e "new_hostname=new-instance.example.com" yourplaybook.xml

これは、Ansible 変数の優先順位に従っています。

  • -e 変数は常に優先されます
  • それから「他のほとんどすべて」が来る
  • 次に、インベントリで定義された変数が来ます
  • 次に、最も「デフォルト」であり、すべての優先順位を失う「ロールのデフォルト」。
于 2014-02-12T23:22:53.883 に答える