如何在Ansible Playbook中实现Bash脚本的if else分支判断逻辑?
Ansible实现Bash if-else逻辑的方案
你要复现Bash里的if-else分支和变量存储命令结果的逻辑,核心用到Ansible的两个核心功能:
- 用
register关键字注册变量,存储命令/模块的执行结果,对应Bash里变量=$(命令)的用法 - 用
when关键字给任务设置执行条件,满足条件才执行任务,对应Bash的if判断;else分支直接写反向条件的when即可,多组同条件任务可以用block包裹简化写法
下面是匹配你提供的Bash脚本转换完成的Ansible Playbook示例:
--- - name: 复现Bash脚本逻辑的Ansible Playbook hosts: your_target_hosts become: yes vars: audit_key: config_kernel_activ conf_path: /usr/lib/sysctl.d/00-system.conf bak_dir: /root/md_sum bak_conf_path: "{{ bak_dir }}/00-system.conf.bak" md5_path: "{{ bak_dir }}/00-system.md5" tasks: # 预获取基础变量信息,对应Bash开头的变量赋值 - name: 读取备份配置文件内容 slurp: src: "{{ bak_conf_path }}" register: file1 ignore_errors: yes - name: 读取当前配置文件内容 slurp: src: "{{ conf_path }}" register: file2 - name: 获取当前配置文件属性 stat: path: "{{ conf_path }}" get_checksum: no register: conf_stat - name: 格式化所需时间变量 set_fact: file_time2: "{{ conf_stat.stat.mtime | strftime('%Y-%m-%d %H:%M:%S') }}" date_audit2: "{{ conf_stat.stat.mtime | strftime('%H:%M:%S') }}" # 第一部分:检查audit规则 对应第一个if-else - name: 查询当前audit规则列表 command: auditctl -l register: audit_rules changed_when: false - name: 输出audit规则已存在 debug: msg: "audit up" when: "'-w /usr/lib/sysctl.d/00-system.conf -p rwa' in audit_rules.stdout" - name: 新增缺失的audit规则 block: - debug: msg: "audit down" - command: auditctl -w /usr/lib/sysctl.d/00-system.conf -p war -k {{ audit_key }} when: "'-w /usr/lib/sysctl.d/00-system.conf -p rwa' not in audit_rules.stdout" # 第二部分:检查md5校验文件 对应第二个if-else - name: 检查md5文件是否存在 stat: path: "{{ md5_path }}" register: md5_file - name: 输出md5文件已存在 debug: msg: "sum up" when: md5_file.stat.exists and md5_file.stat.size > 0 - name: 生成初始md5校验文件 block: - debug: msg: "sum down" - shell: md5sum {{ conf_path }} > {{ md5_path }} when: not (md5_file.stat.exists and md5_file.stat.size > 0) # 第三部分:检查备份配置文件 对应第三个if-else - name: 检查备份配置文件是否存在 stat: path: "{{ bak_conf_path }}" register: bak_file - name: 输出备份文件已存在 debug: msg: "bak files are present" when: bak_file.stat.exists and bak_file.stat.size > 0 - name: 生成初始配置备份文件 block: - debug: msg: "bak files are not present" - copy: src: "{{ conf_path }}" dest: "{{ bak_conf_path }}" remote_src: yes when: not (bak_file.stat.exists and bak_file.stat.size > 0) # 第四部分:校验文件是否变更 对应第四个if-else - name: 执行md5校验 command: md5sum -c {{ md5_path }} register: md5_check changed_when: false ignore_errors: yes - name: 输出文件未变更 debug: msg: "files have not changed" when: "'OK' in md5_check.stdout" - name: 输出文件变更信息和审计日志 block: - debug: msg: "files has changed {{ file_time2 }}" - debug: msg: "CHANGES 00-system.conf " - shell: comm -31 <(tr ' ' $'\n' <<< {{ file1.content | b64decode }} | sort) <(tr ' ' $'\n' <<< {{ file2.content | b64decode }} | sort) register: conf_diff - debug: msg: "{{ conf_diff.stdout_lines }}" - debug: msg: "more details " - shell: ausearch -k {{ audit_key }} -i | grep {{ date_audit2 }} | grep "ouid" register: audit_log ignore_errors: yes - debug: msg: "{{ audit_log.stdout_lines | default([]) }}" when: "'OK' not in md5_check.stdout"
使用前将your_target_hosts替换为你实际要执行的目标主机组即可,优先使用Ansible原生模块代替command/shell执行命令,可保证操作的幂等性,也更容易获取结构化的返回值。
内容的提问来源于stack exchange,提问作者Gidrotormoz
相关产品推荐
相关产品推荐

