Isidro is an Anthos- and GKE-based microservices chatbot
Note that further unification of GKE and Anthos, via GKE Enterprise (announced at Next '23), may provide an easier way to run the full, multi-continental chatbot configuration
Isidro includes:
- Prebuilt connectors to Slack and Mattermost for event subscription and response
- Flexible, policy-based workflow planning
- Layered intent classification: BERT → ngrams-based regression → non-ML NLP techniques
- Easy delegation of build and deploy workflows to Jenkins, Cloud Build, and GitHub Actions
- Automated execution of workflows (e.g., provisioning, deployments, and test execution)
- Automated presentation of data (e.g., deployment metrics, performance testing results, and spam trends)
- Well-established paths for both development and production deployments
- DEV: 2 clusters, 2 regions, 5 zones, and a regional Cloud Spanner instance
- PROD: 6 clusters, 6 regions, 13 zones, and a multi-regional Cloud Spanner instance
- Security features like binary authorization, mTLS, workload identity, and network policies
- APIs and features enabled on Google Cloud Platform:
- API: Anthos
- API: Anthos Service Mesh Certificate Authority
- API: Binary Authorization
- API: Cloud KMS
- API: Cloud Resource Manager
- API: GKE Hub
- API: Kubernetes Engine
- API: Multi Cluster Ingress
- API: Multi-Cluster Service Discovery
- API: Traffic Director
gcloud services enable \ anthos.googleapis.com \ binaryauthorization.googleapis.com \ cloudkms.googleapis.com \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ gkehub.googleapis.com \ redis.googleapis.com \ meshca.googleapis.com \ multiclusteringress.googleapis.com \ multiclusterservicediscovery.googleapis.com \ spanner.googleapis.com \ trafficdirector.googleapis.com
- Anthos Feature: Service Mesh
- A domain or subdomain managed through Google Cloud DNS
- Skaffold CLI v1.39+
While installation is possible using non-Linux clients, it's not a well-established or documented process
Set the GOOGLE_PROJECT
, API_DOMAIN
, MATTERMOST_DOMAIN
, and DNS_ZONE_NAME
environment variables, with something like:
export GOOGLE_PROJECT=example
export API_DOMAIN=api.example.com
export MATTERMOST_DOMAIN=mattermost.example.com
export DNS_ZONE_NAME="example-com"
Create a service account for provisioning the required resources:
gcloud iam roles create isidro_provisioner \
--project=$GOOGLE_PROJECT \
--file=roles/provisioner.yaml
gcloud iam service-accounts create isidro-provisioner \
--display-name="Isidro Provisioner"
gcloud projects add-iam-policy-binding $GOOGLE_PROJECT \
--member="serviceAccount:isidro-provisioner@$GOOGLE_PROJECT.iam.gserviceaccount.com" \
--role="projects/$GOOGLE_PROJECT/roles/isidro_provisioner"
gcloud iam service-accounts keys create isidro-provisioner.json \
--iam-account="isidro-provisioner@$GOOGLE_PROJECT.iam.gserviceaccount.com"
export GOOGLE_APPLICATION_CREDENTIALS=$PWD/isidro-provisioner.json
Navigate to the development or production directory and run Terraform provisioning, with something like:
gcloud init
terraform init
terraform apply
Create kubecontext configurations for the provisioned clusters:
# For development setups
gcloud container clusters get-credentials isidro-us --region us-central1
gcloud container clusters get-credentials isidro-config --region northamerica-northeast1
kubectl config rename-context gke_"$GOOGLE_PROJECT"_us-central1_isidro-us isidro-us
kubectl config rename-context gke_"$GOOGLE_PROJECT"_northamerica-northeast1_isidro-config isidro-config
# For production setups
gcloud container clusters get-credentials isidro-us-ia --region us-central1
gcloud container clusters get-credentials isidro-us-sc --region us-east1
gcloud container clusters get-credentials isidro-be --region europe-west1
gcloud container clusters get-credentials isidro-nl --region europe-west4
gcloud container clusters get-credentials isidro-tw --region asia-east1
gcloud container clusters get-credentials isidro-config --region northamerica-northeast1
kubectl config rename-context gke_"$GOOGLE_PROJECT"_us-central1_isidro-us-ia isidro-us-ia
kubectl config rename-context gke_"$GOOGLE_PROJECT"_us-east1_isidro-us-sc isidro-us-sc
kubectl config rename-context gke_"$GOOGLE_PROJECT"_europe-west1_isidro-be isidro-be
kubectl config rename-context gke_"$GOOGLE_PROJECT"_europe-west4_isidro-nl isidro-nl
kubectl config rename-context gke_"$GOOGLE_PROJECT"_asia-east1_isidro-tw isidro-tw
kubectl config rename-context gke_"$GOOGLE_PROJECT"_northamerica-northeast1 isidro-config
Setup a service account for building the required artifacts:
gcloud iam service-accounts create isidro-skaffold \
--display-name="Isidro Skaffold"
gcloud projects add-iam-policy-binding $GOOGLE_PROJECT \
--member="serviceAccount:isidro-skaffold@$GOOGLE_PROJECT.iam.gserviceaccount.com" \
--role="roles/cloudbuild.builds.builder"
gcloud iam service-accounts keys create isidro-skaffold.json \
--iam-account="isidro-skaffold@$GOOGLE_PROJECT.iam.gserviceaccount.com"
export GOOGLE_APPLICATION_CREDENTIALS=$PWD/isidro-skaffold.json
Add helm repositories:
helm repo add mattermost https://helm.mattermost.com
helm repo add jetstack https://charts.jetstack.io
Hydrate configurations:
cp skaffold.dev.yaml skaffold.yaml
sed -i "s/GOOGLE_PROJECT/$GOOGLE_PROJECT/g" skaffold.yaml
sed -i "s/MATTERMOST_DOMAIN/$MATTERMOST_DOMAIN/g" skaffold.yaml
sed -i "s/API_DOMAIN/$API_DOMAIN/g" skaffold.yaml
sed -i "s/DNS_ZONE_NAME/$DNS_ZONE_NAME/g" skaffold.yaml
Make any required skaffold.yaml
configuration changes, then run skaffold:
skaffold dev
Hydrate confiigurations:
cp skaffold.prod.yaml skaffold.yaml
sed -i "s/GOOGLE_PROJECT/$GOOGLE_PROJECT/g" skaffold.yaml
sed -i "s/MATTERMOST_DOMAIN/$MATTERMOST_DOMAIN/g" skaffold.yaml
sed -i "s/API_DOMAIN/$API_DOMAIN/g" skaffold.yaml
sed -i "s/DNS_ZONE_NAME/$DNS_ZONE_NAME/g" skaffold.yaml
Make any required skaffold.yaml
configuration changes, then run skaffold:
skaffold run
To teardown:
skaffold delete
In the Terraform provisioning directory, run:
gcloud init
terraform destroy
Relevant if you are using Slack as your chat tool
Create a Slack app:
- Update the example Slack manifest to use your Isidro endpoint
- Create a Slack app using the application manifest
- Consider giving the app a profile picture (e.g., the Terminator)
- Use the verification token, under the app's "Basic Information" for Helm value
slack.verificationToken
- Use the OAuth token, under the app's "OAuth & Permissions" for Helm value
slack.oauthToken
Relevant if you are using Mattermost as your chat tool
- In the System Console, under "Integrations > Bot Accounts", "Enable Bot Account Creation"
- In the Integrations portal, create a bot account with the name "isidro" and role "System Administrator"
- Consider giving the app a profile picture (e.g., the Terminator)
- Copy the access token to the Helm values (or Skaffold overrides) as
mattermost.accessToken
- Add an outgoing webhook:
- Recommended title is "Isidro Mentions"
- Recommended description is "Push notification enabling the Isidro chatbot to respond to @mentions"
- Application type is "application/json"
- Trigger word is "@isidro"
- Callback URL is https://api.example.com/v1/submit (replace api.example.com with your Isidro API domain)
- Leave the remaining values as the defaults
- Copy the verification token to the Helm values (or Skaffold overrides) as
mattermost.verificationToken
- Upgrade the Helm installation
Relevant if you are triggering GitHub Actions workflows with the chatbot
Create a personal access token, which includes repo
, workflow
, and packages
permissions. Use the token for the Helm value deployer.github.token
.
Mention @isidro in Slack messages, and get a response. Use separate message threads for separate chatbot conversations.
curl -X POST https://api.example.com/v1/submit \
-H "Content-Type: application/json" \
-d '{"token": "1234567890", "event": {"channel": "quality", "ts": "1234567890", "user": "me", "text": "Hello"}}'