5076

How to fallback to a default value when ansible lookup fails?

Question:

I was a little bit surprised to discover that his piece of code fails with an IOError exception instead of defaulting to omitting the value.

#!/usr/bin/env ansible-playbook -i localhost, --- - hosts: localhost tasks: - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') | default(omit) }}"

How can I load a value without raising an exception?

Please note that the lookup module supports a default value parameter but this one is useless to me because it works only when it can open the file.

I need a default value that works even when the it fails to open the file.

Answer1:

As far as I know Jinja2 unfortunately doesn't support any try/catch mechanism.

So you either patch ini lookup plugin / file issue to Ansible team, or use this ugly workaround:

--- - hosts: localhost gather_facts: no tasks: - debug: msg="{{ lookup('first_found', dict(files=['test-ini.conf'], skip=true)) | ternary(lookup('ini', 'foo section=DEFAULT file=test-ini.conf'), omit) }}"

In this example first_found lookup return file name if file exists or empty list otherwise. If file exists, ternary filter calls ini lookup, otherwise omit placeholder is returned.

Answer2:

To avoid the error when the path doesn't exist, use a condition to check for the path before attempting the lookup:

--- - hosts: localhost tasks: - debug: msg="{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}" when: missing-file.conf | exists

You can use this with set_fact as well, then omit the undefined var when using it if required:

- hosts: localhost tasks: - set_fact: foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}" when: missing-file.conf | exists - debug: var: foo # undefined msg: "{{ foo | default(omit) }}" # omitted

Note that lookups and <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-paths" rel="nofollow">Jinja2 tests</a> run on the <em>controller</em>. If you need to check the path on the host, use the stat and either slurp or fetch modules:

- stat: file: missing-remote-file-with-text-i-want register: file - slurp: src: missing-remote-file-with-text-i-want register: slurp when: file.stat.exists - set_fact: foo: "{{ slurp.content | b64decode }}" when: file.stat.exists - fetch: src: missing-file.conf dest: /tmp/fetched fail_on_missing: False - set_fact: bar: "{{ lookup('ini', 'foo section=DEFAULT file=/tmp/fetched/' + inventory_hostname + '/missing-file.conf') }}" when: ('/tmp/fetched/' + inventory_hostname + '/missing-file.conf') | exists

Second note, in Ansible v2.5 the grammar for using the path tests was changed, the format is now:

- set_fact: foo: "{{ lookup('ini', 'foo section=DEFAULT file=missing-file.conf') }}" when: missing-file.conf is exists

Recommend

  • INSERT INTO View, INSTEAD OF Trigger, Identity, multiple tables?
  • MongoDB - Check if value exists for a field in a document
  • Is the scope of Responsive Design worth considering for IE8 as of 2013?
  • Angular 4 using ngComponentOutlet to display dynamically changing ContentChildren
  • ObjectDisposedException on a ASP.NET Core 2.0 MVC custom database initializer class
  • JPA EntityManager and JavaFx [duplicate]
  • How to add database query results to an array
  • Can you review my Perl rewrite of Cucumber?
  • Sequelize belongsToMany additional attributes in join table
  • Use a keras model in a custom keras loss
  • How to expire a session if user leave an interface for 2 minutes? ASP.NET
  • Excel VBA: Forward ParamArray to Application.Run
  • Mocking OpenXML with Moq
  • Decompress string in java from compressed string in C#
  • ARKit – Rendering a 3D object under an invisible plane
  • PySpark: Get first Non-null value of each column in dataframe
  • What is the diff. between default.properties and project.properties?
  • Making query to find nearest multiple(Lat,Long) from the single(Lat,Long)
  • Implementing and using MinMax with four in row (connect4) game
  • How to intercept local server web requests using Burp in Internet Explorer
  • How to create mirrored image effect with CSS single element
  • Modifying native query cannot have named parameter bindings?
  • Adding native code to an existing Worklight hybrid app
  • cSPADE data mining in R using arulesSequences - Error while converting to “transactions” format
  • Unable to start a WebView from an AsyncTask
  • how to add dashed border on highcharts “area” graph for every point
  • Swift manually rotate view controller
  • C# code can't “see” the methods in my C++ dll
  • How to use Typescript with libraries like Ampersand.js that parse configs to build prototypes
  • Copy and paste data from multiple workbooks to a worksheet in another Workbook
  • All Event listing on specified date in Google Calender api (V3) in java?
  • What is the difference between dynamically creating a script tag and statically embed a script tag?
  • How to run chrome.tabs.insertCSS from the background page on each page?
  • java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/SpringDispatcher-ser
  • jQuery scrollTop if URL has hash
  • Background transfer download task failed when app was closed
  • ssh remote server login script
  • media foundation H264 decoder not working properly