[英]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.