Search code examples
ansiblesyntax-error

How to pass parameters to task from file


I create a file with a content and I need to pass this to my task paramaters:

The original tasks is like this:

- name: Configure Web filter profiles.
  fortinet.fortios.fortios_webfilter_profile:
    vdom: "{{ vdom }}"
    state: "present"
    access_token: "x4jcqmpwhrgdjw0p4qnHcw35m5GH63"
    webfilter_profile:
      feature_set: flow
      name: "{{ wf_name }}"
      ftgd_wf:
        options: "error-allow"
        filters:
            -
              action: "block"
              category: "41"
              id: "41"
              log: "enable"
              warn_duration: "5m"
              warning_duration_type: "timeout"
              warning_prompt: "per-category"
        max_quota_timeout: "300"
        rate_crl_urls: "enable"
        rate_css_urls: "enable"
        rate_javascript_urls: "enable"

When I use this playbook works fine but I need to create multiple lines for multiples IDs, something like this:

- name: Configure Web filter profiles.
  fortinet.fortios.fortios_webfilter_profile:
    vdom: "{{ vdom }}"
    state: "present"
    access_token: "x4jcqmpwhrgdjw0p4qnHcw35m5GH63"
    webfilter_profile:
      feature_set: flow
      name: "{{ wf_name }}"
      ftgd_wf:
        options: "error-allow"
        filters:
            -
              action: "block"
              category: "41"
              id: "41"
              log: "enable"
              warn_duration: "5m"
              warning_duration_type: "timeout"
              warning_prompt: "per-category"
            -
              action: "block"
              category: "42"
              id: "42"
              log: "enable"
              warn_duration: "5m"
              warning_duration_type: "timeout"
              warning_prompt: "per-category"
            -
              action: "block"
              category: "42"
              id: "42"
              log: "enable"
              warn_duration: "5m"
              warning_duration_type: "timeout"
              warning_prompt: "per-category"
            (--- etc ids)
        max_quota_timeout: "300"
        rate_crl_urls: "enable"
        rate_css_urls: "enable"
        rate_javascript_urls: "enable"

So I create a file using lineinfile modules to add lines as Id numbers exists:

- name: Create file
  file:
    path: "/tmp/wf_content.txt"
    state: touch
    mode: '0775'

- name: Add lines in file
  lineinfile:
    path: "/tmp/wf_content.txt"
    line: |
          '-
            action: "block"
            category: "{{ item }}"
            id: "{{ item }}"
            log: "enable"
            warn_duration: "5m"
            warning_duration_type: "timeout"
            warning_prompt: "per-category"'
  loop: "{{ id_number }}"

- name: remove blank lines in file
  shell: "sed -e '/^[[:blank:]]*$/d' wf_content.txt > wf_content2.txt"
  args:
    chdir: "/tmp/"

But when I replace the content of task from my file I got "dictionary requested, could not parse JSON or key=value"

My full playbooks is the next:

- name: Create file with context to fortinet
  hosts: localhost
  become: false
  gather_facts: false
  vars_files:
    vars_fortinet.yml

  tasks: 

    - name: Create file
      file:
      path: "/tmp/wf_content.txt"
      state: touch
      mode: '0775'

    - name: Add lines in file
      lineinfile:
        path: "/tmp/wf_content.txt"
        line: |
            '-
              action: "block"
              category: "{{ item }}"
              id: "{{ item }}"
              log: "enable"
              warn_duration: "5m"
              warning_duration_type: "timeout"
              warning_prompt: "per-category"'
      loop: "{{ id_number }}"

    - name: remove blank lines in file
      shell: "sed -e '/^[[:blank:]]*$/d' wf_content.txt > wf_content2.txt"
      args:
        chdir: "/tmp/"

- name: Test connection to fortinet
  hosts: fortinet
  connection: httpapi
  become: false
  vars:
  ansible_httpapi_use_ssl: yes
  ansible_httpapi_validate_certs: false
  ansible_network_os: fortinet.fortios.fortios
  vdom: "VDOM_BOT"
  wf_name: wf_10_0_0_3
# Esto debe pasarlo el chatbot -- Convertir la IP de punto a subguión
  vars_files:
    vars_fortinet.yml  

  tasks:

  - name: Get values from file
    shell: "cat /tmp/wf_content2.txt"
    register: output

  - name: Configure Web filter profiles.
    fortinet.fortios.fortios_webfilter_profile:
      vdom: "{{ vdom }}"
      state: "present"
      access_token: "x4jcqmpwhrgdjw0p4qnHcw35m5GH63"
      webfilter_profile:
        feature_set: flow
        name: "{{ wf_name }}"
        ftgd_wf:
          options: "error-allow"
          filters:
            "{{ output.stdout_lines }}"
          max_quota_timeout: "300"
          rate_crl_urls: "enable"
          rate_css_urls: "enable"
          rate_javascript_urls: "enable"

I hope you can help with this and sorry for my bad English.


Solution

  • Given the list ids

    ids: [41, 42, 43]
    

    Create a template instead of a text file. For example,

    shell> cat wf_content.j2
    {% filter from_yaml %}
    {% for id in ids %}
    - action: block
      category: {{ id }}
      id: {{ id }}
      log: enable
      warn_duration: 5m
      warning_duration_type: timeout
      warning_prompt: per-category
    {% endfor %}
    {% endfilter %}
    

    Create the list filters

      filters: "{{ lookup('template', 'wf_content.j2') }}"
    

    gives

      filters:
      - action: block
        category: 41
        id: 41
        log: enable
        warn_duration: 5m
        warning_duration_type: timeout
        warning_prompt: per-category
      - action: block
        category: 42
        id: 42
        log: enable
        warn_duration: 5m
        warning_duration_type: timeout
        warning_prompt: per-category
      - action: block
        category: 43
        id: 43
        log: enable
        warn_duration: 5m
        warning_duration_type: timeout
        warning_prompt: per-category
    

    Use it in the module. Put the declaration, for example, into the task's vars

    - name: Configure Web filter profiles.
      fortinet.fortios.fortios_webfilter_profile:
        vdom: "{{ vdom }}"
        state: present
        access_token: "x4jcqmpwhrgdjw0p4qnHcw35m5GH63"
        webfilter_profile:
          feature_set: flow
          name: "{{ wf_name }}"
          ftgd_wf:
            options: error-allow
            filters: "{{ filters }}"
      ...
      vars:
        filters: "{{ lookup('template', 'wf_content.j2') }}"