Skip to main content

deepstream-build-compute-stack

Provision Ubuntu 24.04 NVIDIA stacks with Ansible on x86_64 or ARM SBSA, with Xorg setup and optional DeepStream dependencies. Not for Jetson.

Source facts

Repository
NVIDIA/DeepStream
Last source activity
October 16, 2026 at 10:53
Detected SKILL.md language
English
Stars
301
Forks
69

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
27 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
deepstream-build-compute-stack
description
Provision Ubuntu 24.04 NVIDIA stacks with Ansible on x86_64 or ARM SBSA, with Xorg setup and optional DeepStream dependencies. Not for Jetson.
license
Apache-2.0
metadata
{"author":"Kamal Mansata <kmansata@nvidia.com>","version":"1.0.0","tags":["ansible","cuda","tensorrt","cudnn","nvidia-driver","nvidia-docker","provisioning","gpu","ubuntu","x86","sbsa"],"domain":"provisioning"}
# DeepStream Build Compute Stack Configure a target system with a chosen NVIDIA compute stack by running the bundled Ansible playbook (`assets/compute-stack-provisioning/`). The agent collects the target and the desired versions, runs the playbook, handles the driver reboot, verifies the result, and reports. This is a **general-purpose** skill for any team that needs a GPU host provisioned. The default (generic) stack installs the NVIDIA **open** display driver, the CUDA toolkit, cuDNN, TensorRT, and the NVIDIA container and Docker runtime. Versions are fully parameterized. An optional DeepStream-specific layer (GStreamer + OpenTelemetry-C++ built from source) is available opt-in via `--tags deepstream-deps` and is **not** part of the default run. After the stack is built, install your framework or SDK on top — e.g. for DeepStream, the `deepstream-setup` skill; other teams layer their own runtime. --- ## Purpose Give any team a repeatable, version-pinned way to provision the NVIDIA compute stack on a GPU host, driven from an AI tool, instead of hand-running driver, CUDA, and TensorRT install steps. Use it to stand up a fresh host, pin a specific stack for reproducing an issue, or add a single missing component to an existing host. ## Instructions 1. Collect the target (`host` for push over SSH; omit to configure the local machine) and any versions the operator explicitly named — otherwise use the defaults. 2. Preflight: ensure Ansible on the control machine (§4.1) and confirm the target is Ubuntu 24.04. For a shared or lab host, confirm its identity and get approval before provisioning — the run reboots and reconfigures it (§4.2, hard rule 4). 3. Run the bundled playbook — the **full stack** by default, or a **single component** with `--tags <tag>` (see §2.1). Only pass `-e` overrides for versions the operator specified. 4. In push mode the driver install reboots the host; the run reconnects on its own — do not ask the operator for input, just poll for availability at a reasonable interval and continue once the host is back. (On-target/`localhost` the reboot is **skipped** — a manual reboot may be needed before the driver loads, so a post-install `nvidia-smi` failure there is not a run failure.) 5. Read [`references/provisioning.md`](references/provisioning.md) before an on-target run or verification, then emit the final report (§7). Full procedure: push mode → §4; on-target and verification → [`references/provisioning.md`](references/provisioning.md). Hard rules → §5. --- ## 1. Prerequisites — scope, requirements, and knowledge | Aspect | Supported / required | |--------|----------------------| | OS | **Ubuntu 24.04 only** — the playbook asserts `24.04 <= version < 25.00` and fails fast otherwise | | Architecture | **x86_64** and **ARM SBSA** (`aarch64`) | | Jetson | **Out of scope** — use [NVIDIA SDK Manager](https://developer.nvidia.com/sdk-manager) / JetPack instead | | Privileges | Requires `sudo`/`become` on the target | | Network | Target needs internet access (NVIDIA apt repos; https://nvidia.github.io + GitHub only if the optional DeepStream deps are requested) | | Driver | Installs the NVIDIA **open** kernel driver (not the proprietary module) | | Reboot | Driver install **reboots** remote hosts; on `localhost` the reboot is skipped and must be done manually before the driver loads | Role execution order: `init` → `cuda` → `nv_display_driver` → `nvidia-docker` → `cudnn` → `tensorrt` run by default; `deepstream-deps` is **opt-in only** (`--tags deepstream-deps`, tagged `never`). What each role/tag installs is in §2.1's tag-mapping table. --- ## 2. Parameters | Parameter | Required | Description | Example | |-----------|----------|-------------|---------| | `host` | No | SSH target `user@host` or IP. **Omit** → configure the local machine | `ubuntu@10.0.0.5` | | `ssh_key` | If remote (push) and no password | Path to SSH private key | `/path/to/private-key` | | `ssh_auth` | If remote (push) | `key` (default, uses `ssh_key`) or `password` — password is always collected interactively, never as a parameter value | `password` | | `mode` | No | `push` or `on-target`. Auto: remote `host` → `push`; else `on-target` | `push` | | `nv_driver_version` | No | NVIDIA open driver version. Default `595.45.04` | `595.45.04` | | `cuda_version` | No | CUDA version, format `XX-X`. Default `13-2` | `13-2` | | `cudnn_version` | No | cuDNN major version. Default `9` | `9` | | `cudnn_sub_version` | No | cuDNN sub-version (apt pin). Default `9.20` | `9.20` | | `trt_version` | No | TensorRT major version. Default `10` | `10` | | `trt_sub_version` | No | TensorRT sub-version (apt pin). Default `10.16` | `10.16` | | `components` | No | Which components to install. Default: the **generic stack** (driver, CUDA, cuDNN, TensorRT, Docker). Set to install a single component or a subset, or `deepstream-deps` for the optional DeepStream layer | `driver` | **Input source precedence:** a value the operator explicitly names in their prompt always wins; anything not named falls back to the playbook's built-in defaults (`assets/compute-stack-provisioning/defaults/main.yml`). There is no state file or persisted config between runs — every invocation resolves its inputs fresh from what the operator says this time plus those defaults. Collect the target first, then the versions. **Only pass `-e` overrides for versions the operator explicitly specified** — everything else uses the playbook defaults. Never invent version strings; if the operator names a version, use it verbatim. SSH auth for push mode is **either** a private key (default, `--private-key`) **or** a username/password (`--ask-pass`, entered interactively) — never both requested at once. Prefer the key when the operator has one; fall back to password auth only when they say they don't have (or don't want to use) a key. See §4.3 for how password auth is collected and passed. ### 2.1 Install scope (full stack or single component) The playbook is tagged so it can install the **generic stack** (default) or **one component**. Map the operator's request to a tag: | Component the operator asks for | Tag | What runs | |---------------------------------|-----|-----------| | Generic stack (no component named) | *(none)* | driver + cuda + cudnn + tensorrt + docker (excludes `deepstream-deps`) | | NVIDIA display driver | `driver` | CUDA repo and keyring + `nvidia-open` plus pinning + Xorg config | | CUDA toolkit | `cuda` | CUDA repo and keyring + `cuda-toolkit-<ver>` | | cuDNN | `cudnn` | CUDA repo and keyring + cuDNN packages | | TensorRT | `tensorrt` | CUDA repo and keyring + TensorRT packages | | NVIDIA Docker | `docker` | `nvidia-docker` only | | DeepStream OS deps (optional) | `deepstream-deps` | GStreamer + OS deps + OpenTelemetry — **opt-in only** | | Everything incl. DeepStream | `all,deepstream-deps` | generic stack + the DeepStream layer | Rules: - **Default is the generic compute stack** (driver, CUDA, cuDNN, TensorRT, Docker). The DeepStream layer is DeepStream-specific and tagged `never`, so it is **excluded** unless explicitly requested with `--tags deepstream-deps` (or `--tags all,deepstream-deps` for everything). - Only scope down to a single component when the operator names it (e.g. "install *just* the driver", "install cuDNN only"). - Fact-gathering (`init`) and the Ubuntu-24.04 assert are tagged `always` and run regardless. - `driver`, `cudnn`, and `tensorrt` automatically pull in the shared CUDA repo and keyring setup — the `nvidia-open`, cuDNN, and TensorRT packages all ship from the CUDA repo — but **not** the full CUDA toolkit. - To install several components, pass a comma-separated tag list (e.g. `--tags driver,docker`). --- ## 3. Version reference Each version parameter maps to concrete apt packages and pins. The playbook derives `cuda_major_version` from `cuda_version` and couples the cuDNN pin to it. Full mapping, plus how to check that a requested version exists in the NVIDIA repo, is in [`references/versions.md`](references/versions.md). Quick summary: - `cuda_version=13-2` → `cuda-toolkit-13-2`; major `13` also drives the cuDNN pin. - `nv_driver_version=595.45.04` → branch `595` → `nvidia-open-595` + `nvidia-driver-pinning-595.45.04`. - `cudnn_version=9` / `cudnn_sub_version=9.20` → `libcudnn9...-cuda-13=9.20*`. - `trt_version=10` / `trt_sub_version=10.16` → `libnvinfer10=10.16*` family. --- ## 4. Procedure — Mode A: push (remote host over SSH) Use when the operator supplies a remote `host` with credentials. ### 4.1 Ensure Ansible on the control machine ```bash ansible-playbook --version ``` If missing, run `sudo apt update`, then `sudo apt install -y ansible`. No sudo, or a PEP 668 "externally-managed-environment" error (default on Ubuntu 24.04)? Install without root via `pipx install --include-deps ansible`, a venv (`python3 -m venv` - needs `python3-venv`), or `pip install --user --break-system-packages ansible`. **Pass:** `ansible-playbook --version` prints a version. ### 4.2 Confirm the target before provisioning For a shared or lab host, confirm the host identity with the operator before proceeding — provisioning reboots the machine and rewrites its GPU and display config. ### 4.3 Write the inventory (no plaintext secrets) Create a working inventory (e.g. `/tmp/csb-inventory.ini`) with only the host and user. Do **not** write passwords into it, and do not edit the bundled `assets/compute-stack-provisioning/inventory.ini` in place. ```ini [target] target-host ansible_user=your-username [all:vars] ansible_python_interpreter=/usr/bin/python3 ansible_ssh_common_args='-o StrictHostKeyChecking=accept-new' ``` `accept-new` auto-accepts a first-seen host but still fails on a *changed* key (MITM protection). If a re-imaged target trips `REMOTE HOST IDENTIFICATION HAS CHANGED`, clear its stale key with `ssh-keygen -R <host>` rather than disabling verification; `-o UserKnownHostsFile=/dev/null` (off entirely) is a disposable-lab fallback only. Supply credentials **without persisting them to disk**: - **SSH key (default):** add `--private-key <path>` on the command line. - **SSH username/password (alternative to a key):** do **not** put the password in the inventory, a `-e` value, or any file. Use Ansible's interactive prompt, `--ask-pass` (short `-k`), so the operator (or the terminal session driving this skill) is prompted at run time; for unattended automation, source the password from an approved vault or secret-manager environment lookup instead of a literal. Password auth requires `sshpass` on the **control machine** (`sudo apt install -y sshpass` if `ansible-playbook` reports it missing). - **Become password:** use `--ask-become-pass`; for unattended automation, use an approved vault or secret-manager-backed environment lookup. Do not ask the operator to paste a password into chat — direct them to enter it at the `--ask-pass`/`--ask-become-pass` prompt (or the vault flow) instead. Only stop and ask for a different credential if neither a key nor password auth is available. Never hard-code `ansible_ssh_pass` or `ansible_become_pass` in an inventory or commit secrets. ### 4.4 Preflight ```bash ansible -i /tmp/csb-inventory.ini target --private-key <path> \ -m setup -a 'filter=ansible_distribution*' ``` Password auth: swap `--private-key <path>` for `--ask-pass`. **Pass:** connection succeeds and reports `Ubuntu` `24.04`. If the target is not Ubuntu 24.04, stop — the playbook will assert-fail (see Troubleshooting). ### 4.5 Run the playbook ```bash ansible-playbook -i /tmp/csb-inventory.ini \ assets/compute-stack-provisioning/ubuntu_setup.yml \ --private-key <path> --ask-become-pass \ -e "cuda_version=13-2" \ -e "nv_driver_version=595.45.04" # ...only include -e lines for versions the operator overrode # Single component? append --tags <tag>, e.g. --tags driver (see §2.1) ``` Password auth: swap `--private-key <path>` for `--ask-pass` — it prompts once per `ansible-playbook` invocation and reuses that connection password for the whole run; it is never written to the generated inventory or logs. The `nv_display_driver` role **reboots the remote host** and then `wait_for_connection`s; the play resumes automatically. Treat the mid-run disconnect + reconnect as **expected**, not a failure. This is long-running (~10–40 min). Run it detached and poll its log rather than blocking the session. **Do not stop to ask the operator for input after the reboot.** The play polls for the host itself and continues on its own; if you drive the reboot outside the playbook, poll for SSH and host availability at a reasonable interval (e.g. every 15–30 s, for up to 9 minutes) and resume the workflow automatically once the host answers — no operator confirmation is needed. Stop after 9 minutes if the host does not return; report a reboot timeout and the last successful playbook task, and do not restart provisioning automatically. **Pass:** the play recap ends with `failed=0` for the target host. If the recap reports `failed>0` or `unreachable>0`, stop, report the failed task and recap, and troubleshoot the specific error before rerunning. Never emit a successful final report. --- ## 5. Hard rules 1. **Only override what the operator specified.** Pass `-e` for a version only when the operator named it; otherwise let the playbook defaults apply. *Why: silent version drift produces a stack the operator did not ask for.* 2. **Never invent version strings.** Use the operator's values verbatim; if unsure a version exists, check the NVIDIA repo (see `references/versions.md`) rather than guess. *Why: a nonexistent apt pin fails the run partway through.* 3. **Ubuntu 24.04 only; never Jetson.** Do not target other distros or releases, or Jetson — the playbook asserts and fails fast. Redirect Jetson requests to SDK Manager (JetPack). 4. **Confirm shared-host identity before provisioning.** Provisioning reboots the host and rewrites GPU and display config — get operator approval before touching a shared or lab host. 5. **Treat the driver reboot as expected, and never pause for input on it.** In push mode the mid-run disconnect + reconnect is normal; do not abort or re-run from scratch on seeing it, and do not ask the operator to confirm the reboot or that the host is back. Poll for host availability at a reasonable interval and resume the workflow automatically once it answers. 6. **Do not edit the bundled playbook.** Parameterize via `-e` and a generated inventory; the `assets/compute-stack-provisioning/` tree is the shipped source of truth. 7. **Never persist an SSH or become password.** Password auth is collected only via `--ask-pass`/`--ask-become-pass` (or a vault/secret-manager lookup) — never write a password into the inventory, a `-e` value, a command echoed to a log, or chat. *Why: an inventory or transcript containing a plaintext password is a standing credential leak.* --- ## 6. Troubleshooting If a run fails or an operator reports an error, consult [`references/troubleshooting.md`](references/troubleshooting.md) for the Error → Cause → Solution table (assertion failures, SSH/sudo auth, apt/CUDA-repo errors, `sshpass`, driver reboot/verify issues) before improvising a fix. --- ## 7. Final report Emit a fixed-width summary at the end: ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub