如何用Ansible的ternary过滤器切换文件加密/解密状态?
解决Ansible切换文件加密状态的YAML语法错误及实现方案
核心问题分析
你的playbook存在两个关键问题:
- YAML语法错误:
local_action: shell之后的行没有遵循键: 值的YAML结构,直接写命令导致解析失败。 - 过滤器用法错误:
ternary是Ansible的Jinja2模板过滤器,不能直接嵌入到shell管道命令中执行,系统shell无法识别Ansible的模板语法。
正确实现方案
下面提供两种可行的实现方式,均能完成「已加密则解密,未加密则加密」的切换逻辑:
方案1:使用ternary动态选择执行命令
--- # site.yml - name: 切换文件的Ansible Vault加密状态 hosts: localhost gather_facts: no vars: target_file: test_key_file encrypt_cmd: "ansible-vault encrypt {{ target_file }}" decrypt_cmd: "ansible-vault decrypt {{ target_file }}" # 检测文件是否加密:返回0表示已加密,非0表示未加密 check_encrypt_status: "head -1 {{ target_file }} | grep -q '\\$ANSIBLE_VAULT'" tasks: - name: 检测文件加密状态 command: "{{ check_encrypt_status }}" register: encrypt_check_result ignore_errors: true # 未加密时grep返回非0,忽略该错误避免任务中断 - name: 执行加密/解密切换 command: "{{ encrypt_check_result.rc | ternary(decrypt_cmd, encrypt_cmd) }}"
方案2:使用when条件分支执行任务
如果觉得过滤器逻辑不够直观,可以用条件分支分别处理两种状态:
--- # site.yml - name: 切换文件的Ansible Vault加密状态 hosts: localhost gather_facts: no vars: target_file: test_key_file tasks: - name: 检测文件是否加密 command: head -1 {{ target_file }} | grep -q '\$ANSIBLE_VAULT' register: encrypt_check_result ignore_errors: true - name: 加密未加密的文件 command: ansible-vault encrypt {{ target_file }} when: encrypt_check_result.rc != 0 - name: 解密已加密的文件 command: ansible-vault decrypt {{ target_file }} when: encrypt_check_result.rc == 0
原写法的语法修正说明
如果一定要用local_action,正确的YAML格式应该是这样(但仍需调整过滤器的用法):
- local_action: module: shell cmd: "<your command>"
但如前所述,ternary过滤器不能直接嵌入shell命令,所以还是推荐上面的两种方案。
内容的提问来源于stack exchange,提问作者rustyshamrock
相关产品推荐
相关产品推荐

