[英]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
第二個任務是第一個任務的完美克隆,然后覆蓋name
, condition
和循環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.