Ansible lineinfile模块无法向已有inventory文件插入重复行,如何解决?
解决Ansible inventory文件重复行无法插入组变量的问题
问题根源
你当前用lineinfile逐条添加配置行时,像ansible_user=administrator这类通用配置,因为其他VM组已经存在相同行,模块会判定该行已存在,不会为当前目标组的vars块插入这些行——只有ansible_password因每个组值不同,才会被正常插入。
方案一:改进lineinfile绑定组变量块
给每个lineinfile任务指定insertafter和regexp,确保配置行仅插入到当前组的[group:vars]块下,避免和其他组的重复行冲突。修改后的代码如下:
- name: 添加Windows虚拟机连接参数 ansible.builtin.lineinfile: path: /home/ansible/inventory/hosts line: "{{ item.line }}" insertafter: "{{ item.insertafter }}" regexp: "{{ item.regexp | default('^' + item.line + '$') }}" with_items: - { line: '[{{ group_names[0] }}:vars]', insertafter: EOF } - { line: 'ansible_user=administrator', insertafter: '^\[{{ group_names[0] }}:vars\]$', regexp: '^ansible_user=' } - { line: "ansible_password='{{ lookup('file', '/home/ansible/directory/file_'+group_names[0] ) }}'", insertafter: '^\[{{ group_names[0] }}:vars\]$', regexp: '^ansible_password=' } - { line: 'ansible_connection=winrm', insertafter: '^\[{{ group_names[0] }}:vars\]$', regexp: '^ansible_connection=' } - { line: 'ansible_port=5986', insertafter: '^\[{{ group_names[0] }}:vars\]$', regexp: '^ansible_port=' } - { line: 'ansible_winrm_server_cert_validation=ignore', insertafter: '^\[{{ group_names[0] }}:vars\]$', regexp: '^ansible_winrm_server_cert_validation=' } delegate_to: localhost
关键改动说明
- 用
insertafter指定每一行必须插入到当前组的[group:vars]块之后,确保配置归属当前组 - 给通用变量行设置
regexp(比如^ansible_user=),仅匹配当前组vars块下的对应变量行,不会干扰其他组的相同配置 - 组标题行直接插入到文件末尾(不存在时)
方案二:用blockinfile批量管理组变量块
blockinfile更适合整块内容的管理,直接为当前组生成完整的vars块,彻底避免逐行匹配的问题。代码如下:
- name: 批量添加Windows虚拟机连接参数块 ansible.builtin.blockinfile: path: /home/ansible/inventory/hosts marker: "# {mark} ANSIBLE MANAGED BLOCK - {{ group_names[0] }} VARS" block: | [{{ group_names[0] }}:vars] ansible_user=administrator ansible_password='{{ lookup('file', '/home/ansible/directory/file_'+group_names[0] ) }}' ansible_connection=winrm ansible_port=5986 ansible_winrm_server_cert_validation=ignore delegate_to: localhost
优势
- 每个组的vars块有唯一标记(包含组名),不会和其他组的块混淆
- 若组的vars块已存在,自动更新为最新内容;不存在则插入到文件末尾
- 结构清晰,维护成本远低于逐行的
lineinfile
注意事项
- 确保
group_names[0]能正确获取目标组名,避免空值或错误组名 - 检查Ansible执行用户对
/home/ansible/directory/下文件的读取权限 - 手动编辑的inventory内容不会被
blockinfile影响,仅管理标记包裹的块
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

