var values in the same line

Hi all,

We have a role var defined for every role like bellow :

roles/db/vars/main.yml :

role : db

roles/web/vars/main.yml :

role : web

roles/app/vars/main.yml :

role : app

We need to have this var a specific “config :” line in a configuration file in a way that will be the same if we run 1 single role on a host or all roles :

if we only run the db role the file should be :

/etc/file.conf :

config: role : db

if we run all roles on the host the file should look like :

/etc/file.conf :

config: role : db, role: web, role:app

This might look simple but I’m having a hard time to code the logic in Ansible… any ideas ?

Thanks in advance.

Hi Nicolas,

thinking about a regexp that check and add the string below if not present (e.g: with lineinfile)
role:

it will use the negative look ahead pattern of regexp

I will pass it to you tomorrow if someone else do not beat me

Stay tuned

Phil

Thank you Phil that will be great.

Looking forward to see your solution.

Nicolas,

for clarity I made a small modification to you specification so the config file contains something like below

role: common,web,app,db

then you can use this regexp to check that rolename is not already part of the list

(^role\s*[:]\s*(?!rolename)[\w]+)((,(?!rolename)[\w]+)*)$

for the explanations you can use: https://regex101.com/
to see what’s happening

copy the regexp above in the “Regular Expression” field

for the test use the string below:
role: rolenam1,common,app,web,rolenam2,db,rolenam3

look at the “MATCH INFORMATION” window and you will get it I think

change rolenam1 to rolename => no match

that will be the same for rolenam2 or rolename3

to show the position of the decl does not matter.

then from an Ansible perspective

each role can have a task like below, that will append the rolename to the list if not already done

vars:

  • therole: “rolename”
  • string: “role: common”

tasks:

  • name: check if config exist
    stat: path=“/tmp/config”
    register: stat_result

  • name: start with a basis /tmp/config file
    shell: echo “{{ string }}” > /tmp/config
    when: stat_result.stat.exists == False

  • name: Append rolename string to the list if not present already
    lineinfile:
    dest=/tmp/config
    backrefs=True
    state=present
    regexp=‘(^role\s*[:]\s*(?!rolename)[\w]+)((,(?!rolename)[\w]+)*)$’
    line=‘\1\2,rolename’

it will be easy to :

  • parameterize the rolename string with an ansible variable

relace it with {{therole}} in the lineifile task

  • adapt back to you original spec (config: role:app, role:web)

  • deal with any number of white spaces

there is one limitation: the need to have a firt role being declared in the config.

It is possible to address this but then the regex will be, say, harder to read

HTH

Phil

sorry to answer my own post

I should have put a ref to https://regex101.com/r/xQ6tI0/1