2014-02-12 53 views
4

有沒有人有更好的解決方案來配置主機名實例,然後才能將該主機名分配給服務器?Ansible:如何在DNS分配之前設置主機名

假設我們正在使用AWS並實例化實例ec2-1-2-3-4.compute-1.amazonaws.com。在配置完成後,我們最終會在DNS的new-instance.example.com中爲其分配一個CNAME,以替換已在生產中的現有實例。

new-instance.example.com已經存在,是集生產,所以我們不能重新分配CNAME到ec2-1-2-3-4.compute-1.amazonaws.com直到機器配置正確,我們準備好切換。但是,我們現在需要內部配置文件和實例上的主機名爲new-instance.example.com,以準備DNS更改。所以我們不能使用inventory_hostname變量,因爲它會是ec2-1-2-3-4.compute-1.amazonaws.com。我也有正常的生產服務器,不需要使用新的主機名,所以我希望能夠使用現有的inventory_hostname

我最好的想法迄今已分配的資源文件中的變量:

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

在劇本,我可以測試new_hostname的存在。如果new_hostname存在,則使用它,如果不存在,則使用inventory_hostname。這將導致致命錯誤,除非error_on_undefined_vars設置爲false並且我不希望將其設置爲防止輸入錯誤的好處。下面是一個失敗的例子。

測試劇本:

- 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未設置,則失敗。

此策略的最佳實踐?

回答

6

對此非常害羞,因爲我也是新手,如果我理解你的問題,一種方法是在任務上使用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 

現在,這是一種方法。另一個可能是爲此發揮作用,並且只能從庫存中的添加條目中單獨地將該角色(旋轉過程)分別發揮到目標機器。如果你喜歡一些額外的閱讀,請看best practices

+0

不要認爲這種方法適用於'when',因爲它需要一個布爾值而不是字符串。 – Rico

+0

@Rico oups對不起,忘了定義。應付粘貼重命名錯誤。看到更正的答案 –

+1

@Jimmy_Kane沒問題。這也將工作:-) – Rico

3

when一種方法是,如果你的DNS名稱有一個模式,因爲你總是定義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 

這裏的關鍵是始終定義變量並尋找匹配或不匹配的模式。您的庫存和命令行變量應該覆蓋您的playbook變量。

爲了更將其應用到你的情況:

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

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

優先級:

  • -e變量總是贏
  • 然後是 「最一切」
  • 然後是庫存中定義的變量
  • 然後是「角色違約」,它是最「默認」的,並且優先於所有東西而失去。
+1

這是偉大的@Rico。我相信,如果我想使用inventory_hostname的實例,只需定義'new_hostname = ec2-1-2-3-4.compute-1.amazonaws.com'而不是'nada'即可完成此操作,而無需額外的邏輯。 然而,我想要實現的好處是能夠爲這些類型的服務器使用主機名分組,而不必爲不需要它的實例組設置「new_hostname」。 –

4

站立時高達cloud-init設置的主機名。 (我使用廚師,但這與解決方案無關)。這解決了在自動化框架中設置主機名的問題,因爲它在節點引導時已經設置好了。我的雲配置的

部分設置fqdnmanage_etc_hosts選項,像這樣:

fqdn: new-instance.example.com 
manage_etc_hosts: true 

有大量的示例配置片段在doc/examples directory,很容易玩一圈,找到你喜歡的設置。

相關問題