Search code examples
jsonansiblejinja2

Ansble - adding file contents to the dictionary


I need to add several dictionaries with file contents to one list for further use with the URI module. I'm doing it manually now, like this:

ansible.builtin.uri:
  method: POST
  body_format: json
  body:
    actions:
      - action: create
          file_path: ".gitlab-ci.yml"
          content: "{{ lookup('file', '.gitlab-ci.yml') }}"
      - action: create
          file_path: "README.md"
          content: "{{ lookup('file', 'README.md') }}"

I want to make this task universal so that I don't have to hard specify the name of the files:

ansible.builtin.set_fact:
  files:
   - .gitlab-ci.yml
   - README.md

ansible.builtin.uri:
  method: POST
  body_format: json
  body:
    actions: ["
      {% for fs in files -%}
      {
        'action': 'create',
        'file_path': '{{ fs }}',
        'content': '{{ lookup('file', fs) }}'
      }{% if not loop.last %},{% endif %}
      {%- endfor %}"
      ]

The content of the file is thus stored in the actions[*]content variable, but only as a string because the file contains markup. If you replace lookup with the line 'Hello World', the json is generated normally. Could you please tell me how to use loop and lookup to save the contents of a file with the content key in the actions variable?


Solution

  • Use the filter indent to properly indent the block. Then filter the structure by from_yaml

        actions: |
          {% filter from_yaml %}
          {% for fs in files %}
          - action: create
            file_path: {{ fs }}
            content: |
              {{ lookup('file', fs)|indent(4) }}
          {% endfor %}
          {% endfilter %}
    

    gives

      actions:
      - action: create
        content: |-
          Content of .gitlab-ci.yml
          line 2
          line 3
          # EOF
        file_path: .gitlab-ci.yml
      - action: create
        content: |-
          Content of README.md
          line 2
          line 3
          # EOF
        file_path: README.md
    

    You should be able to use it in the uri module

    - ansible.builtin.uri:
        method: POST
        body_format: json
        body: "{'actions': {{ actions|to_json }} }"
    

    (not tested)