merging dictionaries in ansible

前端 未结 6 930
日久生厌
日久生厌 2020-12-03 06:47

I\'m currently building a role for installing PHP using ansible, and I\'m having some difficulty merging dictionaries. I\'ve tried several ways to do so, but I can\'t get it

相关标签:
6条回答
  • 2020-12-03 06:50

    It is now possible to use the anchor and extend features of YAML:

    ---
    - hosts: localhost
      vars:
        my_default_values: &def
          key: value
        my_values:
          <<: *def
          my_key: my_value
      tasks:
        - debug: var=my_default_values
        - debug: var=my_values
    

    Result:

    TASK [debug]
    ok: [localhost] => {
        "my_default_values": {
            "key": "value"
        }
    }
    
    TASK [debug] 
    ok: [localhost] => {
        "my_values": {
            "key": "value", 
            "my_key": "my_value"
        }
    }
    

    I have no idea why this was not mentioned before.

    0 讨论(0)
  • 2020-12-03 06:53

    Try this role from Ansible Galaxy.

    I did it some time ago for same reason. It can deep merge dictionaries from several vars files and set custom precedence of merging.

    This role can work under Ansible 2.0+

    0 讨论(0)
  • 2020-12-03 06:59

    If you need the merged dictionary a few times, you can set it to a new "variable":

    - set_fact: _my_values="{{ my_default_values|combine(my_values) }}"
    
    - debug: msg="{{ item.key }} = {{ item.value }}"
      with_dict: _my_values
    
    0 讨论(0)
  • 2020-12-03 07:03

    If you want hash merging I would turn the hash merging feature on in ansible. In your ansible config file turn hash merging on.

    With hash_behaviour=merge you can have two var files with the same variable name:

    defaults.yml:

    values:
      key: value
    

    overrides.yml:

    values:
      my_key: my_value
    

    In order for the two vars to be merged you will need to include both var files:

    ansible-playbook some-play.yml ... -e@defaults.yml  -e@overrides.yml
    

    And you will end up with this:

    TASK: [debug var=values] ********************************************************
    ok: [localhost] => {
        "values": {
            "key": value,
            "my_key": my_value
        }
    }
    

    Calling update on a variable can be done in Jinja but in general it will be messy, I wouldn't do it outside of your templates and even then try to avoid it altogether.

    0 讨论(0)
  • 2020-12-03 07:06

    In Ansible 2.0, there is a Jinja filter, combine, for this:

    - debug: msg="{{ item.key }} = {{ item.value }}"
      with_dict: "{{ my_default_values | combine(my_values) }}"
    
    0 讨论(0)
  • 2020-12-03 07:16
    >>> key = 'default key'
    >>> value = 'default value'
    >>> my_key = 'my key'
    >>> my_value = 'my value'
    >>>
    >>> my_default_values = {key: value}
    >>> print my_default_values
    {'default key': 'default value'}
    >>>
    >>> my_values = {my_key: my_value}
    >>> print my_values
    {'my key': 'my value'}
    >>>
    >>> with_dict = my_default_value.copy()
    >>> print with_dict
    {'default key': 'default value'}
    >>> with_dict.update(my_values)
    >>> print with_dict
    {'default key': 'default value', 'my key': 'my value'}
    
    0 讨论(0)
提交回复
热议问题