From ba9f0e557125389ea88993d804e1c4a9f65489b6 Mon Sep 17 00:00:00 2001 From: Riccardo Schirone <562321+ret2libc@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:14:35 +0200 Subject: [PATCH] Add Tailscale support to the custom scripts (#354) --- .gitignore | 1 + Makefile | 15 +---- deployment/crs-architecture.sh | 1 + deployment/env.template | 1 + .../{proxies.yaml => proxies.template} | 5 +- .../tailscale-coredns/coredns-custom.template | 2 +- .../k8s/charts/ui/templates/ingress.yaml | 23 +++++++ guides/AKS_DEPLOYMENT.md | 9 +++ scripts/setup-azure.sh | 28 +++++++++ scripts/web_ui.sh | 61 +++++++++++++++++++ 10 files changed, 129 insertions(+), 17 deletions(-) rename deployment/k8s/base/tailscale-connections/{proxies.yaml => proxies.template} (66%) create mode 100644 deployment/k8s/charts/ui/templates/ingress.yaml create mode 100755 scripts/web_ui.sh diff --git a/.gitignore b/.gitignore index b0734815..5c45cda3 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ errored.tfstate deployment/k8s/values-*.yaml deployment/k8s/base/tailscale-coredns/coredns-custom.yaml deployment/k8s/base/tailscale-operator/operator.yaml +deployment/k8s/base/tailscale-connections/proxies.yaml ## Python __pycache__/ diff --git a/Makefile b/Makefile index ac7bb380..a872828c 100644 --- a/Makefile +++ b/Makefile @@ -221,17 +221,4 @@ signoz-ui: fi web-ui: - @echo "Opening web UI (https://localhost:31323/)..." - @if ! kubectl get namespace $${BUTTERCUP_NAMESPACE:-crs} >/dev/null 2>&1; then \ - echo "Error: CRS namespace not found. Deploy first with 'make deploy'."; \ - exit 1; \ - fi - kubectl port-forward -n $${BUTTERCUP_NAMESPACE:-crs} service/buttercup-ui 31323:1323 & - @sleep 3 - @if command -v xdg-open >/dev/null 2>&1; then \ - xdg-open http://localhost:31323; \ - elif command -v open >/dev/null 2>&1; then \ - open http://localhost:31323; \ - else \ - echo "Please open http://localhost:31323 in your browser."; \ - fi + @./scripts/web_ui.sh diff --git a/deployment/crs-architecture.sh b/deployment/crs-architecture.sh index e09e31bf..95338e01 100755 --- a/deployment/crs-architecture.sh +++ b/deployment/crs-architecture.sh @@ -28,6 +28,7 @@ else fi if [ "$TAILSCALE_ENABLED" = "true" ]; then envsubst k8s/base/tailscale-operator/operator.yaml + envsubst k8s/base/tailscale-connections/proxies.yaml fi if [ "$(echo "$LANGFUSE_ENABLED" | tr '[:upper:]' '[:lower:]')" = "true" ]; then LANGFUSE_ENABLED="true" diff --git a/deployment/env.template b/deployment/env.template index dcbfab89..af5cd993 100644 --- a/deployment/env.template +++ b/deployment/env.template @@ -29,6 +29,7 @@ export TAILSCALE_ENABLED=false # or true # export TS_CLIENT_ID="" # export TS_CLIENT_SECRET="" # export TS_OP_TAG="" +# export TAILSCALE_DOMAIN="tail123456.ts.net" # AIxCC - Competition API settings, used to properly connect to the right endpoint and # with the right authentication. If COMPETITION_API_ENABLED is true, a test API diff --git a/deployment/k8s/base/tailscale-connections/proxies.yaml b/deployment/k8s/base/tailscale-connections/proxies.template similarity index 66% rename from deployment/k8s/base/tailscale-connections/proxies.yaml rename to deployment/k8s/base/tailscale-connections/proxies.template index 59e8eef2..251747c1 100644 --- a/deployment/k8s/base/tailscale-connections/proxies.yaml +++ b/deployment/k8s/base/tailscale-connections/proxies.template @@ -5,7 +5,7 @@ metadata: name: competition-echo-egress namespace: tailscale annotations: - tailscale.com/tailnet-fqdn: "echo.tail7e9b4c.ts.net" #Basic http echo test server + tailscale.com/tailnet-fqdn: "echo.${TAILSCALE_DOMAIN}" #Basic http echo test server spec: externalName: placeholder type: ExternalName @@ -16,7 +16,8 @@ metadata: name: competition-api-1-egress namespace: tailscale annotations: - tailscale.com/tailnet-fqdn: "api.tail7e9b4c.ts.net" #Competition API FQDN + tailscale.com/tailnet-fqdn: "api.${TAILSCALE_DOMAIN}" #Competition API FQDN spec: externalName: placeholder type: ExternalName + diff --git a/deployment/k8s/base/tailscale-coredns/coredns-custom.template b/deployment/k8s/base/tailscale-coredns/coredns-custom.template index 1dc790c3..724dada6 100644 --- a/deployment/k8s/base/tailscale-coredns/coredns-custom.template +++ b/deployment/k8s/base/tailscale-coredns/coredns-custom.template @@ -5,7 +5,7 @@ metadata: namespace: kube-system data: tailscale.server: | - tail7e9b4c.ts.net:53 { + ${TAILSCALE_DOMAIN}:53 { forward . ${TS_DNS_IP} cache 30 } diff --git a/deployment/k8s/charts/ui/templates/ingress.yaml b/deployment/k8s/charts/ui/templates/ingress.yaml new file mode 100644 index 00000000..009786ef --- /dev/null +++ b/deployment/k8s/charts/ui/templates/ingress.yaml @@ -0,0 +1,23 @@ +--- +kind: Ingress +apiVersion: networking.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-ui + annotations: + tailscale.com/hostname: "{{ default (printf "%s-ui" .Release.Name) }}" + tailscale.com/experimental-forward-cluster-traffic-via-ingress: "true" +spec: + ingressClassName: tailscale + tls: + - hosts: + - "{{ default (printf "%s-ui" .Release.Name) }}" + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Release.Name }}-ui + port: + number: {{ .Values.service.port }} diff --git a/guides/AKS_DEPLOYMENT.md b/guides/AKS_DEPLOYMENT.md index b21a1be3..9b161b78 100644 --- a/guides/AKS_DEPLOYMENT.md +++ b/guides/AKS_DEPLOYMENT.md @@ -21,6 +21,7 @@ number of tasks that you want to solve at the same time, size of projects, etc. For more fine-grained adjustments that are not configurable during the automated setup script, modify `deployment/env` and `deployment/values-upstream-aks.template`. In particular you may want to change the number of nodes in the k8s cluster, the type of nodes, the number of pods for different kind of services, the storage, etc. +We *strongly suggest* you also enable Tailscale, so that your cluster is accessible only through the Tailscale network. Moreover, for a real production environment, you may want to generate and set secrets for all services, including redis, postgresql, etc. ## Deploy to AKS @@ -30,6 +31,14 @@ For more fine-grained adjustments that are not configurable during the automated make deploy ``` +## Access the cluster + +To access the CRS Web interface: +```bash +make web-ui +``` + + ## Scaling and Management - **Scale nodes:** Update `TF_VAR_usr_node_count` in your env file and run `make deploy` again diff --git a/scripts/setup-azure.sh b/scripts/setup-azure.sh index 35b0840d..c09c3fb5 100755 --- a/scripts/setup-azure.sh +++ b/scripts/setup-azure.sh @@ -273,6 +273,33 @@ setup_aks_resources() { print_success "Set TF_VAR_usr_node_count to $usr_node_count in deployment/env" } +setup_tailscale() { + print_status "Setting up Tailscale..." + read -p "Do you want to setup Tailscale? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + print_status "Setting up Tailscale..." + print_status "Configure a OAuth Client at https://login.tailscale.com/admin/settings/oauth" + print_status "Make sure to configure Tailscale DNS and to enable HTTPS Certificates at https://login.tailscale.com/admin/dns" + + read -p "Enter the OAuth Client ID: " oauth_client_id + read -s -p "Enter the OAuth Client Secret: " oauth_client_secret + read -p "Enter the Tailscale Operator Tag: " tailscale_op_tag + read -p "Enter the Tailscale Domain: " tailscale_domain + + portable_sed "s|^[# ]*export TAILSCALE_ENABLED=.*|export TAILSCALE_ENABLED=\"true\"|" deployment/env + portable_sed "s|^[# ]*export TS_CLIENT_ID=.*|export TS_CLIENT_ID=\"$oauth_client_id\"|" deployment/env + portable_sed "s|^[# ]*export TS_CLIENT_SECRET=.*|export TS_CLIENT_SECRET=\"$oauth_client_secret\"|" deployment/env + portable_sed "s|^[# ]*export TS_OP_TAG=.*|export TS_OP_TAG=\"$tailscale_op_tag\"|" deployment/env + portable_sed "s|^[# ]*export TAILSCALE_DOMAIN=.*|export TAILSCALE_DOMAIN=\"$tailscale_domain\"|" deployment/env + + print_success "Set TAILSCALE_ENABLED to true in deployment/env" + else + portable_sed "s|^[# ]*export TAILSCALE_ENABLED=.*|export TAILSCALE_ENABLED=\"false\"|" deployment/env + print_success "Set TAILSCALE_ENABLED to false in deployment/env" + fi +} + # Function to provide deployment instructions deployment_instructions() { print_success "Production setup completed!" @@ -298,6 +325,7 @@ main() { setup_service_principal setup_remote_state setup_aks_resources + setup_tailscale print_status "Configuration validation..." if validate_config; then diff --git a/scripts/web_ui.sh b/scripts/web_ui.sh new file mode 100755 index 00000000..01740e69 --- /dev/null +++ b/scripts/web_ui.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +if [ ! -f deployment/env ]; then + echo "Error: Deployment environment file not found. Run 'make setup-local' or 'make setup-azure' first." + exit 1 +fi +source ./deployment/env + +if ! kubectl get namespace "${BUTTERCUP_NAMESPACE:-crs}" >/dev/null 2>&1; then + echo "Error: CRS namespace not found. Deploy first with 'make deploy'." + exit 1 +fi + +echo "Opening web UI..." + +if [ "${TAILSCALE_ENABLED:-false}" = "true" ]; then + # Use Tailscale domain + if [ -z "${TAILSCALE_DOMAIN}" ]; then + echo "Error: TAILSCALE_ENABLED is true but TAILSCALE_DOMAIN is not set" + exit 1 + fi + CRS_HOSTNAME="${CRS_HOSTNAME:-buttercup-ui}" + UI_URL="http://${CRS_HOSTNAME}.${TAILSCALE_DOMAIN}" +else + # Use local port-forward + echo "Starting port-forward to buttercup-ui service..." + kubectl port-forward -n "${BUTTERCUP_NAMESPACE:-crs}" service/buttercup-ui 31323:1323 & + PORT_FORWARD_PID=$! + sleep 3 + UI_URL="http://localhost:31323" + + # Function to cleanup on exit + cleanup() { + echo "" + echo "Stopping port-forward..." + kill $PORT_FORWARD_PID 2>/dev/null + echo "Port-forward stopped. Goodbye!" + exit 0 + } + + echo "" + echo "Port-forward is active. Press Ctrl+C to stop the port-forward and exit." + echo "The web UI will remain accessible at $UI_URL until you stop this process." + + # Set up signal handlers + trap cleanup SIGINT SIGTERM +fi + +echo "Opening web UI at $UI_URL in your browser..." +if command -v xdg-open >/dev/null 2>&1; then + xdg-open "$UI_URL" +elif command -v open >/dev/null 2>&1; then + open "$UI_URL" +else + echo "Please open $UI_URL in your browser." +fi + +if [ -n "$PORT_FORWARD_PID" ]; then + # Keep the script running + wait $PORT_FORWARD_PID +fi