Skip to content

Commit 4cb3207

Browse files
authored
Longw/multi tenant templates with Terraform (#1505)
* add Bicep tempalte for multitenancy
1 parent b30bede commit 4cb3207

File tree

5 files changed

+240
-0
lines changed

5 files changed

+240
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Multi-tenancy AKS Monitoring Configuration
2+
3+
This Terraform configuration enables multi-tenancy monitoring for an existing AKS cluster by creating and configuring:
4+
- Data Collection Endpoint
5+
- Data Collection Rule
6+
- Data Collection Rule Association
7+
8+
## Prerequisites
9+
10+
1. An existing AKS cluster
11+
2. Azure Log Analytics workspace
12+
3. [Terraform](https://www.terraform.io/downloads.html) installed (version >= 1.0.0)
13+
4. Azure CLI installed and logged in
14+
15+
## Usage
16+
17+
1. Clone this repository and navigate to this directory:
18+
```bash
19+
cd scripts/onboarding/aks/multi-tenancy-terraform
20+
```
21+
22+
2. Create a `terraform.tfvars` file with your configuration values:
23+
```hcl
24+
aksResourceId = "/subscriptions/<SubscriptionId>/resourcegroups/<ResourceGroup>/providers/Microsoft.ContainerService/managedClusters/<ClusterName>"
25+
aksResourceLocation = "<aksClusterLocation>"
26+
workspaceResourceId = "/subscriptions/<SubscriptionId>/resourceGroups/<ResourceGroup>/providers/Microsoft.OperationalInsights/workspaces/<WorkspaceName>"
27+
workspaceRegion = "<workspaceRegion>"
28+
k8sNamespaces = ["namespace1", "namespace2"]
29+
resourceTagValues = {
30+
"environment" = "production"
31+
"owner" = "team-name"
32+
}
33+
transformKql = "" # Optional: Add your KQL transformation query
34+
```
35+
36+
3. Initialize Terraform:
37+
```bash
38+
terraform init
39+
```
40+
41+
4. Review the planned changes:
42+
```bash
43+
terraform plan
44+
```
45+
46+
5. Apply the configuration:
47+
```bash
48+
terraform apply
49+
```
50+
51+
## Important Notes
52+
53+
1. This configuration only manages the monitoring components for an existing AKS cluster. It does not create or modify the AKS cluster itself.
54+
55+
2. The following resources will be created:
56+
- Data Collection Endpoint for ingestion
57+
- Data Collection Rule for multi-tenancy logging
58+
- Data Collection Rule Association linking the DCR to your AKS cluster
59+
60+
3. Terraform state will only track the monitoring components, not the existing AKS cluster.
61+
62+
## Variables
63+
64+
| Variable | Description | Required |
65+
|----------|-------------|----------|
66+
| aksResourceId | Full resource ID of the existing AKS cluster | Yes |
67+
| aksResourceLocation | Location of the AKS resource (e.g., "eastus") | Yes |
68+
| workspaceResourceId | Full resource ID of the Log Analytics workspace | Yes |
69+
| workspaceRegion | Region of the Log Analytics workspace | Yes |
70+
| k8sNamespaces | Array of Kubernetes namespaces to monitor | Yes |
71+
| resourceTagValues | Map of tags to apply to created resources | No |
72+
| transformKql | KQL transformation query for log ingestion | No |
73+
74+
## Example terraform.tfvars
75+
76+
```hcl
77+
aksResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/my-rg/providers/Microsoft.ContainerService/managedClusters/my-aks"
78+
aksResourceLocation = "eastus"
79+
workspaceResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.OperationalInsights/workspaces/my-workspace"
80+
workspaceRegion = "eastus"
81+
k8sNamespaces = [
82+
"default",
83+
"kube-system"
84+
]
85+
resourceTagValues = {
86+
"environment" = "production"
87+
"managed-by" = "terraform"
88+
}
89+
transformKql = ""
90+
```
91+
92+
## Cleanup
93+
94+
To remove the monitoring configuration:
95+
```bash
96+
terraform destroy
97+
```
98+
99+
This will remove all monitoring components but will not affect the AKS cluster itself.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Data source for existing AKS cluster
2+
data "azurerm_kubernetes_cluster" "existing" {
3+
name = local.cluster_name
4+
resource_group_name = local.resource_group_name
5+
}
6+
7+
locals {
8+
cluster_id_parts = split("/", var.aksResourceId)
9+
cluster_name = local.cluster_id_parts[8]
10+
resource_group_name = local.cluster_id_parts[4]
11+
subscription_id = local.cluster_id_parts[2]
12+
workspace_name = split("/", var.workspaceResourceId)[8]
13+
workspace_location = replace(var.workspaceRegion, " ", "")
14+
cluster_location = replace(var.aksResourceLocation, " ", "")
15+
16+
dce_name_full = "MSCI-multi-tenancy-${local.workspace_location}-${sha1(var.workspaceResourceId)}"
17+
dce_name = length(local.dce_name_full) > 43 ? substr(local.dce_name_full, 0, 43) : local.dce_name_full
18+
ingestion_dce_name = endswith(local.dce_name, "-") ? substr(local.dce_name, 0, length(local.dce_name) - 1) : local.dce_name
19+
20+
dcr_name_full = "MSCI-multi-tenancy-${local.workspace_location}-${sha1(var.workspaceResourceId)}"
21+
dcr_name = length(local.dcr_name_full) > 64 ? substr(local.dcr_name_full, 0, 64) : local.dcr_name_full
22+
}
23+
24+
# Data Collection Endpoint for ingestion
25+
resource "azurerm_monitor_data_collection_endpoint" "ingestion_dce" {
26+
name = local.ingestion_dce_name
27+
resource_group_name = local.resource_group_name
28+
location = var.workspaceRegion
29+
kind = "Linux"
30+
tags = var.resourceTagValues
31+
}
32+
33+
# Data Collection Rule
34+
resource "azurerm_monitor_data_collection_rule" "dcr" {
35+
name = local.dcr_name
36+
resource_group_name = local.resource_group_name
37+
location = var.workspaceRegion
38+
tags = var.resourceTagValues
39+
kind = "Linux"
40+
41+
destinations {
42+
log_analytics {
43+
workspace_resource_id = var.workspaceResourceId
44+
name = "ciworkspace"
45+
}
46+
}
47+
48+
data_flow {
49+
streams = ["Microsoft-ContainerLogV2-HighScale"]
50+
destinations = ["ciworkspace"]
51+
transform_kql = var.transformKql != "" ? var.transformKql : null
52+
}
53+
54+
data_sources {
55+
extension {
56+
name = "ContainerLogV2Extension"
57+
extension_name = "ContainerLogV2Extension"
58+
streams = ["Microsoft-ContainerLogV2-HighScale"]
59+
extension_json = jsonencode({
60+
"dataCollectionSettings": {
61+
"namespaces": var.k8sNamespaces
62+
}
63+
})
64+
}
65+
}
66+
67+
data_collection_endpoint_id = azurerm_monitor_data_collection_endpoint.ingestion_dce.id
68+
}
69+
70+
# Data Collection Rule Association
71+
resource "azurerm_monitor_data_collection_rule_association" "dcra" {
72+
name = "ContainerLogV2Extension-${sha1(var.workspaceResourceId)}"
73+
target_resource_id = var.aksResourceId
74+
data_collection_rule_id = azurerm_monitor_data_collection_rule.dcr.id
75+
description = "Association of Logs Multi-tenancy collection rule. Deleting this association will break the Multi-tenancy logs data collection for this AKS Cluster."
76+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
terraform {
2+
required_providers {
3+
azurerm = {
4+
source = "hashicorp/azurerm"
5+
version = "~> 3.47"
6+
}
7+
}
8+
required_version = ">= 1.0.0"
9+
}
10+
11+
provider "azurerm" {
12+
features {}
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
aksResourceId = "/subscriptions/<SubscriptionId>/resourcegroups/<ResourceGroup>/providers/Microsoft.ContainerService/managedClusters/<ResourceName>"
2+
aksResourceLocation = "<aksClusterLocation>"
3+
workspaceResourceId = "/subscriptions/<SubscriptionId>/resourceGroups/<ResourceGroup>/providers/Microsoft.OperationalInsights/workspaces/<workspaceName>"
4+
workspaceRegion = "<workspaceRegion>"
5+
k8sNamespaces = [
6+
"<namespace1>",
7+
"<namespace2>",
8+
"<namespaceN>"
9+
]
10+
resourceTagValues = {
11+
"<existingOrnew-tag-name1>": "<existingOrnew-tag-value1>",
12+
"<existingOrnew-tag-name2>": "<existingOrnew-tag-value2>",
13+
"<existingOrnew-tag-nameN>": "<existingOrnew-tag-valueN>"
14+
}
15+
transformKql = "<KQL filter for ingestion transformation>"
16+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
variable "aksResourceId" {
2+
type = string
3+
description = "AKS Cluster Resource ID"
4+
}
5+
6+
variable "aksResourceLocation" {
7+
type = string
8+
description = "Location of the AKS Resource"
9+
}
10+
11+
variable "workspaceRegion" {
12+
type = string
13+
description = "Workspace Region for data collection rule"
14+
}
15+
16+
variable "workspaceResourceId" {
17+
type = string
18+
description = "Full Resource ID of the log analytics workspace that will be used for data destination"
19+
}
20+
21+
variable "resourceTagValues" {
22+
type = map(string)
23+
description = "Existing or new tags to use on AKS, ContainerInsights and DataCollectionRule Resources"
24+
default = {}
25+
}
26+
27+
variable "k8sNamespaces" {
28+
type = list(string)
29+
description = "An array of Kubernetes namespaces for Multi-tenancy logs filtering"
30+
}
31+
32+
variable "transformKql" {
33+
type = string
34+
description = "KQL filter for ingestion transformation"
35+
default = ""
36+
}

0 commit comments

Comments
 (0)