Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strip quotes from a variable in Ansible

Tags:

regex

ansible

I'm trying to get the value of a variable in a file into an Ansible variable so I can use it.

Here's what I've got:

      - name: extract Unique Key
        shell: "grep UNIQUE_KEY ../config.py | cut -d' ' -f 3"
        register: command_output

      - set_fact:
          unique_key: x{{ command_output.stdout | regex_replace("^'", '') | regex_replace('^"', '') | regex_replace("'$", '') | regex_replace('"$', '')  }}

      - set_fact:
          unique_key: "{{ unique_key | regex_replace('^x', '') }}"

      - debug: var=unique_key

This works, but feels kludgy and looks ugly.

I've already tried to add sed to my original shell module, but I couldn't figure out how to get the quotes escaped correctly. I also couldn't figure out how to escape the regex_replace to get it to work in a single variable assignment.

Is there a simpler way to go from this:

"TEST"

or

'TEST'

to this:

TEST

in Ansible? (I'm also really new to Ansible so that's not helping either)

EDIT: After the answer by @Vladimir-Botka which I initially accepted, I found this issue:

If I don't strip the quotes and embed the variable in another variable, it keeps the quotes:

I need to use this value to construct a path:

    vars:
      service_location: "/opt/{{ unique_key }}-scheduler-service"

If I don't remove the quotes using my method above, The variable will contain the quotes as in this output of a debug statement:

ok: [fedorasvr1] => {
    "service_location": "/opt/'TEST'-scheduler-service"
}
like image 982
TheDavidFactor Avatar asked Jul 18 '19 21:07

TheDavidFactor


People also ask

How do you escape a single quote in Ansible?

In single-quoted characters, on the other hand, escape sequences using \ don't mean anything special to YAML. So you can use \[ to escape regex special characters.

How do you get Ansible facts?

To access the variables from Ansible facts in the Ansible playbook, we need to use the actual name without using the ansible keyword. The gather_facts module from the Ansible playbook runs the setup module by default at the start of each playbook to gather the facts about remote hosts.


1 Answers

The short answer is "omit the first and the last character" if the quotes are part of the string

      - set_fact:
          unique_key: command_output.stdout[1:-1]

Internal interpretation is all the same. The quotes control the expansion of the variables. See 7.3.1. Double-Quoted Style and 7.3.2. Single-Quoted Style.

As an example. The play below

    - hosts: localhost
      vars:
        var1: TEST
        var2: 'TEST'
        var3: "TEST"
      tasks:
        - template:
            src: test.j2
            dest: test

and the template

    shell> cat test.j2
    {{ var1 }}
    {{ var2 }}
    {{ var3 }}

give

    shell> cat test
    TEST
    TEST
    TEST

The quotes, if part of the string, can be removed. As an example the play below

    - hosts: localhost
      vars:
        regex: "[`'\"]"
        replace: ""
        service_location: "/opt/{{ item|regex_replace(regex, replace)
                                   }}-scheduler-service"
      tasks:
        - debug:
            var: service_location
          loop:
            - '`TEST`'
            - '"TEST"'
            - '''TEST'''
            - "'TEST'"

gives

    ok: [localhost] => (item=`TEST`) => 
      item: '`TEST`'
      service_location: /opt/TEST-scheduler-service
    ok: [localhost] => (item="TEST") => 
      item: '"TEST"'
      service_location: /opt/TEST-scheduler-service
    ok: [localhost] => (item='TEST') => 
      item: '''TEST'''
      service_location: /opt/TEST-scheduler-service
    ok: [localhost] => (item='TEST') => 
      item: '''TEST'''
      service_location: /opt/TEST-scheduler-service

It is also possible to use custom filter_plugins/string_filters.py which might be more convenient than complex escape constructs.

As an example. The play below

    - hosts: localhost
      vars:
        replace: ""
        service_location: "/opt/{{ item.0|string_replace(item.1, replace)
                                   }}-scheduler-service"
      tasks:
        - debug:
            var: service_location
          with_together:
            - - '`TEST`'
              - '"TEST"'
              - "'TEST'"
            - - '`'
              - '"'
              - "'"

gives

    ok: [localhost] => (item=[u'`TEST`', u'`']) => 
      item:
      - '`TEST`'
      - '`'
      service_location: /opt/TEST-scheduler-service
    ok: [localhost] => (item=[u'"TEST"', u'"']) => 
      item:
      - '"TEST"'
      - '"'
      service_location: /opt/TEST-scheduler-service
    ok: [localhost] => (item=[u"'TEST'", u"'"]) => 
      item:
      - '''TEST'''
      - ''''
      service_location: /opt/TEST-scheduler-service

FWIW, see other examples of filter_plugins.

like image 171
Vladimir Botka Avatar answered Oct 07 '22 13:10

Vladimir Botka