簡體   English   中英

Ansible - 如何在劇本中有條件地反轉變量

[英]Ansible - how to conditionally invert variables in a playbook

我需要能夠反轉存儲在從命令行傳遞給playbook的JSON文件中的變量。

這些是我設置的任務(它們除了變量之外都是相同的 ),這是一個劇本的片段:

- name: Prepare a .sql file
  delegate_to: 127.0.0.1
  mysql_db:
    name: "{{ source['database']['db_name'] }}"
    state: dump
    login_host: "{{ source['database']['host'] }}"
    login_user: "{{ source['database']['user'] }}"
    login_password: "{{ source['database']['password'] }}"
    target: test_db.sql
  when: invert is not defined

- name: Prepare a .sql file (inverted)
  delegate_to: 127.0.0.1
  mysql_db:
    name: "{{ target['database']['db_name'] }}"
    state: dump
    login_host: "{{ target['database']['host'] }}"
    login_user: "{{ target['database']['user'] }}"
    login_password: "{{ target['database']['password'] }}"
    target: test_db.sql
  when: invert is defined

所以當我執行時

ansible-playbook -i hosts playbook.yml --extra-vars "@dynamic_vars.json"

第一個任務被執行。 如果我執行

ansible-playbook -i hosts playbook.yml --extra-vars "@dynamic_vars.json" --extra-vars "invert-yes"

執行第二個任務,它接受與參數相同的哈希,但只交換目標的源(它基本上成為我的劇本中的源)。

正如你所看到的,這是一種非常簡單的方法,有很多不必要的重復,我只是不喜歡它。 但是,我想不出能夠在命令行恢復變量而不構建更復雜的包含邏輯的更好方法。

也許你可以建議我如何做得更好? 謝謝!

在涉及避免重復的主題時,我是YAML錨點和參考的忠實粉絲。 由於內容是動態的,你可以利用with_items ,它可以用來傳遞一個參數,如下所示:

- &sqldump
  name: Prepare a .sql file
  delegate_to: 127.0.0.1
  mysql_db:
    name: "{{ item['database']['db_name'] }}"
    state: dump
    login_host: "{{ item['database']['host'] }}"
    login_user: "{{ item['database']['user'] }}"
    login_password: "{{ item['database']['password'] }}"
    target: test_db.sql
  when: invert is not defined
  with_items:
    - source


- <<: *sqldump
  name: Prepare a .sql file (inverted)
  when: invert is defined
  with_items:
    - target

第二個任務是第一個任務的完美克隆,然后覆蓋namecondition和循環with_items以傳遞target而不是source


在閱讀了@ydaetskcoR的答案之后,聽起來您在某些情況下需要使用來自其中一個或另一個字典的數據。 也許在那種情況下,根據invert參數來定義var全局是有意義的。 您的vars文件可能如下所示:

---

source:
  database: ...
  db_name: ...

target:
  database: ...
  db_name: ...

data: "{{ target if invert is defined else source }}"

然后,您可以在所有任務中使用data ,而無需進一步處理條件。

- name: Prepare a .sql file
  delegate_to: 127.0.0.1
  mysql_db:
    name: "{{ data['database']['db_name'] }}"
    state: dump
    login_host: "{{ data['database']['host'] }}"
    login_user: "{{ data['database']['user'] }}"
    login_password: "{{ data['database']['password'] }}"
    target: test_db.sql

當然,這樣你就有了一個固定的任務名稱,它不隨你傳遞的參數而改變。

如果您嘗試執行相同的操作但只想根據主機/組指定不同的變量,那么更好的方法可能是將這些變量設置為主機/組變量並將其作為單個任務運行。

如果我們設置我們的庫存文件有點像這樣:

[source_and_target-nodes:children]
source-nodes
target-nodes

[source-nodes]
source database_name='source_db' database_login_user='source_user' database_login_pass='source_pass'

[target-nodes]
target database_name='target_db' database_login_user='target_user' database_login_pass='target_pass'

然后我們可以在source_and_target-nodes處定位任務,如下所示:

- name: Prepare a .sql file
  hosts: source_and_target-nodes
  mysql_db:
    name: "{{ database_name }}"
    state: dump
    login_host: "{{ inventory_hostname }}"
    login_user: "{{ database_login_user }}"
    login_password: "{{ database_login_pass }}"
    target: test_db.sql

如果您需要在問題中使用delegate_to ,那么您將無法輕松訪問其他主機的主機變量,但如果您只是需要在本地運行該游戲,則可以在主機中將ansible_connection設置為local / group vars或設置connection: local播放中的connection: local

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM