Add InfluxDB settings in Telegraf using Ansible: [WARNING]: The value [...] (type list) in a string field was converted to "[...]" (type string)

Posted by ads' corner on Tuesday, 2020-06-23
Posted in [Ansible][Influxdb][Linux][Software]

I’m in the process of updating my entire home setup, and integrate everything properly. Part of this process is to automate everything, and use Ansible Playbooks to deploy devices and configurations.

Today: install Telegraf and send data to InfluxDB

Along the way something broke, and Ansible doesn’t really like me anymore. But let’s start at the beginning.

In the Telegraf configuration in /etc/telegraf/telegraf.conf one can specify output plugins. One of them (probably the most used one) is “InfluxDB”. The InfluxDB instance(s) are specified as a [...] list. In Ansible I somehow need to have this list as a string, and write it into the configuration file. This happens:

TASK [Update telegraf.conf InfluxDB settings] ***************************************************
changed: [localhost] => (item={'section': '[outputs.influxdb]', 'option': 'urls', 'value': [''], 'state': 'present'})
[WARNING]: The value [''] (type list) in a string field was converted to "['']" (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.

Looks nasty …

The Playbook I’m using:

  # setup the InfluxDB output plugin
  - name: Update telegraf.conf InfluxDB settings
      path: "/etc/telegraf/telegraf.conf"
      section: "{{ item.section }}"
      option: "{{ item.option }}"
      value: "{{ item.value }}"
      state: "{{ item.state }}"
      - { section: "[outputs.influxdb]", option: "urls", value: "{{ influxdb_url }}", state: present }
      - restart telegraf

The Task is a bit longer than that, but for this purpose the above example is enough. Note that even though the [ini_file]( plugin understands sections, you have to specify an extra set of square backets here, because the Telegraf config is using [[...]] instead of [...]:

# Configuration for sending metrics to InfluxDB

The InfluxDB urls are supposed to be a list:

urls = ["", "", ""]

If you store that list in an Ansible variable, Ansible (or more exactly: the YAML parser) complains that it recognized a list and converts that into what it thinks is the right data type. But in this case that’s neither nesessary nor what I want. There are two ways to work around that problem:

The config approach

The Ansible configuration file (ansible.cfg) knows a variable string_conversion_action. Since Ansible 2.8 this is set to warn, and apparently will change to error in 2.12. If this is set to ignore, the problem goes away.

However that is quite a brutal approach: this applies to all Playbooks. There might be valid use cases which will be hidden if that setting is changed to ignore.

The string approach

After testing around for a while I found that the YAML parser only complains (and converts) if the string starts with a [. And Telegraf doesn’t care how many spaces are after the =. The easy solution is:

influxdb_url: ' [""]'

Note there is a space at the beginning of the string. This makes the YAML parser happy, and no longer converts the string into an Ansible list. As a result the /etc/telegraf/telegraf.conf looks like:

urls =  [""]

Categories: [Ansible] [Influxdb] [Linux] [Software]