Skip to content

Instantly share code, notes, and snippets.

@juan131
Last active April 8, 2024 07:33
Show Gist options
  • Save juan131/654ab3df8db2b09ccf6508e0a6aee42f to your computer and use it in GitHub Desktop.
Save juan131/654ab3df8db2b09ccf6508e0a6aee42f to your computer and use it in GitHub Desktop.
A script to install NGINX Ingress Controller in your local K8s cluster with a NGROK proxy so you have a valid URL associated to your Ingress.
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# Constants
RESET='\033[0m'
GREEN='\033[38;5;2m'
RED='\033[38;5;1m'
YELLOW='\033[38;5;3m'
# Axiliar functions
########################
# Log message to stderr
# Arguments:
# $1 - Message to log
#########################
log() {
printf "%b\n" "${*}" >&2
}
########################
# Log info message
# Arguments:
# $1 - Message to log
#########################
info() {
log "${GREEN}INFO ${RESET} ==> ${*}"
}
########################
# Log error message
# Arguments:
# $1 - Message to log
#########################
error() {
log "${RED}ERROR ${RESET} ==> ${*}"
}
########################
# Wait for a deployment to be rolled out
# Arguments:
# $1 - Namespace
# $2 - Deployment name
# Returns:
# Integer - ExitCode
#########################
k8s_wait_for_deployment() {
namespace=${1:?namespace is missing}
deployment=${2:?deployment name is missing}
local -i exit_code=0
# Avoid to exit the function if the rollout fails
kubectl rollout status --namespace "$namespace" deployment "$deployment" >/dev/null 2>&1 || exit_code=$?
return $exit_code
}
########################
# Print menu
#########################
print_menu() {
local script
script=$(basename "${BASH_SOURCE[0]}")
log "${RED}NAME${RESET}"
log " $(basename -s .sh "${BASH_SOURCE[0]}")"
log ""
log "${RED}SYNOPSIS${RESET}"
log " $script [${YELLOW}-h${RESET}] [${YELLOW}-n ${GREEN}\"namespace\"${RESET}] [${YELLOW}-t ${GREEN}\"ngrok-token\"${RESET}]"
log ""
log "${RED}DESCRIPTION${RESET}"
log " Script to install NGINX Ingress Controller in your K8s cluster with an NGROK proxy."
log ""
log " The options are as follow:"
log ""
log " ${YELLOW}-n, --namespace ${GREEN}[namespace]${RESET} Namespace where te create the POD."
log " ${YELLOW}-t, --token${RESET} NGROK token."
log " ${YELLOW}-h, --help${RESET} Print this help menu."
log ""
log "${RED}EXAMPLES${RESET}"
log " $script --help"
log " $script --namespace \"ingress\" --token \"ngrok-token\""
log ""
}
namespace="kube-system"
token=""
help_menu=0
while [[ "$#" -gt 0 ]]; do
case "$1" in
-h|--help)
help_menu=1
;;
-n|--namespace)
shift; namespace="${1:?missing namespace}"
;;
-t|--token)
shift; token="${1:?missing token}"
;;
*)
error "Invalid command line flag $1" >&2
exit 1
;;
esac
shift
done
if [[ -z "$token" ]]; then
help_menu=1
error "No NGROK token was indicated"
fi
if [[ "$help_menu" -eq 1 ]] ; then
print_menu
exit 0
fi
info "Installing NGINX Ingress Controller in namespace $namespace"
if ! helm upgrade --install nginx-ingress-controller oci://registry-1.docker.io/bitnamicharts/nginx-ingress-controller -n "$namespace" >/dev/null 2>&1; then
error "Failed to install NGINX Ingress Controller"
exit 1
fi
k8s_wait_for_deployment "$namespace" "nginx-ingress-controller"
info "NGINX Ingress Controller installed successfully"
proxy_manifests="(mktemp)"
cleanup() {
rm "$proxy_manifests"
}
trap cleanup EXIT
cat > "$proxy_manifests" << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller-ngrok-proxy
namespace: ${namespace}
labels:
app.kubernetes.io/instance: nginx-ingress-controller
app.kubernetes.io/component: ngrok-proxy
spec:
selector:
matchLabels:
app.kubernetes.io/instance: nginx-ingress-controller
app.kubernetes.io/component: ngrok-proxy
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/instance: nginx-ingress-controller
app.kubernetes.io/component: ngrok-proxy
spec:
containers:
- name: ngrok
image: wernight/ngrok
command:
- /bin/sh
args:
- -ec
- |
#!/bin/sh
ngrok authtoken \${NGROK_AUTH}
exec ngrok http nginx-ingress-controller
env:
- name: NGROK_AUTH
valueFrom:
secretKeyRef:
name: ngrok
key: token
ports:
- containerPort: 4040
name: http
---
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller-ngrok-proxy
namespace: ${namespace}
labels:
app.kubernetes.io/instance: nginx-ingress-controller
app.kubernetes.io/component: ngrok-proxy
spec:
type: ClusterIP
ports:
- name: http
port: 4040
targetPort: http
protocol: TCP
selector:
app.kubernetes.io/instance: nginx-ingress-controller
app.kubernetes.io/component: ngrok-proxy
EOF
info "Deploying NGROK proxy"
if kubectl get deploy -n "$namespace" nginx-ingress-controller-ngrok-proxy >/dev/null 2>&1; then
error "There's already a NGROK proxy deployed"
exit 1
fi
kubectl delete secret ngrok --ignore-not-found -n "$namespace"
kubectl create secret generic ngrok --from-literal=token="$token" -n "$namespace"
if ! kubectl create -f "$proxy_manifests" >/dev/null 2>&1; then
error "Failed to deploy NGROK proxy"
exit 1
fi
k8s_wait_for_deployment "$namespace" "nginx-ingress-controller-ngrok-proxy"
info "NGROK proxy deployed successfully"
info "Use the command below to obtain the public URL you can use to access the NGINX Ingress Controller"
log ""
log " kubectl port-forward -n $namespace svc/nginx-ingress-controller-ngrok-proxy 4040:4040 >/dev/null 2>&1 &"
log " curl -s http://127.0.0.1:4040/api/tunnels | jq -r .tunnels[].public_url"
log ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment