使用Ansible实现LXD存储池的幂等配置
实现LXD存储池配置的幂等性
问题场景
想用Ansible配置LXD存储池,实现幂等效果——仅当存储池不存在或配置不符合预期时执行创建命令,但原Playbook的when条件写法错误,尝试json_query也没解决问题。
原Playbook片段
- name: LXD config dump shell: cmd: lxd init --dump register: lxd_dump - name: LXD storage pool on NAS shell: cmd: lxc storage create nas dir source=/data/nas/pool/lxd when: (lxd_dump.stdout | from_yaml).storage_pools.config.name is undefined or (lxd_dump.stdout | from_yaml).storage_pools.name != "nas" or (lxd_dump.stdout | from_yaml).storage_pools.config.source != /data/nas/pool/lxd
存储池配置示例
(lxd_dump.stdout | from_yaml).storage_pools的实际结构是数组,示例内容如下:
[ { "config": { "source": "/data/nas/pool/lxd" }, "description": "", "driver": "dir", "name": "nas" }, { "config": { "source": "/var/lib/lxd/storage-pools/default" }, "description": "", "driver": "dir", "name": "default" } ]
解决方案
原条件的核心错误是没处理storage_pools为数组的特性,需要先筛选出名为nas的存储池,再判断其存在性和配置正确性。
方法1:用selectattr+first筛选存储池
先通过set_fact定义变量存储目标存储池,再写清晰的判断条件:
- name: LXD config dump shell: cmd: lxd init --dump register: lxd_dump - name: 提取nas存储池配置 set_fact: nas_storage_pool: "{{ (lxd_dump.stdout | from_yaml).storage_pools | selectattr('name', 'equalto', 'nas') | first | default(None) }}" - name: 创建/重建nas存储池 shell: cmd: lxc storage create nas dir source=/data/nas/pool/lxd when: > nas_storage_pool is none or nas_storage_pool.driver != 'dir' or nas_storage_pool.config.source != '/data/nas/pool/lxd'
方法2:用json_query直接筛选
如果习惯用json_query,可以直接在条件里做数组筛选:
- name: LXD config dump shell: cmd: lxd init --dump register: lxd_dump - name: 创建/重建nas存储池 shell: cmd: lxc storage create nas dir source=/data/nas/pool/lxd when: > (lxd_dump.stdout | from_yaml | json_query('storage_pools[?name==`nas`]') | length == 0) or (lxd_dump.stdout | from_yaml | json_query('storage_pools[?name==`nas`].driver | [0]') != 'dir') or (lxd_dump.stdout | from_yaml | json_query('storage_pools[?name==`nas`].config.source | [0]') != '/data/nas/pool/lxd')
注意事项
- 两种方法都会先判断
nas存储池是否存在,不存在则执行创建;若存在则检查驱动类型、存储源路径是否符合预期,任意一项不符就执行创建; - 注意字符串比较要加引号,比如
'/data/nas/pool/lxd',避免Ansible解析错误; lxc storage create无法修改已有存储池,如果需要修改配置而非重建,可以改用lxc storage set命令适配需求。
内容的提问来源于stack exchange,提问作者arniom
相关产品推荐
相关产品推荐

