This component provides a Slack application designed to integrate with the Kubernetes Pizza Observability project. The primary purpose of this Slack app is to provide a human-in-the-loop confirmation step for pizza orders triggered by cluster alerts. It enhances the system by allowing team members to review and approve or reject automated pizza orders via an interactive Slack message, preventing unwanted orders and adding a layer of control.
Example of a Slack confirmation message for a pizza order
The Slack app is a Node.js application built using the Bolt for JavaScript framework. Its key architectural components include:
app.js or app-http.js): The main application instance that initializes the Bolt framework, configures listeners for Slack events, actions, and commands.app_mention or messages in subscribed channels.PizzaOrder resources directly.npm or yarn for package management.ngrok is highly recommended. For production, this will be the URL of your deployed application (e.g., on a server, container platform, or serverless function).Once the app is created, you'll need to configure its features from the app's settings page (sidebar navigation):
chat:write: Allows the app to send messages as itself.commands: Allows the app to register and respond to slash commands.chat:write.public: To write to public channels it's not a member of.users:read: If you need to look up user information./k8s-pizza-approvehttps://YOUR_PUBLIC_APP_URL/slack/commands (replace YOUR_PUBLIC_APP_URL)https://YOUR_PUBLIC_APP_URL/slack/actions (replace YOUR_PUBLIC_APP_URL). This URL will receive payloads when users click buttons or interact with other components.https://YOUR_PUBLIC_APP_URL/slack/events (replace YOUR_PUBLIC_APP_URL). Slack will verify this URL.app_mention if you want it to respond to mentions).xoxb-...).Your Node.js application will require environment variables to connect to Slack and other services. Create a .env file in the slack/ directory (this file should be in your .gitignore to avoid committing secrets).
# Slack App Credentials
SLACK_BOT_TOKEN="xoxb-YOUR_SLACK_BOT_TOKEN" # Found under "OAuth & Permissions" after installing the app
SLACK_SIGNING_SECRET="YOUR_SLACK_SIGNING_SECRET" # Found under "Basic Information" -> App Credentials
# Port for the Slack app to run on
PORT=3000 # Or any other port you prefer
# URL of your Azure Function (or other alert handler)
# This is where the Slack app will send the approval/rejection signal
AZURE_FUNCTION_URL="https://YOUR_AZURE_FUNCTION_APP_NAME.azurewebsites.net/api/HttpPizzaOrderConfirmationHandler" # Example URL
# (Optional) Kubernetes API details if slash commands interact directly with the cluster
# KUBERNETES_API_URL="https://YOUR_K8S_API_SERVER_URL"
# KUBERNETES_TOKEN="YOUR_K8S_SERVICE_ACCOUNT_TOKEN"
app.js / app-http.js)Ensure your app.js (or app-http.js if using HTTP mode for serverless environments) is configured to:
SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET.PORT.AZURE_FUNCTION_URL with the decision.# Navigate to the slack directory
cd slack
# Install dependencies
npm install
# Start the application
npm start
Dockerfile in the slack/ directory similar to this:
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000 # Or your configured PORT
CMD [ "node", "app.js" ] # Or app-http.js
# Build the Docker image
docker build -t k8s-pizza-slack-app .
# Run the container (ensure .env file is available or pass env vars directly)
docker run -d -p 3000:3000 --env-file .env k8s-pizza-slack-app
Deployment and Service manifest for the Slack app.SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET as Kubernetes Secrets and mount them as environment variables into the pod.Service is exposed publicly (e.g., via an Ingress controller) so Slack can reach its endpoints.slack-app-deployment.yaml (simplified):
apiVersion: apps/v1
kind: Deployment
metadata:
name: slack-app
namespace: k8s-pizza
spec:
replicas: 1
selector:
matchLabels:
app: slack-app
template:
metadata:
labels:
app: slack-app
spec:
containers:
- name: slack-app
image: your-registry/k8s-pizza-slack-app:latest # Your Docker image
ports:
- containerPort: 3000
env:
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
name: slack-credentials
key: botToken
- name: SLACK_SIGNING_SECRET
valueFrom:
secretKeyRef:
name: slack-credentials
key: signingSecret
- name: AZURE_FUNCTION_URL
value: "YOUR_AZURE_FUNCTION_URL"
- name: PORT
value: "3000"
---
apiVersion: v1
kind: Service
metadata:
name: slack-app-service
namespace: k8s-pizza
spec:
selector:
app: slack-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP # Use LoadBalancer or Ingress for external access
PizzaOrder CR in Kubernetes, which the Pizza Controller then picks up to place the actual Dominos order.ngrok, ensure it's running and the URL in Slack settings matches the ngrok forwarding URL.not_authed, invalid_auth):
SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET are correct in your environment configuration.commands scope is added.AZURE_FUNCTION_URL.AZURE_FUNCTION_URL is correct and the Azure Function is running and accessible.npm start.docker logs <container_id_or_name>kubectl logs -n k8s-pizza <slack-app-pod-name>SLACK_SIGNING_SECRET to ensure they are genuine. Bolt for JavaScript handles this automatically if configured correctly.SLACK_BOT_TOKEN and other secrets securely. Do not hardcode them. Use environment variables and, in production Kubernetes, use Kubernetes Secrets.Contributions to enhance the Slack integration are welcome. This could include: