Ansible: listing private IPs using linode-cli v5.0.1

So I've been spending a bunch of time this week working to setup a nodebalancer and two backend linodes this week, and it's been harder than expected.

First, the linode_v4 ansible module doesn't support nodebalancers. Second, I found a couple of bugs in the linode-cli tool that needed to get fixed, but those are happening quite quickly, so that's good. Third, I'm still learning Ansible and trying to understand it better.

Since I'd like other people to be able to use what I've learned, here's a quick tutorial. This is based on the [] guide that Linode has published, but now I build on it.

Let's assume I've create one or more linodes, and I've assigned them private IPs, but now I want to get that information back for a new playbook so I can add them to a nodebalancer config. Here's a simple set of three playbooks to use.

The first one is what I use for calling my block of tasks, so I don't have to use my main script. It's called

# Note!  You must have setup linode-cli properly ahead of time!
- name: "test using linode-cli to make changes"
  hosts: localhost
  become: false

    - ./vars/vars.yml
    - ./vars/external.yml

    # This is just for testing!  In reality we need to get this from
    # the dynamic inventory.
      - ""
      - ""

    - include_tasks: linodes-set-fact.yml

This calls the playbook file linodes-set-fact.yml which looks like this, because it let's me write my tasks and test in isolation, then I just include these tasks into my main script.

# Basic inventory grabbing for data we need farther down
- name: "Find linodes"
    cmd: "linode-cli linodes list --json --suppress-warnings --format 'id'"
  register: found

- name: "Save found linode IDs"
    my_linodes: "{{ my_linodes|default([]) }} + [ {{ }} ]"
  with_items: " {{ found.stdout|from_json }}"

- name: "Show linode IDs"
  debug: var=my_linodes

- name: "Loops over each linode id, including some tasks."
  include_tasks: set-fact-private-ip.yml
  with_items: "{{ my_linodes }}"
  when: my_linodes|length > 0

- name: "Show private IPs we found"
  debug: var=private_ips

All this because I can't figure out how to update the dynamic inventory from within a running playbook, and I didn't want to have multiple playbooks. Any suggestions on how to clean this up would be apprecaited.

In turn, this calls the playbook set-fact-private-ip.yml which looks like this:

# NOTE!  This depends on linode-cli v5.0.1 and the ips-list bug under --text mode.  
- name: "Find linode private IP..."
    cmd: "linode-cli linodes ips-list {{ item }} --text --no-headers --suppress-warnings --format 'private'"
  register: foundip

- name: "Save found private IPs in temp var"
    tmp_ips: "{{ foundip.stdout }}"

- name: "Save private IP to private_ips"
    private_ips: "{{ private_ips|default([]) }} + [ '{{ mp_ips.address }}' ]"

So now I can actually use all this information to add a config to my nodebalancer pointing at the private IP associated with one or more linodes.

One tweak would be to filter my linodes by using either tags or by labels. I might end up doing this if I start doing multiple nodebalancers in the future, say one for production and one for test.

Any comments on how I could do this better would be appreciated!

1 Reply

Hey @toshiba-it - I admittedly don't have a ton of experience with Ansible, but from what I can tell from this Stack Overflow post, - meta: refresh_inventory might do the trick. In the post, it also looks like another user had success with --refresh-cache if that doesn't get the job done:

Reload Ansible's dynamic inventory

And from Ansible's site, this doc has some more examples:

ansible.builtin.meta – Execute Ansible ‘actions’


Please enter an answer

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct