Working with with_items and some filter

Hey ho,

I would like to deploy an application to several vhosts is item.useApplication exists. I am possible to do that, download files and so on and so on. But I get a problem as soon as I want to do an action if the application is never installed.

Normally:

  • stat: path=/etc/.git

register: exists_git

ignore_errors: yes

  • lineinfile: dest=/etc/rkhunter.conf line=‘ALLOWHIDDENDIR=“/etc/.git”’ owner=root group=root mode=0644

when: exists_git.stat.exists

But how is it possible for me to do this combined with “with_items”? One approach, that (untested) will not work in my opinion:

  • stat: path=/etc/.git
    register: exists_git_{{ item.name }}
    with_items: hosts
    when: item.useApplication
    ignore_errors: yes

  • lineinfile: dest=/etc/rkhunter.conf line=‘ALLOWHIDDENDIR=“/etc/.git”’ owner=root group=root mode=0644
    with_items: hosts
    when: item.useApplication
    when: exists_git_{{ item.name }}.stat.exists

Is someone able to help me here?

Have a nice week,
Greetings from Bochum, RuhrArea, Germany,

Bastian

PS: rkhunter is just a demonstration how I do this normally^^.

You can’t say “when:” twice, but you can feed it a list.

when:

  • item.useApplication
  • other_conditional

What you are doing with building a variable name in a conditional is a little weird, and this doesn’t work.

Rather, register when used with “with_items” will return an array, which you can easily debug:

  • stat: path=/etc/.git
    register: stats
    with_items: hosts
    when: item.useApplication

  • debug: var=stats

Though ultimately, it looks like you should drop the lineinfile and just include your logic in a template, and it will be much cleaner and easier.

Hey ho,

You can’t say “when:” twice, but you can feed it a list.

when:

  • item.useApplication
  • other_conditional

perfect!

What you are doing with building a variable name in a conditional is a little weird, and this doesn’t work.

Rather, register when used with “with_items” will return an array, which you can easily debug:

  • stat: path=/etc/.git
    register: stats
    with_items: hosts
    when: item.useApplication

  • debug: var=stats

Though ultimately, it looks like you should drop the lineinfile and just include your logic in a template, and it will be much cleaner and easier.

I do that with templates but I want to unzip, move and copy some files to create a perfect application environment. Perhaps your return of an array will solve my problem^^.

As soon as I tried this solution I will give you an answer! Thanks for the moment!

I am not able to figure out which array position is important for the current item as:

hosts:

  • 1 - noApplication ( ID = 3 )
  • 2 - Application ( ID = 2 )
  • 3 - Application ( ID = 42 )

would be

  • 1 ( ID = 2 )
  • 2 ( ID = 42 )

And I see no way to match those… Any Idea? Or is it possible without a lot of problems to create a plugin in ansible to solve this problem?

Sorry, I’m no following the above.

Can we step back a moment?

This appears to be a playbook that fixes various things in particular git directories, if found, for a very large number of git directories?

Knowing what you are trying to do might help suggest a more idiomatic solution.

Okay =).

I could write it down in some kind of PHP so you get my point.

I have got:

hosts:

  • name: “domain.tld”
    database:
    name: test
    user: test
    pw: test
    systemUser: domain
    useApplication: true

This will create me /var/www/domain.tld with everything I normally need. No I add “useApplication” for example ownCloud.
The steps I need to do are:

  • Download Zip File
  • Extract Zip File
  • Move Content of ZipFile Around ( important as owncloud.zip contains a folder named owncloud/ )
  • Install a Template for the Settings
  • Run a Database Dummy
  • Remove WebDav
  • Restart Apache

But only do that if there is no locking file. I do not want to have all of this done on each run and need some kind of if( ! file_exists(lockfile) ) doEverything();
And all of this should of course only happen if useApplication is set to true^^.

foreach($hosts as $item) {
if( $item->useApplication ) {
if( ! file_exsists( $item->getLockfile() ) ) {
doAllAbove();
}
}
}

Is this more clear?

Not really.

Is the issue you have a delegated host action that you only want to run once?

If so you could factor this out to an action that happens last in the playbook.

Not only once a run, I want to have it run only to install it^^.

So if the vhost Application is already installed I don’t want to have the package to unzip anymore, move files around or run the database dummy. I am able to control this behavior without “with_items” but as soon as I a have an array of informations to be checked for each I am not able to

Another option would be to register the stats informations into my “item” from the config array so I am able to say:

  • name: whatever
    whatever command
    with_items: hosts
    when: item.myFile.stats.exists

Easy what I need to do: