0

New to ansible - I'm trying to set the PS1 variable in /etc/bash.bashrc based on the condition of the host's IP address. But I am having trouble with the ps1 variable being available across tassks. I don't know if this is a scope issue (as far as I can tell from this link) or if I should really have two separate playbooks basically doing the same thing (one for LAN hosts, one for WIFI hosts). When I run this playbook I get:

The task includes an option with an undefined variable. The error: 'dict object' has no attribute 'stdout'\n\n

Is there a way to define the ps1 variable so I can assign it inside a task and have it available to other tasks?

---
- hosts: all
  tasks:
    - name: generate LAN host bash prompt
      when: ansible_default_ipv4.address is match("192.168.16")
      connection: local
      shell : /usr/local/bin/psgen -l
      register: ps1
    - debug: var=ps1.stdout

    - name: generate WIFI host bash prompt
      when: ansible_default_ipv4.address is match("172.10.1")
      connection: local
      shell : /usr/local/bin/psgen -w
      register: ps1

    - name: write PS1 to remote /etc/bash.bashrc
      lineinfile:
        dest: /etc/bash.bashrc
        line: "{{ ps1.stdout }}"
        regexp: "PS1="
        insertafter: EOF
  • You seem to be setting (registering) the ps1 in two tasks? Is the second over-writing a value you expected to see from the first? Which task did you actually want the value from? – Zoredache May 3 '18 at 19:50
  • Maybe that's the issue. I didn't think it was overwriting the variable since the conditional on the IP address would only match once (in the when clause). Any way to tell it to leave the variable alone or do I need two separate playbooks for each subnet? – Server Fault May 3 '18 at 20:06
0

If I were going to do this, I wouldn't add tasks. Instead I would remove one, making your task into a loop. When you loop over something all the results will then be stored in a list. You can then use various jinja expressions to extract the successful result from the list.

---
- hosts: all
  tasks:
  - name: generate host bash prompt
    when: ansible_default_ipv4.address is match(item.net_match)
    connection: local
    shell : "{{item.shell}}"
    register: ps1
    loop:
    - name: LAN
      shell: /usr/local/bin/psgen -l
      net_match: 192.168.16
    - name: WAN
      shell: /usr/local/bin/psgen -w
      net_match: 172.10.1

  - debug:
      msg: "ps1"
  - debug:
      msg: "{{ (ps1.results | selectattr('rc', 'defined') | list)[0].stdout }}"

  - name: write PS1 to remote /etc/bash.bashrc
    lineinfile:
      dest: /etc/bash.bashrc
      line: "{{ (ps1.results | selectattr('rc', 'defined') | list)[0].stdout }}"
      regexp: "PS1="
      insertafter: EOF
| improve this answer | |
  • Good to know about the loop: feature, thanks for taking the time to think about this! – Server Fault May 4 '18 at 13:12
2

@Zoredache is correct.

From: http://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#registered-variables

If a task fails or is skipped, the variable still is registered with a failure or skipped status, the only way to avoid registering a variable is using tags.

This should work:

- name: lan
  set_fact:
    psgen_args: -l
  when: ansible_default_ipv4.address is match("192.168.16")

- name: wlan
  set_fact:
    psgen_args: -w
  when: ansible_default_ipv4.address is match("172.10.1")

- name: set ps1
  shell: /usr/local/bin/psgen {{ psgen_args }}
  register: ps1

- name: write PS1 to remote /etc/bash.bashrc
  lineinfile:
    dest: /etc/bash.bashrc
    line: "{{ ps1.stdout }}"
    regexp: "PS1="
    insertafter: EOF
| improve this answer | |
  • Nice approach! I really like how you assigned the command arguments as a fact and then reference the fact with one task. I hadn't thought of doing it that way and it will come in handy for other playbooks. – Server Fault May 4 '18 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.