ansible是否有yaml编辑模块?

ansible是否有yaml编辑模块?,ansible,Ansible,我需要修改一个yaml文件(),我想从ansible playbook中进行修改-有这样做的模块吗?谷歌很难做到这一点,出现的一切都是如何编写剧本。没有这样的模块。您可以通过查看 您最好使用或或模块。我还需要配置和管理yaml文件。我已经编写了一个ansible模块,它试图在编辑yaml文件时成为幂等的 我称之为yedit(yaml编辑) 如果你觉得有用,请告诉我。当我们的团队遇到需要时,我将通过请求或拉动请求添加功能 下面是一个简单的剧本示例: roles: - lib_yaml_editor

我需要修改一个yaml文件(),我想从ansible playbook中进行修改-有这样做的模块吗?谷歌很难做到这一点,出现的一切都是如何编写剧本。

没有这样的模块。您可以通过查看


您最好使用或或模块。

我还需要配置和管理yaml文件。我已经编写了一个ansible模块,它试图在编辑yaml文件时成为幂等的

我称之为yedit(yaml编辑)

如果你觉得有用,请告诉我。当我们的团队遇到需要时,我将通过请求或拉动请求添加功能

下面是一个简单的剧本示例:

roles:
- lib_yaml_editor

tasks:
- name: edit some yaml
  yedit:
    src: /path/to/yaml/file
    key: foo
    value: bar

- name: more complex data structure
  yedit:
    src: /path/to/yaml/file
    key: a#b#c#d
    value:
      e:
        f:  This is a test
应该生成如下所示的内容:

foo: bar
a:
  b:
    c:
      d:
        e:
          f: This is a test

编辑:2018年5月27日这里介绍了几种不同的方法:


实现这一点的一种方法是将文件读入事实,根据需要更新事实,然后将事实写回yaml文件

- name: Read the yaml
  slurp:
    path: myfile.yaml
  register: r_myfile

- name: extract the data
  set_fact:
    mydata: "{{ r_myfile['content'] | b64decode | from_yaml }}"
然后根据需要更新事实,例如使用

- name: Write back to a file
  copy:
    content: '{{ mydata | to_nice_yaml }}'
    dest: myfile.yaml
当然,您需要知道,这会使整个更新变得非原子化


更新:我最初的建议使用了查找('file'),但这当然会访问本地文件。slurp是读取远程文件的正确方法。

这是基于Kevin Keane的回答-我刚刚添加了事实修改部分。由于似乎无法编辑现有的答案(编辑队列已满),我只为(像我一样)来这里查找详细信息的任何人添加了这个

  • 从文件中读取YAML数据,并创建存储该数据的事实:

    - name: Read the yaml 
      slurp:
        path: myfile.yaml
      register: r_myfile
    
    - name: extract the data
      set_fact:
        mydata: "{{ r_myfile['content'] | b64decode | from_yaml }}"
    
  • 我找不到任何方法修改现有的Ansible词典。因此,实际修改数据的解决方法是创建一个与现有事实同名的新dict(
    mydata
    ),并使用
    combine
    过滤器根据需要更改键:

    - name: Create configuration for core - modify params
      set_fact:
        mydata: "{{ mydata | combine(newdata) }}"
      vars: 
        newdata:
          old_key: new_value
          new_key: new_value
    
  • 将修改后的数据写入文件:

    - name: Write back to a file
      copy:
        content: '{{ mydata | to_nice_yaml }}'
        dest: myfile.yaml
    
  • 结果:

    原始myfile.yaml:

     ---
     another_key: another_value  # This is a key that we will not touch
     old_key: old_value          # This is an old key, that we will change
    
    playbook执行后的文件:

     another_key: another_value
     new_key: new_value
     old_key: new_value
    

    请注意(正如您可能预期的那样)所有注释都已消失,因为您只是在读取YAML数据并将其写回。

    基于Kevin和Bogd的答案,如果您希望合并嵌套键而不是覆盖YAML文件的整个分支,则必须在combine函数中启用递归:

    mydata: "{{ mydata | combine(newdata, recursive=True) }}"
    
    从:

    递归的 是布尔值,默认为False。应该以递归方式合并嵌套哈希。注意:它不取决于ansible.cfg中hash_行为设置的值

    因此,完整的解决方案变成:

    - name: Open yaml file
      slurp:
        path: myfile.yaml
      register: r_myfile
    
    - name: Read yaml to dictionary
      set_fact:
        mydata: "{{ r_myfile['content'] | b64decode | from_yaml }}"
    
    - name: Patch yaml dictionary
      set_fact:
        mydata: "{{ mydata | combine(newdata, recursive=True) }}"
      vars: 
        newdata:
          existing_key:
            existing_nested_key: new_value
            new_nested_key: new_value
    
    - name: Write yaml file
      copy:
        content: '{{ mydata | to_nice_yaml }}'
        dest: myfile.yaml
    

    注意:递归仅允许添加嵌套键或替换嵌套值。删除特定的嵌套键需要更高级的解决方案。

    哇,非常感谢您的提醒-我会在开始时看一看,现在正忙于其他事情非常好的模块。。。我不知道现在你可以安装一个角色并直接使用它。。。简直让我大吃一惊。你能把这个加到Ansible星系吗?我已经把它加到Ansible星系了。唯一的缺点是为了让galaxy导入工具找到它,我不得不重命名。这是否适用于具有多个文档的yaml?如果是的话,你能给我举一个有效的例子吗?似乎你没有回答这个问题?在您所指的文档中,甚至没有提到编写YAML,更不用说读取修改后的数据并将其写入YAML文件了。那么您建议如何使用Ansible中常用的模块来实现这一点呢?我发现这个答案很有用,因为链接页面描述了修改(文本)文件的一系列可能性。尽管如此,这里提出的唯一可能在本例中应用的解决方案是
    lineinfle
    方法,该方法仅在简单的情况下有用。我建议Blockinfle以及关于如何更改yaml文件内容的更多细节,这将真正有助于发挥作用。@Josiah-这一点很好。我无法找到一种方法来更改Ansible中现有的词典。我能找到的唯一解决办法是创建一个同名的新事实,并根据需要使用
    组合
    过滤器替换原始dict中的键。似乎是一条可行的道路。