fix: kubectl binary copy works through bastion and cross-platform#1339
fix: kubectl binary copy works through bastion and cross-platform#1339michael-balint merged 1 commit intoNVIDIA:masterfrom
Conversation
Replace synchronize (rsync) with fetch module for copying kubectl from the cluster — rsync spawns its own SSH that bypasses ansible_ssh_common_args, failing when a bastion/proxy is required. Add cross-platform support: detect when the ansible controller and cluster have different OS/arch (e.g., macOS ARM vs Linux x86-64) and download the correct kubectl binary from dl.k8s.io matching the cluster's K8s version. Install kubectl to the active virtualenv ($VIRTUAL_ENV/bin/) instead of /usr/local/bin, eliminating the need for sudo and keeping it scoped to the DeepOps environment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Douglas Holt <dholt@nvidia.com>
There was a problem hiding this comment.
Pull request overview
Updates the Kubernetes cluster playbook’s “local” kubectl handling so it works when connecting through a bastion/proxy and when the Ansible controller platform differs from the cluster platform, while also avoiding sudo by installing kubectl into the active virtualenv.
Changes:
- Replace
synchronize/rsync pull withfetchto copy kubectl through the existing Ansible SSH connection (bastion-friendly). - Add controller/remote platform detection and download a matching kubectl binary for the controller when OS/arch differs.
- Install kubectl into
$VIRTUAL_ENV/bin/(when available) instead of/usr/local/bin.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| flat: yes | ||
| run_once: true | ||
| when: local_uname.stdout == remote_uname.stdout | ||
|
|
There was a problem hiding this comment.
fetch doesn't guarantee the fetched file is executable on the controller. Since later tasks execute {{ artifacts_dir }}/kubectl, ensure you set mode 0755 on the fetched file (e.g., follow the existing pattern used after fetch in roles/netapp-trident/tasks/main.yml).
| - name: ensure kubectl binary is executable on ansible host | |
| file: | |
| path: "{{ artifacts_dir }}/kubectl" | |
| mode: '0755' | |
| delegate_to: localhost | |
| run_once: true | |
| when: local_uname.stdout == remote_uname.stdout |
| - name: get kubectl version for cross-platform download | ||
| command: /usr/local/bin/kubectl version --client -o json | ||
| register: kubectl_ver_json | ||
| run_once: true |
There was a problem hiding this comment.
This kubectl version command is used only for discovery, but without changed_when: false it will report the play as changed on every run. Add changed_when: false (and optionally failed_when handling if you want to tolerate missing kubectl) to keep the --tags local run idempotent.
| run_once: true | |
| run_once: true | |
| changed_when: false |
| url: "https://dl.k8s.io/release/{{ kubectl_ver }}/bin/{{ kubectl_os }}/{{ kubectl_arch }}/kubectl" | ||
| dest: "{{ artifacts_dir }}/kubectl" | ||
| mode: '0755' | ||
| force: yes |
There was a problem hiding this comment.
The cross-platform get_url download runs on localhost but doesn't pass proxy_env. If this repo is configured to run behind an HTTP(S) proxy (as many other tasks do), this download will fail; consider adding environment: "{{ proxy_env if proxy_env is defined else {} }}" to this task.
| force: yes | |
| force: yes | |
| environment: "{{ proxy_env if proxy_env is defined else {} }}" |
| get_url: | ||
| url: "https://dl.k8s.io/release/{{ kubectl_ver }}/bin/{{ kubectl_os }}/{{ kubectl_arch }}/kubectl" | ||
| dest: "{{ artifacts_dir }}/kubectl" | ||
| mode: '0755' | ||
| force: yes |
There was a problem hiding this comment.
This downloads an executable kubectl binary but doesn't verify integrity (no checksum). Consider fetching the published SHA256 for the selected version/arch and using get_url's checksum parameter to reduce supply-chain risk.
Summary
synchronize(rsync) withfetchmodule for copying kubectl from the cluster — rsync spawns its own SSH connection that bypassesansible_ssh_common_args, failing when a bastion/proxy is required.$VIRTUAL_ENV/bin/) instead of/usr/local/bin, eliminating the need for sudo.Test plan
fetchcopies kubectl through SSH bastion successfully.venv/bin/kubectl— correct Mach-O arm64 binarykubectl version --clientreturns matching cluster version (v1.34.3)--tags localcompletes with zero failures🤖 Generated with Claude Code