在ansible中构建复杂字符串的正确方法是什么?
给出命令模块中az cli的示例:
---
- name: >
LISTDELETED {{ DATABASE_LISTDELETED_DATABASE }} databases
FROM {{ DATABASE_LISTDELETED_SQLSERVER }} sqlserver
command: >
az sql db list-deleted
--resource-group "{{ DATABASE_LISTDELETED_RESOURCEGROUP }}"
--server "{{ DATABASE_LISTDELETED_SQLSERVER }}"
--query "{{ DATABASE_LISTDELETED_QUERY | default('[*]') }}"
--output json
register: DATABASE_LISTDELETED_RESULT
--query
参数。编辑:基于@Zeitounator gist,我结束了。
---
- name: >
LISTDELETED {{ DATABASE_LISTDELETED_DATABASE }} databases
FROM {{ DATABASE_LISTDELETED_SQLSERVER }} sqlserver
vars:
listdelted_command: >
az sql db list-deleted
--resource-group "{{ DATABASE_LISTDELETED_RESOURCEGROUP }}"
--server "{{ DATABASE_LISTDELETED_SQLSERVER }}"
{% if DATABASE_LISTDELETED_QUERY is defined %}
--query "{{ DATABASE_LISTDELETED_QUERY }}"
{% endif %}
command: "{{ listdelted_command }}"
register: DATABASE_LISTDELETED_RESULT
答案 0 :(得分:2)
需求2和需求3是互斥的:您可以在任务中提前构建var(例如,在执行ansible模块之前),但仅可用于该任务(请参见救援任务中的插图)。下面的示例)。
使用 default
过滤器时,您可以处理特定未设置变量的默认值。如果要省略更复杂的字符串,则必须使用相关测试将其用if
jinja2表达式包围。
这是我会在您的情况下尝试的方法(由于未安装az
,因此没有可运行的数据库/查询,因此未经过全面测试)
- name: Store my command in a var
set_fact:
my_command: >-
az sql db list-deleted
--resource-group "{{ DATABASE_LISTDELETED_RESOURCEGROUP }}"
--server "{{ DATABASE_LISTDELETED_SQLSERVER }}"
{% if DATABASE_LISTDELETED_QUERY is defined %}
--query "{{ DATABASE_LISTDELETED_QUERY }}"
{% if %}
--output json
- block:
- name: >
LISTDELETED {{ DATABASE_LISTDELETED_DATABASE }} databases
FROM {{ DATABASE_LISTDELETED_SQLSERVER }} sqlserver
command: "{{ my_command }}"
register: DATABASE_LISTDELETED_RESULT
rescue:
- name: debug failed az command
var:
msg: |
There as been an error running the following command:
{{ my_command }}
The reported error was:
{{ DATABASE_LISTDELETED_RESULT.stderr }}
debug:
msg: "{{ msg.split('\n') }}"
注意:
set_fact
会将提到的变量存储为当前主机的事实。然后,您可以在其他任务中为同一主机重用此变量。block
和rescue
来说明条件调试。修改以适应您的需求。-
符号是strip chomping indicator,以确保为提高可读性而引入的代码中的新行不会干扰构造的命令。msg.split('\n')
只是将多行消息字符串转换为列表,以便于屏幕阅读。DATABASE_LISTDELETED_QUERY
可以设置为空字符串,并且您还想处理这种情况以跳过--query
参数,则可以将测试更改为DATABASE_LISTDELETED_QUERY | default() | length > 0
答案 1 :(得分:0)
您可以为此编写Jinja2模板,在其中可以使用if-else来包含命令的某些部分,例如--query
---
- name: >
LISTDELETED {{ DATABASE_LISTDELETED_DATABASE }} databases
FROM {{ DATABASE_LISTDELETED_SQLSERVER }} sqlserver
command: >
az sql db list-deleted
--resource-group "{{ DATABASE_LISTDELETED_RESOURCEGROUP }}"
--server "{{ DATABASE_LISTDELETED_SQLSERVER }}"
{% if DATABASE_LISTDELETED_QUERY %}
--query "{{ DATABASE_LISTDELETED_QUERY | default('[*]') }}"
{% endif %}
--output json
register: DATABASE_LISTDELETED_RESULT
然后使用ansible模板模块对其进行解析
- name: Template a file to my-command.yml
template:
src: /mytemplates/foo.j2
dest: /commands/my-command.yml