The cisco.radkit Ansible collection provides plugins and modules for network automation through Cisco RADKit, enabling secure, scalable remote access to network devices and infrastructure.
Cisco RADKit (Remote Access Development Kit) is a secure, cloud-based platform that enables remote access to customer network devices for troubleshooting, monitoring, and automation. RADKit consists of three main components:
- RADKit Client: Install from PyPI -
pip install cisco-radkit-client - Version: RADKit 1.9.0+
- Python: 3.10, 3.11, 3.12, or 3.13
- Authentication: Certificate-based login required
- python-proxy: Only required for
http_proxymodule
pip install cisco-radkit-clientFrom Ansible Galaxy:
ansible-galaxy collection install cisco.radkitFrom Git (Development):
ansible-galaxy collection install git+https://github.com/CiscoAandI/cisco.radkit.gitFrom Local Archive:
ansible-galaxy collection install cisco-radkit-<version>.tar.gzAll modules and plugins require authentication credentials for RADKit. Environment variables are the recommended approach:
export RADKIT_ANSIBLE_CLIENT_PRIVATE_KEY_PASSWORD_BASE64=$(echo -n 'mypassword' | base64)
export RADKIT_ANSIBLE_IDENTITY="[email protected]"
export RADKIT_ANSIBLE_SERVICE_SERIAL="xxxx-xxx-xxxx"# Set RADKit credentials
export RADKIT_ANSIBLE_CLIENT_PRIVATE_KEY_PASSWORD_BASE64=$(echo -n 'your_key_password' | base64)
export RADKIT_ANSIBLE_IDENTITY="[email protected]"
export RADKIT_ANSIBLE_SERVICE_SERIAL="your-service-serial"For SSH Proxy Approach (Recommended):
[cisco_devices]
router1
router2
router3
[cisco_devices:vars]
ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'For Legacy Connection Plugins (DEPRECATED):
# Device hostnames and IPs must match what is configured in RADKit inventory
router1 ansible_host=10.1.1.1
router2 ansible_host=10.1.2.1
router3 ansible_host=10.1.3.1Important:
- SSH Proxy: Device hostnames in inventory must match device names in your RADKit service. Use
127.0.0.1asansible_hostsince connections go through the local proxy. - Legacy Plugins: Both hostname and IP address must match exactly what is configured in your RADKit service inventory.
Inventory file (inventory.ini):
[cisco_devices]
router1
router2
router3
[cisco_devices:vars]
ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'Playbook:
---
- name: Setup RADKit SSH Proxy
hosts: localhost
become: no
gather_facts: no
vars:
ssh_proxy_port: 2225
tasks:
- name: Start RADKit SSH Proxy Server
cisco.radkit.ssh_proxy:
local_port: "{{ ssh_proxy_port }}"
async: 300 # Keep running for 5 minutes
poll: 0
register: ssh_proxy_job
failed_when: false
- name: Wait for SSH proxy to become available
ansible.builtin.wait_for:
port: "{{ ssh_proxy_port }}"
host: 127.0.0.1
delay: 3
timeout: 30
- name: Display connection information
debug:
msg: |
SSH Proxy is now running on port {{ ssh_proxy_port }}
Connect to devices using: ssh <device_hostname>@{{ lookup('env', 'RADKIT_ANSIBLE_SERVICE_SERIAL') }}@localhost -p {{ ssh_proxy_port }}
Device credentials are handled automatically by RADKit service
- name: Execute commands on network devices
hosts: cisco_devices # Define your devices in inventory
become: no
gather_facts: no
connection: ansible.netcommon.network_cli
vars:
ansible_network_os: ios
ansible_host: 127.0.0.1 # All connections go through local proxy
ansible_port: 2225
ansible_user: "{{ inventory_hostname }}@{{ lookup('env', 'RADKIT_ANSIBLE_SERVICE_SERIAL') }}"
ansible_host_key_checking: false
tasks:
- name: Get device version information
cisco.ios.ios_command:
commands: show version
register: version_infoInventory Setup (hostnames and IPs must match RADKit service inventory):
[cisco_devices]
router1 ansible_host=10.1.1.100 # IP must match RADKit inventory
router2 ansible_host=10.1.2.100 # IP must match RADKit inventoryPlaybook:
---
- hosts: router1 # Hostname must match RADKit service
connection: cisco.radkit.network_cli
vars:
radkit_identity: [email protected]
ansible_network_os: ios
become: yes
gather_facts: no
tasks:
- name: Run show ip interface brief
cisco.ios.ios_command:
commands: show ip interface brief
register: version_output- hosts: localhost
vars:
target_server: "linux-server-01"
remote_port: 22
tasks:
- name: Start port forward
cisco.radkit.port_forward:
device_name: "{{ target_server }}"
remote_port: "{{ remote_port }}"
local_port: 2223
register: port_forward_result
- name: Wait for port forward to be ready
ansible.builtin.wait_for:
port: 2223
delay: 3
delegate_to: localhost
- name: Connect to Linux server via port forward
vars:
ansible_host: localhost
ansible_port: 2223
ansible_host_key_checking: false
delegate_to: localhost
block:
- name: Get system information
ansible.builtin.setup:
register: system_facts
- name: Display system information
debug:
msg: "Server {{ target_server }} running {{ system_facts.ansible_facts.ansible_distribution }} {{ system_facts.ansible_facts.ansible_distribution_version }}"
- name: Close port forward when done
cisco.radkit.port_forward:
device_name: "{{ target_server }}"
remote_port: "{{ remote_port }}"
local_port: 2223
state: absent
- hosts: localhost
vars:
target_server: "linux-server-01"
remote_port: 22
tasks:
- name: Start port forward
cisco.radkit.port_forward:
device_name: "{{ target_server }}"
remote_port: "{{ remote_port }}"
local_port: 2223
register: port_forward_result
- name: Wait for port forward to be ready
ansible.builtin.wait_for:
port: 2223
delay: 3
delegate_to: localhost
- name: Connect to Linux server via port forward
vars:
ansible_host: localhost
ansible_port: 2223
ansible_host_key_checking: false
delegate_to: localhost
block:
- name: Get system information
ansible.builtin.setup:
register: system_facts
- name: Display system information
debug:
msg: "Server {{ target_server }} running {{ system_facts.ansible_facts.ansible_distribution }} {{ system_facts.ansible_facts.ansible_distribution_version }}"
- name: Close port forward when done
cisco.radkit.port_forward:
device_name: "{{ target_server }}"
remote_port: "{{ remote_port }}"
local_port: 2223
state: absent
- hosts: localhost
tasks:
- name: Execute commands directly on network device
cisco.radkit.command:
device_name: router-01
commands:
- show version
- show ip interface brief
- show running-config | include hostname
register: command_output
- name: Display command results
debug:
var: command_output.results- Single Proxy Server: One
ssh_proxyinstance handles connections to all devices - Username Format: Connect using
<device_hostname>@<service_serial>as the username - Device Authentication: RADKit service handles device credentials automatically
- Long-Running Process: Use
asyncandpoll: 0to keep proxy running during playbook execution
π Learn More: SSH Forwarding Documentation
- SSH Proxy: Best for network devices (routers, switches) - one proxy for multiple devices
- Port Forward: Best for Linux servers - one port forward per device, supports file transfers
π Learn More: Port Forwarding Documentation
- Device hostnames in inventory must match device names in RADKit service
- SSH host key checking should be disabled (keys change between sessions)
- Use
ansible_host: localhostto connect through the proxy - Set
ansible_portto match your SSH proxy port
wait_for_connection not supported: Use cisco.radkit.exec_and_wait instead:
- name: Reload device and wait for recovery
cisco.radkit.exec_and_wait:
device_name: "{{ inventory_hostname }}"
commands: ["reload"]
prompts: [".*yes/no].*", ".*confirm].*"]
answers: ["yes\r", "\r"]
seconds_to_wait: 300
delay_before_check: 10
register: reload_result
- name: Reset connection after reload
meta: reset_connectionHigh fork errors: When using many concurrent connections:
- Increase timeouts in
ansible.cfg - Reduce fork count:
ansible-playbook -f 10 playbook.yml - Use
port_forwardmodule if device credentials are available
"RADKIT failure:" with empty error message: This usually indicates:
- Missing RADKit Client: Install with
pip install cisco-radkit-client - Invalid Credentials: Check your environment variables:
echo $RADKIT_ANSIBLE_IDENTITY echo $RADKIT_ANSIBLE_SERVICE_SERIAL echo $RADKIT_ANSIBLE_CLIENT_PRIVATE_KEY_PASSWORD_BASE64 | base64 -d
- Certificate Issues: Verify radkit certificate paths, expiration, and permissions
- Network Connectivity: Ensure access to RADKit cloud services
- Service Serial: Confirm the service serial is correct and active
Run with -vvv for detailed debugging information.
macOS "Dead Worker" Error:
export no_proxy='*'
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YESNote: Incompatible with HTTP Proxy module
Linux Requirements:
- Terminal connection plugin requires passwordless sudo
- Add to
/etc/sudoers:username ALL=(ALL:ALL) NOPASSWD:ALL
Connection Plugins (DEPRECATED): Enable Ansible modules to connect through RADKit instead of direct SSH. Device credentials stored on RADKit service. Update your playbooks to use the new ssh_proxy and port_forward modules for better reliability and security.
Modules: Specific tasks using RADKit functions. Includes specialized modules for network automation, device management, and proxy functionality.
Inventory Plugins: Dynamically pull device inventory from RADKit service into Ansible without manual configuration.
| Component | Network CLI | Linux SSH | File Transfer | Device Creds | Status |
|---|---|---|---|---|---|
| ssh_proxy + network_cli | β Excellent | β No | β No SCP | π Remote | β Recommended |
| port_forward | β Good | β Excellent | β Full SCP/SFTP | π Local | β Recommended |
| terminal (deprecated) | β No | β Basic | β Yes | π Remote | β Deprecated |
| network_cli (deprecated) | β Good | β No | β Yes | π Remote | β Deprecated |
| http_proxy | β No | β No | β Yes | π Local | β Active |
| Command/Genie modules | β Specialized | β No | β No | π Remote | β Recommended |
- RADKit Documentation: radkit.cisco.com
- PyPI Package: cisco-radkit-client
- Certificate Setup: Authentication Guide
- SSH Forwarding: Feature Documentation
- Port Forwarding: Feature Documentation
- Collection Documentation: Available in
docs/directory
For detailed examples and advanced configurations, see the playbooks/ directory in this collection.