Files
azure-ki-infrastruktur/beispiel-terraform/beispiel-k8s-cluster/main.tf
T
cbazzaandClaude Sonnet 4.5 dfff276de6 Restructure project: Move AKS cluster to beispiel-k8s-cluster directory
Major improvements:
- Import existing Azure AKS cluster with aztfexport
- Optimize VM size from Standard_D4d_v4 to Standard_D2as_v6 (50% cost reduction)
- Configure availability zones to [1, 2]
- Add comprehensive monitoring setup:
  * New Log Analytics Workspace
  * OMS Agent integration
  * Data Collection Rule for Container Insights
  * Email alerts for CPU and Memory
- Refactor configuration:
  * Extract all values to variables.tf
  * Rename resources with meaningful names
  * Add detailed outputs.tf
- Add project documentation:
  * Comprehensive README.md
  * cluster-status-commands.md with useful Azure CLI commands
  * terraform.tfvars.example template
  * .gitignore for sensitive files

Infrastructure changes:
- Resource Group: trusted_ai_demo_rg (Germany West Central)
- AKS Cluster: trai_k8s_cluster (Kubernetes 1.33)
- Node Pool: 2-3 nodes with auto-scaling
- Network: VNet 10.0.0.0/16, Subnet 10.0.0.0/24
- Monitoring: Full Container Insights with alerts

Cost optimization: ~€75/month (down from ~€140/month)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 13:36:51 +01:00

196 lines
5.3 KiB
Terraform

resource "azurerm_resource_group" "main" {
location = var.location
name = var.resource_group_name
}
resource "azurerm_virtual_network" "main" {
address_space = var.vnet_address_space
location = var.location
name = var.vnet_name
resource_group_name = var.resource_group_name
depends_on = [
azurerm_resource_group.main
]
}
resource "azurerm_subnet" "default" {
address_prefixes = var.subnet_address_prefixes
name = var.subnet_name
resource_group_name = var.resource_group_name
virtual_network_name = var.vnet_name
depends_on = [
azurerm_virtual_network.main
]
}
resource "azurerm_log_analytics_workspace" "main" {
name = "aksloganalytics${replace(var.aks_cluster_name, "_", "")}"
location = var.location
resource_group_name = var.resource_group_name
sku = "PerGB2018"
retention_in_days = 30
depends_on = [
azurerm_resource_group.main
]
}
resource "azurerm_kubernetes_cluster" "main" {
automatic_upgrade_channel = "patch"
dns_prefix = var.aks_dns_prefix
image_cleaner_enabled = true
image_cleaner_interval_hours = 168
location = var.location
name = var.aks_cluster_name
oidc_issuer_enabled = true
resource_group_name = var.resource_group_name
workload_identity_enabled = true
default_node_pool {
auto_scaling_enabled = true
max_count = var.aks_node_pool_max_count
min_count = var.aks_node_pool_min_count
name = "agentpool"
vm_size = var.aks_node_vm_size
zones = var.aks_node_zones
temporary_name_for_rotation = "temppool"
upgrade_settings {
max_surge = "10%"
}
}
identity {
type = "SystemAssigned"
}
maintenance_window_auto_upgrade {
day_of_week = "Sunday"
duration = 8
frequency = "Weekly"
interval = 1
start_time = "00:00"
utc_offset = "+00:00"
}
maintenance_window_node_os {
day_of_week = "Sunday"
duration = 8
frequency = "Weekly"
interval = 1
start_time = "00:00"
utc_offset = "+00:00"
}
oms_agent {
log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id
msi_auth_for_monitoring_enabled = true
}
depends_on = [
azurerm_resource_group.main,
azurerm_log_analytics_workspace.main
]
}
resource "azurerm_monitor_data_collection_rule" "aks_monitoring" {
kind = "Linux"
location = var.location
name = "MSCI-${var.location}-${var.aks_cluster_name}"
resource_group_name = var.resource_group_name
data_flow {
destinations = ["ciworkspace"]
streams = ["Microsoft-ContainerLog", "Microsoft-ContainerLogV2", "Microsoft-KubeEvents", "Microsoft-KubePodInventory"]
}
data_sources {
extension {
extension_json = jsonencode({
dataCollectionSettings = {
enableContainerLogV2 = true
interval = "1m"
namespaceFilteringMode = "Off"
}
})
extension_name = "ContainerInsights"
name = "ContainerInsightsExtension"
streams = ["Microsoft-ContainerLog", "Microsoft-ContainerLogV2", "Microsoft-KubeEvents", "Microsoft-KubePodInventory"]
}
}
destinations {
log_analytics {
name = "ciworkspace"
workspace_resource_id = azurerm_log_analytics_workspace.main.id
}
}
depends_on = [
azurerm_resource_group.main,
azurerm_log_analytics_workspace.main
]
}
resource "azurerm_monitor_action_group" "alerts" {
name = "RecommendedAlertRules-AG-c92012"
resource_group_name = var.resource_group_name
short_name = "alertc92012"
email_receiver {
email_address = var.alert_email_address
name = "Email_-EmailAction-"
use_common_alert_schema = true
}
depends_on = [
azurerm_resource_group.main
]
}
resource "azurerm_monitor_metric_alert" "cpu_alert" {
auto_mitigate = false
frequency = "PT5M"
name = "CPU Usage Percentage - ${var.aks_cluster_name}"
resource_group_name = var.resource_group_name
scopes = [azurerm_kubernetes_cluster.main.id]
action {
action_group_id = azurerm_monitor_action_group.alerts.id
}
criteria {
aggregation = "Average"
metric_name = "node_cpu_usage_percentage"
metric_namespace = "Microsoft.ContainerService/managedClusters"
operator = "GreaterThan"
threshold = 95
}
depends_on = [
azurerm_resource_group.main
]
}
resource "azurerm_monitor_metric_alert" "memory_alert" {
auto_mitigate = false
frequency = "PT5M"
name = "Memory Working Set Percentage - ${var.aks_cluster_name}"
resource_group_name = var.resource_group_name
scopes = [azurerm_kubernetes_cluster.main.id]
action {
action_group_id = azurerm_monitor_action_group.alerts.id
}
criteria {
aggregation = "Average"
metric_name = "node_memory_working_set_percentage"
metric_namespace = "Microsoft.ContainerService/managedClusters"
operator = "GreaterThan"
threshold = 100
}
depends_on = [
azurerm_resource_group.main
]
}