TheDavidFactor
TheDavidFactor

Reputation: 1741

How to strip quotes from a variable in 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"
}

Upvotes: 8

Views: 26098

Answers (3)

Peter Turner
Peter Turner

Reputation: 11435

I believe this may be the simplest way to strip double quotes:

{{ ""My oddly quoted string" | from_json }}

I had an issue upgrading ansible where the json value was no longer being returned (Because my uri module wasn't actually returning json) so I couldn't trick ansible into populating something in the json response and I had to go back to using content.

Because these were passwords and we didn't notice this for a week this led to much sadness and explanations of "just add quotes around your password when you type it next time"

We were going to implement the other solutions here to remove quotes using regex, but I thought, lets just do what ansible was going to do in the first place and see if that works, and it did - very well.


note, this will only work for double quotes. But if you use single quotes to quote a string, you're probably going to have a purist/linter fix your code so you might as well be proactive

Upvotes: 0

nettie
nettie

Reputation: 692

Slightly different, but maybe related: I was getting unwanted quotes when using a lookup to initialize a variable which were then used in a "blockinfile" task. But it turns out the quotes were caused by the "blockinfile" and not the lookup, ie:

- name: set some variables
      set_fact: 
        my_var: "{{ lookup('ini', 'my_var section=variables  file=~/myconf.ini') }}" 



- name: update myconf.cfg
      blockinfile: 
        dest: myconf.cfg                                   
        state: present
        create: true
        owner: "{{user}}"
        group: "{{user}}"
        block: |
               [Credentials]
               access_key_id = blabla
               secret_access_key = "{{my_var}}"
      become: true

removing the quotes from this line worked:

secret_access_key = "{{my_var}}"

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68034

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.

Upvotes: 8

Related Questions