Skip to content

Commit

Permalink
[Feature] Added automated provisioning of CosmosDB and App Insights f…
Browse files Browse the repository at this point in the history
…or OPEA applications - Infosys (#657)

* Updated terraform files with CosmosDB and App Insights

Signed-off-by: kkrishTa <[email protected]>

* Updating code with correct names

Signed-off-by: kkrishTa <[email protected]>

* correcting terraform

Signed-off-by: kkrishTa <[email protected]>

* Added opt in variable for cosmosdb provisioning

Signed-off-by: kkrishTa <[email protected]>

* Defaulting Cosmos DB provisioning to false and added variable in tfvars

Signed-off-by: kkrishTa <[email protected]>

---------

Signed-off-by: kkrishTa <[email protected]>
  • Loading branch information
kkrishTa authored Jan 22, 2025
1 parent 7929a14 commit d29bd2d
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cloud-service-provider/azure/aks/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ terraform init

By default, 1-node cluster is created which is suitable for running the OPEA application. See `variables.tf` and `opea-<application-name>.tfvars` if you want to tune the cluster properties, e.g., number of nodes, instance types or disk size.

## Cosmos DB

By default Cosmos DB will not be provisioned. If you want Cosmos DB as part of your resource provisioning, update `is_cosmosdb_required` property present in `opea-<application-name>.tfvars` to `true`.

## Persistent Volume Claim

OPEA needs a volume where to store the model. For that we need to create Kubernetes Persistent Volume Claim (PVC). OPEA requires `ReadWriteMany` option since multiple pods needs access to the storage and they can be on different nodes. On AKS, only Azure File Service supports `ReadWriteMany`. Thus, each OPEA application below uses the file `aks-azfs-csi-pvc.yaml` to create PVC in its namespace.
Expand Down
133 changes: 133 additions & 0 deletions cloud-service-provider/azure/aks/terraform/azure_main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,79 @@ module "vnet" {
depends_on = [azurerm_resource_group.main]
}

# Cosmos DB
resource "azurerm_cosmosdb_account" "main" {
count = var.is_cosmosdb_required ? 1 : 0
name = "${var.cluster_name}-cosmosdb"
location = var.cosmosdb_account_location
resource_group_name = azurerm_resource_group.main.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
geo_location {
location = var.cosmosdb_account_location
failover_priority = 0
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
capabilities {
name = "EnableNoSQLFullTextSearch"
}
capabilities {
name = "EnableNoSQLVectorSearch"
}
depends_on = [
azurerm_resource_group.main
]
}

resource "azurerm_cosmosdb_sql_database" "main" {
count = var.is_cosmosdb_required ? 1 : 0
name = "${var.cluster_name}-sqldb"
resource_group_name = azurerm_resource_group.main.name
account_name = azurerm_cosmosdb_account.main[count.index].name
throughput = var.throughput
depends_on = [
azurerm_cosmosdb_account.main
]
}

resource "azurerm_cosmosdb_sql_container" "main" {
count = var.is_cosmosdb_required ? 1 : 0
name = "${var.cluster_name}-sql-container"
resource_group_name = azurerm_resource_group.main.name
account_name = azurerm_cosmosdb_account.main[count.index].name
database_name = azurerm_cosmosdb_sql_database.main[count.index].name
partition_key_paths = ["/definition/id"]
partition_key_version = 1
throughput = var.throughput

indexing_policy {
indexing_mode = "consistent"

included_path {
path = "/*"
}

included_path {
path = "/included/?"
}

excluded_path {
path = "/excluded/?"
}
}

unique_key {
paths = ["/definition/idlong", "/definition/idshort"]
}
depends_on = [
azurerm_cosmosdb_sql_database.main
]
}

# AKS Cluster
resource "azurerm_kubernetes_cluster" "main" {
name = var.cluster_name
Expand Down Expand Up @@ -109,5 +182,65 @@ resource "null_resource" "kubectl" {
depends_on = [azurerm_kubernetes_cluster.main]
}

# Application Insights
resource "azurerm_log_analytics_workspace" "main" {
name = "workspace-${var.cluster_name}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
retention_in_days = 30
}

resource "azurerm_application_insights" "t_appinsights" {
name = "${var.cluster_name}-appinsights"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
workspace_id = azurerm_log_analytics_workspace.main.id
application_type = "web"
}

# Data source for Azure subscription information
data "azurerm_client_config" "current" {}

# Cosmos db Primary connection string into key vault
resource "azurerm_key_vault_secret" "cosdb_primary" {
count = var.is_cosmosdb_required ? 1 : 0
name = "AzCosmosDBConnectionStringPrimary"
value = tostring("AccountEndpoint=${azurerm_cosmosdb_account.main[count.index].endpoint};AccountKey=${azurerm_cosmosdb_account.main[count.index].primary_key};")
key_vault_id = azurerm_key_vault.main.id
}

# Cosmos db Secondary connection string into key vault
resource "azurerm_key_vault_secret" "cosdb_secondary" {
count = var.is_cosmosdb_required ? 1 : 0
name = "AzCosmosDBConnectionStringSecondary"
value = tostring("AccountEndpoint=${azurerm_cosmosdb_account.main[count.index].endpoint};AccountKey=${azurerm_cosmosdb_account.main[count.index].secondary_key};")
key_vault_id = azurerm_key_vault.main.id
}

# Kubernetes cluster end point into key vault
resource "azurerm_key_vault_secret" "kube_cluster_endpoint" {
name = "KubeClusterEndPoint"
value = tostring("${azurerm_kubernetes_cluster.main.kube_config.0.host}")
key_vault_id = azurerm_key_vault.main.id
}

# App Insights Instrumentation Key
resource "azurerm_key_vault_secret" "app_insights_instrumentation_key" {
name = "AppInsightsInstrumentationKey"
value = tostring("${azurerm_application_insights.t_appinsights.instrumentation_key}")
key_vault_id = azurerm_key_vault.main.id
}

# App Insights app id
resource "azurerm_key_vault_secret" "app_insights_app_id" {
name = "AppInsightsAppId"
value = tostring("${azurerm_application_insights.t_appinsights.app_id}")
key_vault_id = azurerm_key_vault.main.id
}

# App Insights Connection String
resource "azurerm_key_vault_secret" "app_insights_connection_string" {
name = "AppInsightsConnectionString"
value = tostring("${azurerm_application_insights.t_appinsights.connection_string}")
key_vault_id = azurerm_key_vault.main.id
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_pool_type = "Spot" # cheaper
os_disk_size_gb = 50
location = "eastus"
kubernetes_version = "1.30"
is_cosmosdb_required = false
18 changes: 17 additions & 1 deletion cloud-service-provider/azure/aks/terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
output "cluster_endpoint" {
description = "Endpoint for AKS control plane"
#sensitive = false
sensitive = true
value = azurerm_kubernetes_cluster.main.kube_config.0.host
}
Expand All @@ -19,3 +18,20 @@ output "cluster_name" {
description = "Kubernetes Cluster Name"
value = azurerm_kubernetes_cluster.main.name
}

output "instrumentation_key" {
description = "App Insights Instrumentation Key"
value = azurerm_application_insights.t_appinsights.instrumentation_key
sensitive = true
}

output "app_id" {
description = "App Insights App Id"
value = azurerm_application_insights.t_appinsights.app_id
}

output "app_insights_connection_string" {
description = "App Insights Connection String"
value = azurerm_application_insights.t_appinsights.connection_string
sensitive = true
}
26 changes: 26 additions & 0 deletions cloud-service-provider/azure/aks/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ variable "location" {
default = "eastus"
}

variable "cosmosdb_account_location" {
description = "Cosmos DB account Location"
type = string
default = "westus"
}

variable "cluster_name" {
description = "AKS cluster name"
type = string
Expand Down Expand Up @@ -81,3 +87,23 @@ variable "instance_types" {
type = list(string)
default = ["Standard_D32d_v5"]
}

variable "throughput" {
type = number
default = 400
description = "Cosmos db database throughput"
validation {
condition = var.throughput >= 400 && var.throughput <= 1000000
error_message = "Cosmos db manual throughput should be equal to or greater than 400 and less than or equal to 1000000."
}
validation {
condition = var.throughput % 100 == 0
error_message = "Cosmos db throughput should be in increments of 100."
}
}

variable "is_cosmosdb_required" {
type = bool
description = "Is Cosmos DB required for your deployment? [true/false]"
default = false
}

0 comments on commit d29bd2d

Please sign in to comment.