7

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"
}
U880D
  • 8,601
  • 6
  • 24
  • 40
TheDavidFactor
  • 1,647
  • 2
  • 19
  • 18

2 Answers2

6

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.

Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
0

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}}"
nettie
  • 628
  • 1
  • 11
  • 23