使用 Ansible 替换 YAML 文件中的特定字符串

Posted

技术标签:

【中文标题】使用 Ansible 替换 YAML 文件中的特定字符串【英文标题】:Replace Specific String in YAML File using Ansible 【发布时间】:2019-12-21 12:40:33 【问题描述】:

我有一个使用 YAML 文件进行配置的 Web 应用程序。这是文件中的一个例外:

---
settings:
  domain: 127.0.0.1

我有一个 Ansible 剧本,它使用 lineinfile 模块将上面 YAML 文件中的 IP 地址替换为服务器的公共 IP 地址。

- name: Discovering Public Internet Protocol Address
  ipify_facts:
  register: public_ip

- name: Configuring Application with discovered Public IP
  lineinfile:
    dest: /application/path/settings.yml
    regexp: '^(.*)domain: (.*)$'
    line: 'domain:  ipify_public_ip '

这会找到 127.0.0.1 IP 并将其替换为公共服务器的 IP,但它会破坏 YAML 缩进如下:

---
settings:
domain: 54.12.33.3

问题:“域”与“设置”移动到同一行,我的 ruby​​ 应用程序无法运行迁移,因为它识别出 YAML 语法错误。

我不介意用另一个模块替换 lineinfile,但如果可能的话我想保留它。我已经为此苦苦挣扎了几个小时,并将感谢任何帮助。

【问题讨论】:

【参考方案1】:

作为一种快速解决方案,尝试使用 2 个空格 () 以获得更好的匹配和替换:

    regexp: '^.*domain: (.*)$'
    line: '  domain:  ipify_public_ip '

我确信可以对正则表达式进行其他改进,以使用 \s[:space:]

更新: 不需要从 regexp 开始的 .*。根据请求的评论更新。

【讨论】:

感谢您的回复。我根据您的说明更新了剧本(有 2 个空格),但没有奏效。这一次,这条线保持不变。 好吧,如果你是正则表达式 ('^ domain: (.*)$') 确实匹配你的文件,它应该可以工作。您可能通过 ansible 手动修改了文件。将更新我的回复以考虑到这一点。 在我第一次尝试时,我注意到它在底部添加了额外的 domain: $ip 行。我清理了文件并按照您的初始说明退休,它完美地修改了它。我不能感谢你。祝您有美好的一天!【参考方案2】:

您可以只创建一个 yaml 模板版本。

- template:
    src: /path/to/settings.tpl.yml
    dest: /path/to/settings.yml

settings.tpl.yml

---
settings:
domain:  public_ip 

【讨论】:

以上是关于使用 Ansible 替换 YAML 文件中的特定字符串的主要内容,如果未能解决你的问题,请参考以下文章

Ansible模块lineinfile替换指定行内容多行replace及j2的shell/yaml

YAML基础语法-ansible使用ansible-playbook

Ansible之playbook的使用

Ansible之playbook的使用

Ansible 2.5.5 - “替换”模块中的属性之前不起作用

Ansible playbook