Poka-yoke - Adding a confirmation before running kubectl commands in production

February 22, 2025

Poka-yoke

Poka-yoke is the idea of mistake-proofing. It comes from the Toyota Production System and is the idea that you intentionally add a constraint to a process to prevent human error.

Some common examples are a manual transmission car only starting when the clutch is pressed and a microwave only running when the door is closed.

Kubectl Confirm Prompt

I wanted to apply this idea to the kubectl command when running commands that can change resources in a production environment. I've found it too easy to run an apply command in the wrong context and wanted to ensure that couldn't happen.

My requirements were:

  • A prompt that warns you that you are running the command in production.
  • A confirmation requiring input similar to installing dependencies through a package manager.
  • The check does not run on informational commands like get and describe.
  • The check only runs in a specified context (production)

The following is the Zsh function that I was able to piece together. This setup correctly preserves kubectl tab completion.

# Ensure kubectl completion is loaded
autoload -U compinit && compinit
[[ $commands[kubectl] ]] && source <(kubectl completion zsh)

# Function to wrap kubectl with safety check
kubectl() {
  # Skip check if this is a completion call or no arguments
  if [[ "$1" == "__complete" ]] || [[ $# -eq 0 ]]; then
      command kubectl "$@"
      return
  fi

  # Get the current Kubernetes context using the original kubectl
  local current_context=$(command kubectl config current-context)
  local cmd_arg="$1"

  # Check if context is production and first argument is not "get" or "describe"
  if [[ "$current_context" == "production" ]] && [[ "$cmd_arg" != "get" && "$cmd_arg" != "describe" ]]; then
      echo -e "e[33mWARNING:e[0m You are about to run a kubectl command in PRODUCTION"
      echo "Command to be executed: kubectl $@"
      echo -n "Are you sure you want to proceed? (y/N) "

      local confirm
      read -k 1 confirm
      echo "" # newline after input

      if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
          echo "Command cancelled"
          return 1
      fi
  fi

  # Execute original kubectl
  command kubectl "$@"
}

# Use the original kubectl completion function directly
compdef _kubectl kubectl

This has been working for my needs but may grow if I need to exclude more commands.