Skip to content

Commit dd61f1b

Browse files
committed
Add Rasa & Studio installation steps
1 parent 9e03605 commit dd61f1b

18 files changed

+486
-86
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ azure/configure/test-ingress-certificate.yaml
5656
azure/configure/test-ingress-httpbin-values.yaml
5757
azure/configure/db-init.yaml
5858
azure/rasa/kafka/kafka.yaml
59+
azure/rasa/assistant/repos/*
60+
azure/rasa/assistant/values.yaml
61+
azure/rasa/ingress/ingress.yaml
62+
azure/rasa/ingress/certificate.yaml
63+
azure/studio/repos/*
64+
azure/studio/values.yaml
65+
azure/studio/certificate.yaml
66+
5967

6068

6169
# Dev

aws/setup/environment-variables.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ export BUCKET_NAME_ENTROPY="xbuc"
3939
export MODEL_BUCKET="${MY_COMPANY_NAME}-${BUCKET_NAME_ENTROPY}-${NAME}-model"
4040
# The name of the bucket used to store models for Rasa Studio.
4141
export STUDIO_BUCKET="${MY_COMPANY_NAME}-${BUCKET_NAME_ENTROPY}-${NAME}-studio"
42-
# Process your domain name to create a DNS zone name for Amazon Route 53.
43-
export DNS_ZONE=$(echo "$DOMAIN" | sed -e 's/\./-/g')
4442
# The Kubernetes namespace that will be used for the deployment.
4543
export NAMESPACE=rasa
4644
# The database name for Rasa Pro.

azure/configure/configure-cluster.sh

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
55

66
# Source common utilities
77
source "$SCRIPT_DIR/../../utils/common.sh"
8+
source "$SCRIPT_DIR/../utils/common.sh"
89

9-
print_info "Generating kubeconfig to authenticate with EKS cluster..."
10-
# To be able to interact with the EKS cluster we deployed earlier, we need to obtain the credentials for it. These credentials are saved in a file called kubeconfig which the Azure CLI can generate for us and kubectl can use.
11-
# Ensure we've got a path setup for the kubeconfig file:
12-
export KUBECONFIG=$(pwd)/kubeconfig
13-
print_info "Kubeconfig path: $KUBECONFIG"
14-
rm -f $KUBECONFIG
15-
# Retrieve the credentials for the cluster using the Azure CLI:
16-
az aks get-credentials --resource-group "$NAME" --name "$NAME"
17-
# Next, validate that the credentials work - we should see information about our cluster output here if everything has worked.
18-
print_info "Kubeconfig generated successfully! Printing cluster info below, if you see output here, authentication was successful."
19-
kubectl cluster-info
20-
kubectl get ns
10+
auth_to_k8s
2111

2212
# Get the directory where this script is located
2313
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

azure/configure/get-infra-values.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export REDIS_HOST=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw redis_host)
3333
export REDIS_AUTH=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw redis_pw)
3434

3535
export SERVICE_ACCOUNT_DNS=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw client_id_dns)
36-
export SERVICE_ACCOUNT_ASSISTANT=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw client_id_assistant)
3736
export SERVICE_ACCOUNT_STUDIO=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw client_id_studio)
3837

3938
echo "Infrastructure values fetched successfully:"
@@ -44,5 +43,4 @@ echo "DB_HOST=$DB_HOST"
4443
echo "REDIS_HOST=$REDIS_HOST"
4544
echo "REDIS_AUTH=$REDIS_AUTH"
4645
echo "SERVICE_ACCOUNT_DNS=$SERVICE_ACCOUNT_DNS"
47-
echo "SERVICE_ACCOUNT_ASSISTANT=$SERVICE_ACCOUNT_ASSISTANT"
4846
echo "SERVICE_ACCOUNT_STUDIO=$SERVICE_ACCOUNT_STUDIO"

azure/deploy/main.tf.template

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,6 @@ resource "azuread_application" "assistant" {
185185
owners = [data.azuread_client_config.current.object_id]
186186
}
187187

188-
resource "azuread_service_principal" "assistant" {
189-
client_id = azuread_application.assistant.client_id
190-
app_role_assignment_required = false
191-
owners = [data.azuread_client_config.current.object_id]
192-
use_existing = true
193-
}
194-
195188
output "client_id_assistant" {
196189
value = azuread_application.assistant.client_id
197190
}
@@ -203,13 +196,6 @@ resource "azuread_application" "studio" {
203196
owners = [data.azuread_client_config.current.object_id]
204197
}
205198

206-
resource "azuread_service_principal" "studio" {
207-
client_id = azuread_application.studio.client_id
208-
app_role_assignment_required = false
209-
owners = [data.azuread_client_config.current.object_id]
210-
use_existing = true
211-
}
212-
213199
output "client_id_studio" {
214200
value = azuread_application.studio.client_id
215201
}
@@ -228,33 +214,20 @@ resource "azurerm_storage_account" "main" {
228214

229215
# Model storage container
230216

231-
resource "azurerm_storage_container" "model" {
232-
name = "${NAME}-model"
217+
resource "azurerm_storage_container" "assistant" {
218+
name = "${ASSISTANT_STORAGE_CONTAINER}"
233219
storage_account_id = azurerm_storage_account.main.id
234220
container_access_type = "private"
235221
}
236222

237-
resource "azurerm_role_assignment" "assistant_storage_blob_data_reader" {
238-
scope = azurerm_storage_container.model.id
239-
role_definition_name = "Storage Blob Data Reader"
240-
principal_id = resource.azuread_service_principal.assistant.object_id
241-
}
242-
243223
# Studio storage container
244224

245225
resource "azurerm_storage_container" "studio" {
246-
name = "${NAME}-studio"
226+
name = "${STUDIO_STORAGE_CONTAINER}"
247227
storage_account_id = azurerm_storage_account.main.id
248228
container_access_type = "private"
249229
}
250230

251-
resource "azurerm_role_assignment" "studio_storage_blob_data_contributor" {
252-
scope = azurerm_storage_container.model.id
253-
role_definition_name = "Storage Blob Data Contributor"
254-
principal_id = resource.azuread_service_principal.assistant.object_id
255-
}
256-
257-
258231
# Key Vault ==============================================
259232

260233
resource "azurerm_key_vault" "main" {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
set -e
2+
3+
# Get the directory where this script is located
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
6+
# Source common utilities
7+
source "$SCRIPT_DIR/../../../utils/common.sh"
8+
source "$SCRIPT_DIR/../../utils/common.sh"
9+
10+
auth_to_k8s
11+
12+
print_info "Deleting Rasa Helm chart if it already exists..."
13+
rm -rf $SCRIPT_DIR/repos
14+
15+
# This Helm chart contains instructions for setting up theRasa bot and Analytics components.
16+
print_info "Pulling Rasa Helm chart..."
17+
mkdir $SCRIPT_DIR/repos
18+
helm pull oci://europe-west3-docker.pkg.dev/rasa-releases/helm-charts/rasa --version 1.2.5 --untar --destination $SCRIPT_DIR/repos/rasa-helm
19+
20+
print_info "Getting storage account key..."
21+
SAKEYS_OUTPUT_OUTPUT=$(az storage account keys list \
22+
--resource-group $NAME \
23+
--account-name $NAME)
24+
25+
# Next, we'll ensure that other passwords and secret values that Rasa requires are set, before creating a Kubernetes Secret to securely store them in a way that we can reference later on:
26+
print_info "Creating secrets for the Rasa assistant to use..."
27+
export AUTH_TOKEN=$(openssl rand -hex 8 | base64)
28+
export JWT_SECRET=$(openssl rand -hex 8 | base64)
29+
export KAFKA_CLIENT_PASSWORD=$(kubectl get secret kafka -n $NAMESPACE -o jsonpath='{.data.password}' | base64 -d | cut -d ',' -f 1)
30+
export STORAGE_ACCOUNT_KEY=$(echo $SAKEYS_OUTPUT_OUTPUT | jq -r '.[0].value')
31+
32+
print_info "Secret values retrieved. Validating that all required values are set..."
33+
34+
# Validate all required secret variables
35+
validate_variables \
36+
"AUTH_TOKEN" \
37+
"JWT_SECRET" \
38+
"REDIS_AUTH" \
39+
"KAFKA_CLIENT_PASSWORD" \
40+
"DB_ASSISTANT_PASSWORD" \
41+
"STORAGE_ACCOUNT_KEY" \
42+
"RASA_PRO_LICENSE" \
43+
"OPENAI_API_KEY"
44+
45+
print_info "Deleting a secret if it already exists..."
46+
kubectl delete secret rasa-secrets -n $NAMESPACE || true
47+
48+
print_info "Creating a Kubernetes secret for these values..."
49+
kubectl --namespace $NAMESPACE \
50+
create secret generic rasa-secrets \
51+
--from-literal=authToken="$(echo $AUTH_TOKEN )" \
52+
--from-literal=jwtSecret="$(echo $JWT_SECRET)" \
53+
--from-literal=redisPassword="$(echo REDIS_AUTH)" \
54+
--from-literal=kafkaSslPassword="$(echo $KAFKA_CLIENT_PASSWORD)" \
55+
--from-literal=dbPassword="$(echo DB_ASSISTANT_PASSWORD)" \
56+
--from-literal=storageAccountKey="$(echo $STORAGE_ACCOUNT_KEY)" \
57+
--from-literal=rasaProLicense="$(echo $RASA_PRO_LICENSE )" \
58+
--from-literal=openaiApiKey="$(echo $OPENAI_API_KEY)"
59+
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
rasa:
2+
enabled: true
3+
settings:
4+
environment: production
5+
enableApi: true
6+
credentials:
7+
enabled: true
8+
additionalChannelCredentials:
9+
socketio:
10+
bot_message_evt: bot_uttered
11+
metadata_key: customData
12+
session_persistence: false
13+
user_message_evt: user_uttered
14+
rest: { }
15+
endpoints:
16+
modelGroups:
17+
- id: openai-gpt-4o
18+
models:
19+
- max_tokens: 256
20+
model: gpt-4o-2024-11-20
21+
provider: openai
22+
request_timeout: 7
23+
- id: openai-embeddings
24+
models:
25+
- model: text-embedding-3-small
26+
provider: openai
27+
models:
28+
enabled: false
29+
# Configure the assistant to use our PostgreSQL instance as the Tracker Store, which records the assistant's conversations.
30+
trackerStore:
31+
enabled: true
32+
type: sql
33+
dialect: postgresql
34+
url: ${DB_HOST}
35+
db: ${DB_ASSISTANT_DATABASE}
36+
username: ${DB_ASSISTANT_USERNAME}
37+
password: ${DB_PASSWORD}
38+
port: 5432
39+
# Configure the assistant to use Redis as the Rasa Lock Store.
40+
# This is needed when you have a high-load scenario that requires the Rasa server to be replicated across multiple instances. It ensures that even with multiple servers, the messages for each conversation are handled in the correct sequence without any loss or overlap.
41+
lockStore:
42+
enabled: true
43+
type: concurrent_redis
44+
password: ${REDIS_PASSWORD}
45+
port: 6380
46+
url: ${REDIS_HOST}
47+
use_ssl: true
48+
key_prefix: ${NAME}
49+
# Configure the assistant to use the Kafka broker. This allows us to perform further processing on the messages, like using the Rasa Studio Conversation View or Rasa Pro Analytics.
50+
eventBroker:
51+
enabled: true
52+
type: kafka
53+
security_protocol: SASL_PLAINTEXT
54+
sasl_mechanism: SCRAM-SHA-512
55+
topic: rasa
56+
url: kafka-kafka-bootstrap.${NAMESPACE}.svc.cluster.local:9092
57+
sasl_username: kafka
58+
sasl_password: ${KAFKA_PASSWORD}
59+
ssl_check_hostname: false
60+
# We'll configure Rasa to use Azure for remote storage, so we can load models from the buckets we created earlier.
61+
additionalArgs:
62+
- --remote-storage
63+
- azure
64+
# Define the environment variables that Rasa needs to function and interact with the above services.
65+
# Note here that some of the values are plaintext environment variables and some are configured to be pulled from the Kubernetes Secret we created earlier.
66+
additionalEnv:
67+
- name: AZURE_CONTAINER
68+
value: ${ASSISTANT_STORAGE_CONTAINER}
69+
- name: AZURE_ACCOUNT_NAME
70+
value: ${NAME}
71+
- name: AZURE_ACCOUNT_KEY
72+
valueFrom:
73+
secretKeyRef:
74+
name: rasa-secrets
75+
key: storageAccountKey
76+
- name: BUCKET_NAME
77+
value: ${MODEL_BUCKET}
78+
- name: DB_PASSWORD
79+
valueFrom:
80+
secretKeyRef:
81+
name: rasa-secrets
82+
key: dbPassword
83+
- name: KAFKA_PASSWORD
84+
valueFrom:
85+
secretKeyRef:
86+
name: rasa-secrets
87+
key: kafkaSslPassword
88+
- name: REDIS_PASSWORD
89+
valueFrom:
90+
secretKeyRef:
91+
name: rasa-secrets
92+
key: redisPassword
93+
- name: OPENAI_API_KEY
94+
valueFrom:
95+
secretKeyRef:
96+
key: openaiApiKey
97+
name: rasa-secrets
98+
# Disable other Rasa components for now.
99+
# https://rasa.com/docs/reference/integrations/analytics/
100+
rasaProServices:
101+
enabled: false
102+
# https://rasa.com/docs/action-server
103+
actionServer:
104+
enabled: false
105+
# https://rasa.com/docs/reference/integrations/tracing
106+
tracing:
107+
enabled: false
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
kind: Certificate
2+
apiVersion: cert-manager.io/v1
3+
metadata:
4+
name: $NAME-assistant
5+
namespace: istio-system
6+
spec:
7+
commonName: assistant.$DOMAIN
8+
dnsNames:
9+
- assistant.$DOMAIN
10+
duration: 2160h0m0s
11+
issuerRef:
12+
kind: ClusterIssuer
13+
name: letsencrypt
14+
renewBefore: 360h0m0s
15+
secretName: $NAME-assistant-tls
16+
usages:
17+
- server auth
18+
- client auth
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: Ingress
3+
metadata:
4+
name: $NAME-assistant
5+
namespace: $NAMESPACE
6+
spec:
7+
ingressClassName: istio
8+
tls:
9+
- hosts:
10+
- assistant.$DOMAIN
11+
secretName: $NAME-assistant-tls
12+
rules:
13+
- host: assistant.$DOMAIN
14+
http:
15+
paths:
16+
- path: /
17+
pathType: Prefix
18+
backend:
19+
service:
20+
name: rasa
21+
port:
22+
number: 5005
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
set -e
2+
3+
# Get the directory where this script is located
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
6+
# Source common utilities
7+
source "$SCRIPT_DIR/../../../utils/common.sh"
8+
source "$SCRIPT_DIR/../../utils/common.sh"
9+
10+
auth_to_k8s
11+
12+
# Configure certificate
13+
print_info "Configuring certificate..."
14+
envsubst < $SCRIPT_DIR/certificate.template.yaml > $SCRIPT_DIR/certificate.yaml
15+
16+
print_info "Deploying certificate..."
17+
kubectl apply -f $SCRIPT_DIR/certificate.yaml
18+
19+
# Configure ingress
20+
print_info "Configuring ingress..."
21+
envsubst < $SCRIPT_DIR/ingress.template.yaml > $SCRIPT_DIR/ingress.yaml
22+
23+
print_info "Deploying ingress..."
24+
kubectl apply -f $SCRIPT_DIR/ingress.yaml
25+
26+
print_info "You should now be able to access the Rasa assistant at https://assistant.$DOMAIN. It may take a few minutes for the certificate to issue and be fully available."

0 commit comments

Comments
 (0)