You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ansible replace模块修改resolved.conf无实际变更问题求助

问题

使用Ansible的replace模块修改/etc/systemd/resolved.conf时,任务日志显示成功完成1处替换,但实际查看文件发现#DNS=行并未被修改为指定的DNS条目。相关配置、日志及文件现状如下:

配置代码

vars.yml:

dns_server: "192.168.22.12 192.168.22.13"
#dns_server: "192.168.22.12,192.168.22.13"

Ansible任务:

- name: Handle user DNS entry for /etc/systemd/resolved.conf
  ansible.builtin.set_fact:
    DNS_ENTRY: "{{ dns_server is defined | regex_replace(',', ' ') }}"
  when: 
    - dns_server is defined and dns_server is defined | regex_search(',')

- name: Use original user entry if no comma found
  ansible.builtin.set_fact:
    DNS_ENTRY: "{{ dns_server }}"
  when: 
    - dns_server is defined and not dns_server| regex_search(',')

- name: Ensure DNS configuration is set in resolved.conf
  ansible.builtin.replace:
    path: /etc/systemd/resolved.conf
    regexp: '^#DNS='
    replace: 'DNS={{ DNS_ENTRY }}'

任务执行日志

TASK [Handle user DNS entry for /etc/systemd/resolved.conf] ********************
task path: /opt/vi/firstboot/ansible/tasks/10-network.yml:33
skipping: [127.0.0.1] => {
    "changed": false,
    "skip_reason": "Conditional result was False"
}

TASK [Use original user entry if no comma found] *******************************
task path: /opt/vi/firstboot/ansible/tasks/10-network.yml:39
ok: [127.0.0.1] => {
    "ansible_facts": {
        "DNS_ENTRY": "192.168.22.12 192.168.22.13"
    },
    "changed": false
}

TASK [Ensure DNS configuration is set in resolved.conf] ************************
task path: /opt/vi/firstboot/ansible/tasks/10-network.yml:45
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995 `" && echo ansible-tmp-1709713866.0024374-2195-81793838038995="` echo /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995 `" ) && sleep 0'
Using module file /usr/lib/python3/dist-packages/ansible/modules/replace.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-1398ho9ozv7y/tmpfbiy0ps4 TO /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995/AnsiballZ_replace.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995/ /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995/AnsiballZ_replace.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995/AnsiballZ_replace.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1709713866.0024374-2195-81793838038995/ > /dev/null 2>&1 && sleep 0'
changed: [127.0.0.1] => {
    "changed": true,
    "invocation": {
        "module_args": {
            "after": null,
            "attributes": null,
            "backup": false,
            "before": null,
            "encoding": "utf-8",
            "group": null,
            "mode": null,
            "owner": null,
            "path": "/etc/systemd/resolved.conf",
            "regexp": "^#DNS=",
            "replace": "DNS=192.168.22.12 192.168.22.13",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "unsafe_writes": false,
            "validate": null
        }
    },
    "msg": "1 replacements made"
}

实际文件内容

cat /etc/systemd/resolved.conf
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it under the
#  terms of the GNU Lesser General Public License as published by the Free
#  Software Foundation; either version 2.1 of the License, or (at your option)
#  any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file, or by creating \"drop-ins\" in
# the resolved.conf.d/ subdirectory. The latter is generally recommended.
# Defaults can be restored by simply deleting this file and all drop-ins.
#
# Use 'systemd-analyze cat-config systemd/resolved.conf' to display the full config.
#
# See resolved.conf(5) for details.

[Resolve]
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
# Google:     8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
# Quad9:      9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
#DNS=
#FallbackDNS=
#Domains=
#DNSSEC=no
#DNSOverTLS=no
#MulticastDNS=no
#LLMNR=no
#Cache=no-negative
#CacheFromLocalhost=no
#DNSStubListener=yes
#DNSStubListenerExtra=
#ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no

排查与解决

1. 正则表达式匹配范围不足

你的regexp: '^#DNS='使用了^(行首锚定),但如果目标#DNS=行前存在空格或制表符(可能肉眼难以察觉),这个正则就无法匹配到目标行。而Ansible日志显示的1处替换,大概率是匹配到了文件中其他符合^#DNS=规则的行(比如注释里的某行)。

解决方法:修改正则表达式,允许行首有任意空白字符:

regexp: '^\s*#DNS='

\s*表示匹配0个或多个空白字符(空格、制表符),这样无论目标行是否缩进,都能准确匹配。

2. 修复set_fact任务的条件错误

第一个set_fact任务的条件存在语法错误:dns_server is defined | regex_search(',')是对布尔值dns_server is defined执行正则匹配,这显然不符合预期,应该直接对dns_server做正则检查。修改后的任务:

- name: Handle user DNS entry for /etc/systemd/resolved.conf
  ansible.builtin.set_fact:
    DNS_ENTRY: "{{ dns_server | regex_replace(',', ' ') }}"
  when: 
    - dns_server is defined
    - dns_server | regex_search(',')

3. 验证匹配目标行

在执行replace任务前,先添加一个shell任务确认目标行的格式:

- name: Check target DNS line format
  ansible.builtin.shell: grep -n "\s*#DNS=" /etc/systemd/resolved.conf
  register: dns_line
- name: Print DNS line details
  ansible.builtin.debug:
    var: dns_line.stdout

这能帮你确认目标行是否有缩进,以及具体位置。

4. 启用备份验证替换结果

给replace模块添加backup: yes参数,执行后会在原文件目录生成带时间戳的备份文件,对比备份文件和修改后的文件,就能清楚看到替换的具体内容:

- name: Ensure DNS configuration is set in resolved.conf
  ansible.builtin.replace:
    path: /etc/systemd/resolved.conf
    regexp: '^\s*#DNS='
    replace: 'DNS={{ DNS_ENTRY }}'
    backup: yes

内容的提问来源于stack exchange,提问作者cz75ww

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:37:03