Search code examples
ansibletelnet

Ansible won't connect to emulated network devices over Telnet


I am trying to use Ansible to enable SSH access to network devices emulated in an EVE-NG environment. My goal is for an Ansible playbook to configure SSH. EVE-NG works similar to GNS3 in that you connect to a device via telnet over a specific port. For this example, lets say my EVE-NG server is at 192.168.1.10. EVE-NG will assign a telnet port to that device, such as 32899. If I run telnet 192.168.1.10 32899 I am able to access the device as expected. However, if I execute my playbook, the playbook seems to do nothing during the telnet module executions. A snippet of my playbook is below.

- name: Configure new EVE-NG router
  hosts: new_devices:cisco
  gather_facts: no
  tasks:
    - debug:
        msg: '{{ansible_host}} {{ansible_port}}'
    - name: Setup domain information
      telnet:
        port: '{{ansible_port}}'
        prompts:
          - "[>|#]"
        command:
          - term length 0
          - en
          - conf t

Running ansible-playbook with -vvv doesn't show any useful information. netstat does show an outbound connection in ESTABLISHED state when Ansible is executing.


Solution

  • I would solve this using the shell module combined with /usr/bin/expect as the executable. This gives you more flexibility to interacting with the system, and makes it possible to follow progress in a separate log file.

    - name: Interact with system
      shell: |
        set timeout 120
        log_file {{ '~/logs/your_log_file.explog' }}
    
        spawn telnet {{ inventory_hostname }}
    
        expect "username: "
        send "{{ your_username }}\n"
    
        expect "password:"
        send "{{ your_password }}\n"
    
        expect "# "
        send "term length 0"
    
        expect "# "
        send "en"
    
        expect "# "
        send "conf -t"
      args:
        executable: /usr/bin/expect
      changed_when: yes
      delegate_to: localhost
    

    Or you can use the script module to keep your playbooks tidy and clean.

    - name: Interact with system
      script: interact-with-system.expect
      args:
        executable: /usr/bin/expect
      changed_when: yes
      delegate_to: localhost
    

    PS: If you use a shebang, you don't even need to add the executable.

    Look at the expect man page, or online examples to see what you can do with expect. It is quite powerful, but requires some getting used to.