使用 set_fact/update_fact 更新 YAML 文件

我的 ansible 项目包含 6 个角色(app、db、init、ror、tick、web)。每个角色代表系统的一个组件的安装。每个设备使用文件“/etc/ansible/ansible-install-state.yml”跟踪已安装的角色。它的初始内容是:

# ansible-install-state.yml
#
#
# This file is maintained by Ansible
# Please leave it alone,or accept the consequences!
#

roles:
  app:
    installed: false
  db:
    installed: false
  init:
    installed: false
  ror:
    installed: false
  tick:
    installed: false
  web:        
    installed: false

在“init”角色完成后,我想处理文件以将安装状态更新为“true”。我通过以下调用来做到这一点。 (为了测试,我还设置了 'ror: true' 并添加了一个新角色 'new: unknown'

  - name: System Init | Process ansible_install_state
    ansible.builtin.include_tasks:  process_ansible_install_state.yml
    with_items:
      - role: { key: init,value: true }
      - role: { key: ror,value: true }
      - role: { key: new,value: unknown}
 

更新现有角色相当顺利,但添加新角色却没有。我终于通过首先添加角色本身来让它工作,本质上是“新:{}”,然后再次修改它以添加“已安装:未知”部分。虽然这确实有效,但我不禁相信有更好的方法 - 一种一次性完成的方法。以下是 process_enable_install_state.yml 文件。

---
# process_ansible_install_state.yml

#
#------------------------- Process Ansible Install State File
#

- name: display variable
  debug: 
    var: item

# See https://stackoverflow.com/questions/32994002/is-there-a-yaml-editing-module-for-ansible
- name: Ansible Install State | Read ansible-install-state.yml  
  ansible.builtin.slurp: 
    path: "/etc/ansible/ansible-install-state.yml"
  register: install_state

- name: Ansible Install State | Decode and save yaml as fact
  ansible.builtin.set_fact:
    my_roles: "{{ install_state['content'] | b64decode | from_yaml }}"
  register: its_a_fact

- name: Ansible Install State | Save the new ROLE block
  block: 
 
  - name: Ansible Install State |  Save the new role
    ansible.utils.update_fact:
      updates:
      - path: my_roles.roles.{{ item.role.key }}
        value: {}
    register: updated

  # Update_fact does not update 'in place',so we need to save it as a fact
  - name: Ansible Install State | Update the saved 'fact'
    ansible.builtin.set_fact:
      my_roles: "{{ updated.my_roles}}"

  when: my_roles.roles[item.role.key] is undefined

- name: debug
  debug: 
    var: updated

- name: Ansible Install State | Update the role's installed state
  ansible.utils.update_fact:
    updates:
    - path: my_roles.roles.{{ item.role.key }}.installed
      value: "{{item.role.value}}"
  register: updated

- name: debug
  debug: 
    var: updated

# Update_fact does not update 'in place',so we need to save it as a fact
- name: Ansible Install State | Save modified as 'fact'
  ansible.builtin.set_fact:
    my_roles: "{{ updated.my_roles}}"

- name: Ansible Install State | Write Yaml File
  ansible.builtin.copy:    
    content: '{{ my_roles | to_nice_yaml }}'
    dest: "/etc/ansible/ansible-install-state.yml" 

- name: Ansible Install State | Insert Header Comments
  ansible.builtin.blockinfile:
    path: "/etc/ansible/ansible-install-state.yml"
    insertbefore: BOF
    marker: "#{mark}"
    marker_begin: "-------------------------------------------"
    marker_end:   "-------------------------------------------"
    block: |
      # ansible-install-state.yml
      #
      #
      # This file is maintained by Ansible
      # Please leave it alone,or accept the consequences!
      #
      #


这次成功制作...

# ansible-install-state.yml
#
#
# This file is maintained by Ansible
# Please leave it alone,or accept the consequences!
#
#
#-------------------------------------------
roles:
    app:
        installed: false
    db:
        installed: false
    init:
        installed: true
    new:
        installed: unknown
    ror:
        installed: true
    tick:
        installed: false
    web:
        installed: false
deploy@rpi-tick2:/etc/ansible $ 

wjr349464977 回答:使用 set_fact/update_fact 更新 YAML 文件

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/15499.html

大家都在问