From 702b27e5836d3e5ba79ba12d1a672a919909b69e Mon Sep 17 00:00:00 2001 From: "J.P. Krauss" Date: Wed, 13 Aug 2025 16:11:13 -0700 Subject: [PATCH] maint: initial commit --- Dockerfile | 7 +++++++ README.md | 2 ++ action.yml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ entrypoint.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 action.yml create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b01734c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM alpine:3.22 +RUN apk update && \ + apk add bash py3-pip step-cli && \ + pip3 install ansible + +COPY entrypoint.sh /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2e9590 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# KraussNet Ansible Runner Action +Runs Ansible playbooks on KraussNet hosts utilizing SSH certificates provisioned by the KraussNet PKI. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..2506e8e --- /dev/null +++ b/action.yml @@ -0,0 +1,56 @@ +name: Run Ansible Playbook on KraussNet Servers +description: Runs an Ansible playbook using KraussNet PKI for SSH access +inputs: + pki_ca_url: + description: The PKI certificate authority base URL + required: true + pki_fingerprint: + description: The PKI certificate authority fingerprint + required: true + pki_key_subject: + description: The subject of the SSH certificate + required: false + pki_provisioner_name: + description: The PKI provisioner name (defaults to "ansible") + required: false + pki_provisioner_password: + description: The PKI provisioner password + required: true + playbook: + description: Ansible playbook filepath + required: true + inventory: + description: Ansible inventory filepath + required: true + requirements: + description: Ansible Galaxy requirements filepath + required: false + directory: + description: Root directory of Ansible project (defaults to current) + required: false + configuration: + description: Ansible configuration file content (ansible.cfg) + required: false + vault_password: + description: The password used for decrypting vaulted files + required: false + private_key: + description: SSH private key used to connect to the host + required: false + known_hosts: + description: Contents of SSH known_hosts file + required: false + options: + description: Extra options that should be passed to ansible-playbook command + required: false + become: + description: Set to "true" if root is required for running your playbook + required: false + default: false + check_mode: + description: Set to "true" to enable check (dry-run) mode + required: false + default: false +runs: + using: docker + image: Dockerfile diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..e35f419 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# +# KraussNet Ansible Playbook Runner Action Entrypoint + +set -euo pipefail + +if [ -z "${INPUT_PKI_CA_URL:-}" ] ; then + echo "Missing required input parameter 'pki_ca_url'" + exit 1 +fi +if [ -z "${INPUT_PKI_FINGERPRINT:-}" ] ; then + echo "Missing required input parameter 'pki_fingerprint'" + exit 1 +fi +if [ -z "${INPUT_PKI_PROVISIONER_PASSWORD:-}" ] ; then + echo "Missing required input parameter 'pki_provisioner_password'" + exit 1 +fi +if [ -z "${INPUT_PLAYBOOK:-}" ] ; then + echo "Missing required input parameter 'playbook'" + exit 1 +fi +if [ -z "${INPUT_INVENTORY:-}" ] ; then + echo "Missing required input parameter 'inventory'" + exit 1 +fi + +# Setup Variables +provisioner_name=${INPUT_PKI_PROVISIONER_NAME:-"ansible"} +provisioner_password=${INPUT_PKI_PROVISIONER_PASSWORD} +default_cert_subject="ansible-kraussnet-action-runner@$(hostname -f)" +user_cert_subject=${INPUT_SUBJECT:-"$default_cert_subject"} + +# Bootstrap the PKI Certificate Authority +step ca bootstrap \ + --ca-url "${INPUT_PKI_CA_URL}" \ + --fingerprint "${INPUT_PKI_FINGERPRINT}" +echo "Bootstrapped PKI at ${INPUT_PKI_CA_URL}" + +# Obtain the Host Certificate +[ ! -d ~/.ssh ] && mkdir ~/.ssh +echo "@cert-authority *.kraussnet.com $(step ssh config --host --roots)" > ~/.ssh/known_hosts +echo "Obtained SSH Host Certificate Authority" + +# Obtain a User Certificate for Ansible +token=$(step ca token "${user_cert_subject}" --ssh --provisioner "${provisioner_name}" --provisioner-password-file <(printf "${provisioner_password}")) +echo "Obtained User Token from CA" +echo $token | step crypto jwt inspect --insecure + +[ ! -f ~/.ssh/id_ecdsa ] && ssh-keygen -t ecdsa -f ~/.ssh/id_ecdsa -N '' +[ -f ~/.ssh/id_ecdsa-cert.pub ] && rm ~/.ssh/id_ecdsa-cert.pub +step ssh certificate "${user_cert_subject}" ~/.ssh/id_ecdsa.pub --sign --provisioner "${provisioner_name}" --token $token +echo "Obtained User Certificate from CA" +ssh-keygen -L -f ~/.ssh/id_ecdsa-cert.pub + +# Run a test command (will be replaced with the Ansible command) +ssh ansible@rpi-ns1.lan.kraussnet.com 'echo "Hello from $(hostname -f)"'