Skip to content

Commit a645e36

Browse files
committed
Update AWS playbook to include changes for rasa-pro-services & AWS MSK IAM auth enabled (#5)
* add changes for kafka msk * fix path in endpoints * fix volume mount specification * add new iam enabled env vars per AWS service to rasa-pro values * [PF-489] Update AWS playbook to include rasa-pro-services deployment (#6) * update playbook to include rasa-pro-services deployment * fix values.template.yaml for rasa-pro-services to use a new helm chart release, add analytics db username to the rds policy * define analytics specific service account * make updates to rasa-pro-services values to use 1.3.0-rc.2 rasa helm chart
1 parent ba0c6aa commit a645e36

File tree

9 files changed

+329
-87
lines changed

9 files changed

+329
-87
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ aws/studio/certificate.yaml
4444
secret_db.json
4545

4646
# Dev
47-
aws/setup/environment-variables-dev.sh
47+
aws/setup/environment-variables-dev.sh
48+
AmazonRootCA1.pem

aws/configure/db-init.template.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ spec:
3535
echo "GRANT ALL PRIVILEGES ON SCHEMA public TO $DB_STUDIO_USERNAME;" | psql -qtAX --set=sslmode=require
3636
echo "granted schema public to keycloak"
3737
38+
echo "create analytics database and user"
39+
echo "CREATE USER $DB_ANALYTICS_USERNAME;" | psql -qtAX --set=sslmode=require
40+
echo "GRANT rds_iam TO $DB_ANALYTICS_USERNAME;" | psql -qtAX --set=sslmode=require
41+
echo "CREATE DATABASE $DB_ANALYTICS_DATABASE WITH ENCODING = 'UTF8';" | psql -qtAX --set=sslmode=require
42+
echo "GRANT ALL PRIVILEGES ON DATABASE $DB_ANALYTICS_DATABASE TO $DB_ANALYTICS_USERNAME;" | psql -qtAX --set=sslmode=require
43+
echo "ALTER DATABASE $DB_ANALYTICS_DATABASE OWNER TO $DB_ANALYTICS_USERNAME;" | psql -qtAX --set=sslmode=require
44+
3845
sleep 10
3946
echo "done"
4047
env:

aws/configure/get-infra-values.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ export DB_HOST="${DB_HOST%:$DB_PORT}"
2828
export REDIS_HOST=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw elasticache_cfg_endpoint)
2929
export REDIS_CLUSTER_NAME=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw elasticache_cluster_name)
3030

31+
export KAFKA_BOOTSTRAP_SERVER=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw msk_bootstrap_brokers | awk -F',' '{print $1}')
32+
3133
export SERVICE_ACCOUNT_DNS=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw service_account_dns)
3234
export SERVICE_ACCOUNT_ASSISTANT=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw service_account_assistant)
35+
export SERVICE_ACCOUNT_ANALYTICS=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw service_account_analytics)
3336
export SERVICE_ACCOUNT_STUDIO=$($TF_CMD -chdir=$TARGET_DIR_ABSOLUTE output -raw service_account_studio)
3437

3538
echo "Infrastructure values fetched successfully:"
@@ -42,4 +45,6 @@ echo "REDIS_HOST=$REDIS_HOST"
4245
echo "REDIS_CLUSTER_NAME=$REDIS_CLUSTER_NAME"
4346
echo "SERVICE_ACCOUNT_DNS=$SERVICE_ACCOUNT_DNS"
4447
echo "SERVICE_ACCOUNT_ASSISTANT=$SERVICE_ACCOUNT_ASSISTANT"
48+
echo "SERVICE_ACCOUNT_ANALYTICS=$SERVICE_ACCOUNT_ANALYTICS"
4549
echo "SERVICE_ACCOUNT_STUDIO=$SERVICE_ACCOUNT_STUDIO"
50+
echo "KAFKA_BOOTSTRAP_SERVER=$KAFKA_BOOTSTRAP_SERVER"

aws/deploy/main.tf.template

Lines changed: 159 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ variable "elasticache_subnets" {
2727
default = ["$CIDR_ELASTICACHE_A", "$CIDR_ELASTICACHE_B", "$CIDR_ELASTICACHE_C"]
2828
}
2929

30+
variable "msk_subnets" {
31+
default = ["$CIDR_MSK_A", "$CIDR_MSK_B", "$CIDR_MSK_C"]
32+
}
33+
3034
terraform {
3135
required_providers {
3236
aws = {
@@ -101,6 +105,20 @@ module "vpc" {
101105
}
102106
}
103107

108+
# MSK Subnets =========================================
109+
110+
resource "aws_subnet" "msk_subnets" {
111+
count = length(var.msk_subnets)
112+
113+
vpc_id = module.vpc.vpc_id
114+
cidr_block = var.msk_subnets[count.index]
115+
availability_zone = var.zones[count.index]
116+
117+
tags = {
118+
Name = "${NAME}-msk-${count.index + 1}"
119+
"kubernetes.io/cluster/${NAME}" = "shared"
120+
}
121+
}
104122

105123
# Kubernetes cluster EKS =========================================
106124

@@ -477,6 +495,74 @@ output "elasticache_cluster_name" {
477495
}
478496

479497

498+
# MSK Kafka Cluster =========================================
499+
500+
locals {
501+
msk_cluster_id = "rasa-${NAME}-kafka"
502+
}
503+
504+
module "msk_security_group" {
505+
source = "terraform-aws-modules/security-group/aws"
506+
version = "~> 5.3"
507+
508+
name = "rasa-${NAME}-msk"
509+
description = "Security group for MSK ${NAME}"
510+
vpc_id = module.vpc.vpc_id
511+
512+
ingress_cidr_blocks = module.vpc.private_subnets_cidr_blocks
513+
ingress_rules = ["kafka-broker-tcp", "kafka-broker-tls-tcp"]
514+
515+
egress_cidr_blocks = [module.vpc.vpc_cidr_block]
516+
egress_rules = ["all-all"]
517+
518+
tags = {
519+
Name = "rasa-${NAME}-msk"
520+
}
521+
}
522+
523+
resource "aws_msk_cluster" "kafka_cluster" {
524+
cluster_name = local.msk_cluster_id
525+
kafka_version = "3.8.x"
526+
number_of_broker_nodes = 3
527+
528+
broker_node_group_info {
529+
instance_type = "kafka.m5.large"
530+
client_subnets = aws_subnet.msk_subnets[*].id
531+
security_groups = [module.msk_security_group.security_group_id]
532+
533+
storage_info {
534+
ebs_storage_info {
535+
volume_size = 100
536+
}
537+
}
538+
}
539+
540+
client_authentication {
541+
sasl {
542+
iam = true
543+
}
544+
}
545+
546+
encryption_info {
547+
encryption_in_transit {
548+
client_broker = "TLS"
549+
in_cluster = true
550+
}
551+
}
552+
553+
tags = {
554+
Name = local.msk_cluster_id
555+
}
556+
}
557+
558+
output "msk_cluster_arn" {
559+
value = aws_msk_cluster.kafka_cluster.arn
560+
}
561+
562+
output "msk_bootstrap_brokers" {
563+
value = aws_msk_cluster.kafka_cluster.bootstrap_brokers_sasl_iam
564+
}
565+
480566
# DNS Identity =========================================
481567

482568
module "iam_role_dns" {
@@ -505,7 +591,7 @@ output "service_account_dns" {
505591
}
506592

507593

508-
# Rasa Assistent Identity =========================================
594+
# Rasa Assistant Identity =========================================
509595

510596
# S3 IAM Access Policy
511597

@@ -566,7 +652,8 @@ resource "aws_iam_policy" "rds_database_access" {
566652
"rds-db:connect"
567653
]
568654
Resource = [
569-
"arn:aws:rds-db:${REGION}:${data.aws_caller_identity.current.account_id}:dbuser:${module.rds_main.db_instance_resource_id}/${DB_ASSISTANT_USERNAME}"
655+
"arn:aws:rds-db:${REGION}:${data.aws_caller_identity.current.account_id}:dbuser:${module.rds_main.db_instance_resource_id}/${DB_ASSISTANT_USERNAME}",
656+
"arn:aws:rds-db:${REGION}:${data.aws_caller_identity.current.account_id}:dbuser:${module.rds_main.db_instance_resource_id}/${DB_ANALYTICS_USERNAME}"
570657
]
571658
},
572659
]
@@ -619,6 +706,44 @@ resource "aws_iam_policy" "bedrock_access" {
619706
})
620707
}
621708

709+
# MSK IAM Access Policy
710+
resource "aws_iam_policy" "msk_access" {
711+
name = "${NAME}_msk_access"
712+
path = "/"
713+
description = "Rasa ${NAME} MSK Kafka access"
714+
715+
policy = jsonencode({
716+
Version = "2012-10-17"
717+
Statement = [
718+
{
719+
Effect = "Allow"
720+
Action = [
721+
"kafka-cluster:Connect",
722+
"kafka-cluster:DescribeCluster"
723+
]
724+
Resource = "*"
725+
},
726+
{
727+
Effect = "Allow"
728+
Action = [
729+
"kafka-cluster:*Topic*",
730+
"kafka-cluster:WriteData",
731+
"kafka-cluster:ReadData"
732+
]
733+
Resource = "*"
734+
},
735+
{
736+
"Effect": "Allow",
737+
"Action": [
738+
"kafka-cluster:AlterGroup",
739+
"kafka-cluster:DescribeGroup"
740+
],
741+
"Resource": "*"
742+
}
743+
]
744+
})
745+
}
746+
622747

623748
module "iam_role_assistant" {
624749
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
@@ -627,10 +752,11 @@ module "iam_role_assistant" {
627752
role_name = "${NAME}-assistant"
628753

629754
role_policy_arns = {
630-
s3_policy = aws_iam_policy.assistant.arn
631-
redis_policy = aws_iam_policy.redis_access.arn
632-
rds_policy = aws_iam_policy.rds_database_access.arn
633-
bedrock_policy = aws_iam_policy.bedrock_access.arn
755+
s3 = aws_iam_policy.s3_access.arn
756+
redis = aws_iam_policy.redis_access.arn
757+
rds = aws_iam_policy.rds_database_access.arn
758+
bedrock = aws_iam_policy.bedrock_access.arn
759+
msk = aws_iam_policy.msk_access.arn
634760
}
635761

636762
oidc_providers = {
@@ -649,6 +775,33 @@ output "service_account_assistant" {
649775
value = local.service_account_assistant
650776
}
651777

778+
module "iam_role_analytics" {
779+
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
780+
version = "~> 5.59"
781+
782+
role_name = "${NAME}-analytics"
783+
784+
role_policy_arns = {
785+
rds = aws_iam_policy.rds_database_access.arn
786+
msk = aws_iam_policy.msk_access.arn
787+
}
788+
789+
oidc_providers = {
790+
rasa = {
791+
provider_arn = module.eks.oidc_provider_arn
792+
namespace_service_accounts = ["${NAMESPACE}:rasa-analytics"]
793+
}
794+
}
795+
}
796+
797+
locals {
798+
service_account_analytics = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${module.iam_role_analytics.iam_role_name}"
799+
}
800+
801+
output "service_account_analytics" {
802+
value = local.service_account_analytics
803+
}
804+
652805

653806
# Rasa Studio Identity =========================================
654807

aws/permissions/policy.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"arn:aws:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS",
99
"arn:aws:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup",
1010
"arn:aws:iam::*:role/aws-service-role/elasticache.amazonaws.com/AWSServiceRoleForElastiCache",
11-
"arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS"
11+
"arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS",
12+
"arn:aws:iam::*:role/aws-service-role/kafka.amazonaws.com/AWSServiceRoleForKafka"
1213
]
1314
},
1415
{
@@ -100,6 +101,7 @@
100101
"elasticache:ModifyUser",
101102
"elasticache:ModifyUserGroup",
102103
"elasticache:Connect",
104+
"kafka:*",
103105
"iam:AttachRolePolicy",
104106
"iam:CreateOpenIDConnectProvider",
105107
"iam:CreatePolicy",

aws/rasa/assistant/setup-assistant.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,18 @@ kubectl get ns
2222
# This Helm chart contains instructions for setting up the Rasa bot and Analytics components.
2323
print_info "Pulling Rasa Helm chart..."
2424
mkdir $SCRIPT_DIR/repos
25-
helm pull oci://europe-west3-docker.pkg.dev/rasa-releases/helm-charts/rasa --version 1.2.5 --untar --destination $SCRIPT_DIR/repos/rasa-helm
25+
helm pull oci://europe-west3-docker.pkg.dev/rasa-releases/helm-charts/rasa --version 1.3.0-rc.2 --untar --destination $SCRIPT_DIR/repos/rasa-helm
2626

2727
# 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:
2828
print_info "Creating secrets for the Rasa assistant to use..."
2929
export AUTH_TOKEN=$(openssl rand -hex 8 | base64)
3030
export JWT_SECRET=$(openssl rand -hex 8 | base64)
31-
export KAFKA_CLIENT_PASSWORD=$(kubectl get secret kafka-user-passwords -n $NAMESPACE -o jsonpath='{.data.client-passwords}' | base64 -d | cut -d ',' -f 1)
3231
export RASA_PRO_LICENSE=${RASA_PRO_LICENSE:-'Rasa License is not set! Set it manually with `export RASA_PRO_LICENSE=yourlicense`'}
3332
export OPENAI_API_KEY=${OPENAI_API_KEY:-'OpenAI API Key is not set! Set it manually with `export OPENAI_API_KEY=yourkey`'}
3433

3534
print_info "Secret values retrieved. If any of the values below are not set, be sure to set them manually and re-run this script."
3635
print_info "AUTH_TOKEN: $AUTH_TOKEN"
3736
print_info "JWT_SECRET: $JWT_SECRET"
38-
print_info "KAFKA_CLIENT_PASSWORD: $KAFKA_CLIENT_PASSWORD"
3937
print_info "RASA_PRO_LICENSE: $RASA_PRO_LICENSE"
4038
print_info "OPENAI_API_KEY: $OPENAI_API_KEY"
4139

@@ -45,5 +43,7 @@ create secret generic rasa-secrets \
4543
--from-literal=rasaProLicense="$(echo $RASA_PRO_LICENSE )" \
4644
--from-literal=authToken="$(echo $AUTH_TOKEN )" \
4745
--from-literal=jwtSecret="$(echo $JWT_SECRET)" \
48-
--from-literal=kafkaSslPassword="$(echo $KAFKA_CLIENT_PASSWORD)" \
49-
--from-literal=openaiApiKey="$(echo $OPENAI_API_KEY)"
46+
--from-literal=openaiApiKey="$(echo $OPENAI_API_KEY)"
47+
48+
kubectl --namespace $NAMESPACE create secret generic msk-ssl-ca --from-file=$SCRIPT_DIR/AmazonRootCA1.pem
49+
print_info "Kubernetes secret created successfully!"

0 commit comments

Comments
 (0)