Introduction
Physical AI — AI moving from screens into warehouses, factories, vehicles, and devices — is a defining 2026 trend. Gartner calls out physical AI, and Deloitte reports that enterprises are deploying robot fleets and autonomous production systems. Ansible manages the infrastructure behind these systems: edge device provisioning, ROS2 deployment, AI model distribution, fleet OTA updates, and monitoring.
Edge Device Inventory
# inventory/robots.yml
all:
children:
warehouse_robots:
hosts:
agv-01: { ansible_host: 10.0.1.101, robot_type: agv, zone: zone-a }
agv-02: { ansible_host: 10.0.1.102, robot_type: agv, zone: zone-b }
agv-03: { ansible_host: 10.0.1.103, robot_type: agv, zone: zone-c }
vars:
ansible_user: robot
ansible_become: true
ros_distro: jazzy
edge_gpu: jetson
inspection_drones:
hosts:
drone-01: { ansible_host: 10.0.2.201, flight_zone: north }
drone-02: { ansible_host: 10.0.2.202, flight_zone: south }
vars:
ansible_user: pilot
edge_gpu: orin_nano
factory_arms:
hosts:
arm-01: { ansible_host: 10.0.3.101, cell: welding-1 }
arm-02: { ansible_host: 10.0.3.102, cell: assembly-1 }
vars:
ansible_user: plc
ros_distro: jazzy
Deploy ROS2 (Robot Operating System)
- name: Deploy ROS2 on robot fleet
hosts: warehouse_robots:factory_arms
become: true
vars:
ros_distro: jazzy
ros_packages:
- ros-{{ ros_distro }}-desktop
- ros-{{ ros_distro }}-navigation2
- ros-{{ ros_distro }}-slam-toolbox
- ros-{{ ros_distro }}-moveit
tasks:
- name: Add ROS2 repository key
ansible.builtin.apt_key:
url: https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc
state: present
- name: Add ROS2 repository
ansible.builtin.apt_repository:
repo: "deb http://packages.ros.org/ros2/ubuntu {{ ansible_distribution_release }} main"
state: present
- name: Install ROS2 packages
ansible.builtin.apt:
name: "{{ ros_packages }}"
state: present
update_cache: true
- name: Configure ROS2 environment
ansible.builtin.lineinfile:
path: /etc/bash.bashrc
line: "source /opt/ros/{{ ros_distro }}/setup.bash"
- name: Set ROS_DOMAIN_ID per zone
ansible.builtin.lineinfile:
path: /etc/environment
line: "ROS_DOMAIN_ID={{ ros_domain_ids[zone] | default(0) }}"
- name: Deploy robot-specific navigation config
ansible.builtin.template:
src: "nav2_params_{{ robot_type }}.yaml.j2"
dest: /opt/robot/config/nav2_params.yaml
notify: Restart navigation stack
handlers:
- name: Restart navigation stack
ansible.builtin.systemd:
name: ros2-navigation
state: restarted
Edge AI Model Deployment
- name: Deploy AI models to edge devices
hosts: warehouse_robots:inspection_drones
become: true
vars:
model_server: http://model-registry.internal:8080
model_version: "v2.3.0"
tasks:
- name: Create model directory
ansible.builtin.file:
path: /opt/models/{{ item }}
state: directory
mode: "0755"
loop:
- detection
- navigation
- anomaly
- name: Download object detection model
ansible.builtin.get_url:
url: "{{ model_server }}/models/detection/{{ model_version }}/model.onnx"
dest: /opt/models/detection/model.onnx
checksum: "sha256:{{ detection_model_sha256 }}"
notify: Restart inference service
- name: Download navigation model
ansible.builtin.get_url:
url: "{{ model_server }}/models/navigation/{{ model_version }}/model.trt"
dest: /opt/models/navigation/model.trt
checksum: "sha256:{{ nav_model_sha256 }}"
notify: Restart navigation stack
- name: Verify model on device
ansible.builtin.command: >
python3 -c "import onnxruntime; sess = onnxruntime.InferenceSession('/opt/models/detection/model.onnx'); print('OK:', sess.get_inputs()[0].shape)"
register: model_check
changed_when: false
- name: Report model status
ansible.builtin.debug:
msg: "{{ inventory_hostname }}: {{ model_check.stdout }}"
handlers:
- name: Restart inference service
ansible.builtin.systemd:
name: edge-inference
state: restarted
- name: Restart navigation stack
ansible.builtin.systemd:
name: ros2-navigation
state: restarted
NVIDIA Jetson / Isaac Setup
- name: Configure NVIDIA Jetson for robotics
hosts: warehouse_robots
become: true
tasks:
- name: Install NVIDIA JetPack components
ansible.builtin.apt:
name:
- nvidia-jetpack
- nvidia-tensorrt
- nvidia-cuda-toolkit
state: present
- name: Install Isaac ROS packages
ansible.builtin.apt:
name:
- ros-{{ ros_distro }}-isaac-ros-common
- ros-{{ ros_distro }}-isaac-ros-visual-slam
- ros-{{ ros_distro }}-isaac-ros-dnn-inference
state: present
- name: Optimize Jetson power mode
ansible.builtin.command: >
nvpmodel -m {{ jetson_power_mode | default(0) }}
changed_when: false
- name: Set Jetson clock speeds
ansible.builtin.command: jetson_clocks
changed_when: false
when: maximize_performance | default(false)
Fleet OTA Updates
- name: Rolling OTA update for robot fleet
hosts: warehouse_robots
become: true
serial: 1
max_fail_percentage: 0
pre_tasks:
- name: Put robot in maintenance mode
ansible.builtin.uri:
url: "http://{{ ansible_host }}:8080/api/mode"
method: POST
body_format: json
body: { "mode": "maintenance" }
- name: Wait for robot to reach safe state
ansible.builtin.uri:
url: "http://{{ ansible_host }}:8080/api/status"
register: status
until: status.json.state == "idle"
retries: 30
delay: 10
tasks:
- name: Update robot software
ansible.builtin.apt:
upgrade: safe
update_cache: true
- name: Deploy new application version
ansible.builtin.copy:
src: "releases/robot-app-{{ app_version }}.deb"
dest: /tmp/robot-app.deb
- name: Install application
ansible.builtin.apt:
deb: /tmp/robot-app.deb
- name: Run post-update diagnostics
ansible.builtin.command: /opt/robot/diagnostics.sh
register: diag
failed_when: "'FAIL' in diag.stdout"
post_tasks:
- name: Return robot to operation
ansible.builtin.uri:
url: "http://{{ ansible_host }}:8080/api/mode"
method: POST
body_format: json
body: { "mode": "operational" }
- name: Verify robot is operational
ansible.builtin.uri:
url: "http://{{ ansible_host }}:8080/api/status"
register: post_status
until: post_status.json.state == "operational"
retries: 10
delay: 5
Edge Monitoring
- name: Deploy edge monitoring
hosts: warehouse_robots:inspection_drones
become: true
tasks:
- name: Install Prometheus node exporter
ansible.builtin.package:
name: prometheus-node-exporter
state: present
- name: Deploy GPU metrics exporter
community.docker.docker_container:
name: gpu-exporter
image: utkuozdemir/nvidia_gpu_exporter:latest
ports: ["9835:9835"]
volumes:
- /usr/bin/nvidia-smi:/usr/bin/nvidia-smi
device_requests:
- driver: nvidia
count: -1
capabilities: [[gpu]]
- name: Deploy custom robot metrics
ansible.builtin.template:
src: robot-metrics.py.j2
dest: /opt/robot/metrics-exporter.py
mode: "0755"
notify: Restart metrics exporter
Related Articles
Conclusion
Physical AI in 2026 means managing fleets of robots, drones, and edge devices at scale. Ansible handles the entire lifecycle: provisioning edge hardware (Jetson, Orin), deploying ROS2 and Isaac ROS, distributing AI models with integrity verification, performing rolling OTA updates with safety interlocks (serial: 1, maintenance mode), and monitoring GPU/sensor health. The key pattern: treat robots like servers — inventory them, configure them declaratively, update them safely. Ansible's agentless architecture is perfect for resource-constrained edge devices.