provider-ssh

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2025 License: Apache-2.0

README

Provider SSH

Overview

The provider-ssh is a Crossplane provider that reconciles external resources reachable over SSH. It executes user-supplied scripts to converge a remote system to a desired state, exposes observed state from checks, and supports idempotency and drift detection.

Kinds
  • ProviderConfig: to authenticate/reach the target(s)
  • SSHTask: A unit of desired work on a host

Installation

You can run the provider-ssh locally or install it from an xpkg file. To install the provider use:

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-ssh
spec:
  package: docker.io/etesami/provider-ssh:latest

ProviderConfig

To begin, you'll need to create a ProviderConfig and a Secret. To initiate a connection to the remote host, either a password or privateKey is required. The privateKey should be provided as a single-line, base64-encoded string. To generate the base64 version of a private key, use the following command:

# In Linux
cat .ssh/id_rsa | base64 -w0

The knownHosts file is required to verify the identity of the server. You can generate and verify it using the command below:

ssh-keyscan <HOST-REMOTE-IP>

Next, construct the ProviderConfig and Secret as shown below:

apiVersion: v1
kind: Secret
metadata:
  namespace: crossplane-system
  name: providerssh-secret
type: Opaque
stringData:
  config: |
    {
      "username": "ubuntu",
      "password": "password",
      "privateKey": "5XUUNPV2tSd0ptTFp...wbTNFKzhqMkYzdXc5ClNRZ09QO",
      "hostIP": "10.29.30.5",
      "hostPort": "22",
      "knownHosts": "10.29.30.5 ecdsa-sha2-nistp256 AAAAE2VjZHN...UpvT57WP45MDBAV4CxQ="
    }
---
apiVersion: ssh.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
  name: providerssh-config
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: providerssh-secret
      key: config

SSHTask

apiVersion: ssh.crossplane.io/v1alpha1
kind: SSHTask
metadata:
  name: configure-nginx
spec:
  providerConfigRef:
    name: default
  managementPolicies: ["*"]
  forProvider:
    scripts:
      # 1) checkScript runs first; must be side-effect free. Exit 0 = desired state.
      checkScript:
        inline: |
          if [ -f /etc/nginx/sites-enabled/default ]; then echo "present"; exit 0; else exit 1; fi

      # 2) applyScript converges to desired state; MUST be idempotent.
      applyScript:
        inline: |
          sudo apt-get update -y
          sudo apt-get install -y nginx
          echo "hello" | sudo tee /var/www/html/index.html >/dev/null

      # 3) diffScript (optional) outputs machine-readable drift info (e.g., JSON).
      diffScript:
        inline: |
          test -f /var/www/html/index.html || echo '{"file":"missing"}'
          # exit 0 regardless; controller treats non-empty stdout as drift details

      # 4) cleanupScript runs on Delete.
      cleanupScript:
        inline: |
          sudo apt-get purge -y nginx || true
          sudo rm -f /var/www/html/index.html || true

    # Execution environment & safety
    execution:
      sudo: true
      shell: /bin/bash -euo pipefail
      timeoutSeconds: 600
      maxAttempts: 2              # per reconcile
      # env is map of key, values where all instance of key is replaced
      # by value before executing the script on the remove device
      env:
        INLINE_VAR: FOO

    artifactPolicy:
      capture: stdout        # stdout | stderr | both | none
        
      
status:
  conditions:
    - type: Ready
      status: "True"
      reason: UpToDate
      lastTransitionTime: "2025-08-18T14:02:31Z"
    - type: Synced
      status: "True"
      reason: ObserveSucceeded
      lastTransitionTime: "2025-08-18T14:02:31Z"
  atProvider:
    endpoint:
      host: "10.0.0.12"
      port: 22
      username: "ubuntu"
    lastCheckTime: "2025-08-18T14:02:29Z"
    lastRun:
      time: "2025-08-18T14:02:29Z"
      exitCode: 0
      retryCount: 0
    artifacts:
      stdout: ""
      stderr: ""
    

Development

make build
# The image is stored somewhere like
pkg=provider-ssh-v0.0.0-21.gb69de81.xpkg
VERSION=v2.0.0-rc6 && \
  DIR=/home/ubuntu/provider-ssh/_output/xpkg/linux_amd64 && \
  crossplane xpkg push -f $DIR/$pkg index.docker.io/etesami/provider-ssh:$VERSION && \
  crossplane xpkg push -f $DIR/$pkg index.docker.io/etesami/provider-ssh:latest

Directories

Path Synopsis
Package apis contains Kubernetes API for the SSH provider.
Package apis contains Kubernetes API for the SSH provider.
v1alpha1
Package v1alpha1 contains the core resources of the SSH provider.
Package v1alpha1 contains the core resources of the SSH provider.
cmd
provider command
internal
version
Package version contains the version of this repo
Package version contains the version of this repo

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL