Search code examples
filteransiblejinja2

How can I filter certain element in a string


playbook.yml

---
  hosts: local_host
  connection: local
  gather_facts: False
  tasks:
  - name: set-details
    set_fact:
      filter: "{{ lookup('file', 'tmp/task2.yml') | from_json }}"

  - set_fact:
      result: "{{ filter['msg'] }}"

  - debug:
      var: result

task2.yml

{
    "ansible_loop_var": "item",
    "_ansible_no_log": false,
    "invocation": {
        "module_args": {
            "wait_for_task": true,
            "policy_package": "Mills07_Simplified",
            "version": null,
            "wait_for_task_timeout": 30
        }
    },
    "item": "Mills07_Simplified",
    "changed": false,
    "msg": "Task Verify policy operation with task id 01234567-89ab-cdef-928b-bef7e174fc7a failed. Look at the logs for more details",
    "_ansible_item_label": "Mills07_Simplified"
}

debug message

TASK [debug] *****************************************************************************************************************************************************************************
ok: [localhost] => {
    "result": "Task Verify policy operation with task id 01234567-89ab-cdef-928b-bef7e174fc7a failed. Look at the logs for more details"
}

When I did the following,

  - set_fact:
      task_id: "{{ result |
                   select('regex', my_regex)|
                   first|
                   regex_replace(my_regex, my_replace) }}"

      vars:
        my_regex: '^Task Verify policy operation with task id (.*)$'
        my_replace: '\1'
  - debug:
      var: task_id 

I got an error message

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'my_regex' is undefined\n\nThe error appears to be in 

Goal: I want to get the task-id "01234567-89ab-cdef-928b-bef7e174fc7a"

How can I get this string 01234567-89ab-cdef-928b-bef7e174fc7a


Solution

  • Since you are looking for a universally unique identifier (or UUID) which has a defined format of 8-4-4-4-12 characters for a total of 36 characters (32 hexadecimal characters and 4 hyphens) source, you can use a simple regex to extract it.

    It can be handled with the following regex:

    [0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}
    

    You can test it there: https://regex101.com/r/4Hs7il/1

    So, in a set_fact:

    - set_fact:
        uuid: >- 
          {{ filter.msg 
              | regex_search(
                  '([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})', 
                  '\1', 
                  ignorecase=True
                ) 
              | first 
          }}
    

    As an example:

    - set_fact:
        uuid: >- 
          {{ filter.msg 
              | regex_search(
                  '([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})', 
                  '\1', 
                  ignorecase=True
                ) 
              | first 
          }}
      vars:
        filter:
          msg: >-
            Task Verify policy operation with task
            id 01234567-89ab-cdef-928b-bef7e174fc7a failed.
            Look at the logs for more details
    - debug:
        var: uuid
    

    Would yield:

    TASK [set_fact] ***************************************************
    ok: [localhost]
    
    TASK [debug] ******************************************************
    ok: [localhost] => 
      uuid: 01234567-89ab-cdef-928b-bef7e174fc7a