0
votes

This is my playbook for some basic testing

---
- name: get username and password
  import_playbook: credentials.yaml

- name: Run some commands
  hosts:
    - qfx5100-48s
  roles:
    - Juniper.junos
  vars:
    ansible_python_interpreter: "/opt/ansible/ansible-venv/bin/python"
  connection: local
  gather_facts: no

  tasks:
    - name: get uptime
      juniper_junos_command:
        commands:
          - show system uptime
        provider:
          host: "{{ ansible_host }}"
          port: 22
          user: "{{ username }}"
          passwd: "{{ password }}"
      register: uptime

- name: Run some other commands
  hosts:
    - ex3300-48t
  roles:
    - Juniper.junos
  vars:
    ansible_python_interpreter: "/opt/ansible/ansible-venv/bin/python"
  connection: local
  gather_facts: no

  tasks:
    - name: get uptime
      juniper_junos_command:
            commands:
          - show system alarms
        provider:
          host: "{{ ansible_host }}"
          port: 22
          user: "{{ username }}"
          passwd: "{{ password }}"
      register: alarms

    - name: display uptime
      debug:
        var: uptime.stdout_lines

    - name: display alarms
      debug:
        var: alarms.stdout_lines

When i run this i get this error:

""The task includes an option with an undefined variable. The error was: 'password' is undefined\n\nThe error appears to have been in '/opt/ansible/commands2.yaml': line 15, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: get uptime\n ^ here\n"}"

the credentials.yaml file is:

- name: Get username and password
  hosts: localhost
  vars:
    ansible_python_interpreter: "/opt/ansible/ansible-venv/bin/python"
  connection: local
  gather_facts: no
  vars_prompt:
    - name: username
      prompt: Junos Username
      private: no
    - name: password
      prompt: Junos Password
      private: yes

Since there are two plays i'm trying to avoid having the user prompted for their username and password twice when each play runs...

i'm new to ansible to good chance i'm approaching this wrong, but would appreciate some guidance here.

thanks!

1

1 Answers

0
votes

Variables that are set in the vars or vars_prompt or vars_files sections of play are scoped to that play: they will not be available in subsequent plays. E.g.

---
- hosts: localhost
  gather_facts: false
  vars:
    example: foo

- hosts: localhost
  gather_facts: false

  tasks:
    - debug:
        var: example|default('<NOT SET>')

Will output:

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "example|default('<NOT SET>')": "<NOT SET>"
}

But if you set a fact on a host using that variable, it will be available as a hostvar in subsequent plays. That is, this:

---
- hosts: localhost
  gather_facts: false
  vars:
    example: foo

  tasks:
    - set_fact:
        example: "{{ example }}"

- hosts: localhost
  gather_facts: false

  tasks:
    - debug:
        var: example|default('<NOT SET>')

Will output:

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "example|default('<NOT SET>')": "foo"
}

In this example I'm able to reference {{ example }} because the fact was set on localhost and the second play is also running on localhost. In your example, where you're running the play in credentials.yml on localhost but trying to use the value in a play running on another host, you would need to refer to it as:

{{ hostvars['localhost'].example }}

For completeness, your credentials.yml would look something like:

---
- hosts: localhost
  gather_facts: false
  vars_prompt:
    - name: username
      prompt: Junos Username
      private: no
    - name: password
      prompt: Junos Password
      private: yes

  tasks:
    - set_fact:
        username: "{{ username }}"
        password: "{{ password }}"

And your playbook.yml would look like:

---
- name: get username and password
  import_playbook: credentials.yml

- name: Run some commands
  hosts:
    - qfx5100-48s
  roles:
    - Juniper.junos
  vars:
    ansible_python_interpreter: "/opt/ansible/ansible-venv/bin/python"
  connection: local
  gather_facts: no

  tasks:
    - name: get uptime
      juniper_junos_command:
        commands:
          - show system uptime
        provider:
          host: "{{ ansible_host }}"
          port: 22
          user: "{{ hostvars['localhost'].username }}"
          passwd: "{{ hostvars['localhost'].password }}"
      register: uptime