Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions src/terraform/aks-baseline/main.tf
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
data "azurerm_client_config" "current" {}

resource "random_string" "suffix" {
length = 8
upper = false
special = false
}

data "azurerm_resource_group" "main" {
name = "rg-pvt-aks-cluster-tf-test"
}

resource "azurerm_kubernetes_cluster" "main" {
name = "aks-${var.application_name}-${var.environment_name}-${random_string.suffix.result}"
resource_group_name = data.azurerm_resource_group.main.name
name = "aks-${var.application_name}-${var.environment_name}"
resource_group_name = var.resource_group_name
location = var.location
dns_prefix = "aks${var.application_name}${random_string.suffix.result}"
dns_prefix = "aks${var.application_name}"

default_node_pool {
name = "default"
Expand Down
2 changes: 1 addition & 1 deletion src/terraform/aks-baseline/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
output "resource_group_name" {
value = data.azurerm_resource_group.main.name
value = var.resource_group_name
}
3 changes: 3 additions & 0 deletions src/terraform/aks-baseline/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ variable "application_name" {
variable "environment_name" {
type = string
}
variable "resource_group_name" {
type = string
}
variable "location" {
type = string
}
Expand Down
65 changes: 65 additions & 0 deletions src/terraform/aks-managed-id/acr.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
locals {
acr_name = "cr${random_string.suffix.result}"
}

resource "azurerm_container_registry" "acr" {
name = local.acr_name
resource_group_name = var.resource_group_name
location = var.location
sku = "Premium"
public_network_access_enabled = false
tags = var.tags
}

########################################
# ACR Cache Rules
########################################

# CRITICAL for network isolated clusters - caches ALL MCR images for AKS bootstrap
# BYO ACR requires EXACT settings per MS docs:
# - name: aks-managed-mcr
# - source_repo: mcr.microsoft.com/*
# - target_repo: aks-managed-repository/*
# DO NOT modify this cache rule - it is required for cluster creation/functioning/upgrading
resource "azurerm_container_registry_cache_rule" "aks_managed" {
name = "aks-managed-mcr"
container_registry_id = azurerm_container_registry.acr.id
source_repo = "mcr.microsoft.com/*"
target_repo = "aks-managed-repository/*"
credential_set_id = null
}

########################################
# ACR Private Endpoint
########################################

resource "azurerm_private_endpoint" "acr" {
name = "pe-acr-${local.acr_name}"
location = var.location
resource_group_name = var.resource_group_name
subnet_id = var.acr_subnet_id
tags = var.tags

private_service_connection {
name = "acr-connection"
private_connection_resource_id = azurerm_container_registry.acr.id
is_manual_connection = false
subresource_names = ["registry"]
}

private_dns_zone_group {
name = "acr-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.acr.id]
}
}

########################################
# ACR Role Assignments
########################################

resource "azurerm_role_assignment" "kubelet_acr_pull" {
scope = azurerm_container_registry.acr.id
role_definition_name = "AcrPull"
principal_id = azurerm_user_assigned_identity.kubelet_identity.principal_id
skip_service_principal_aad_check = true
}
93 changes: 93 additions & 0 deletions src/terraform/aks-managed-id/aks.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
locals {
cluster_name = "aks-${var.application_name}-${var.environment_name}"
}

resource "azurerm_kubernetes_cluster" "main" {
name = local.cluster_name
location = var.location
resource_group_name = var.resource_group_name
dns_prefix = local.cluster_name
tags = var.tags

sku_tier = var.aks_sku_tier # SKU Tier - Standard/Premium includes Uptime SLA
kubernetes_version = var.kubernetes_version
automatic_upgrade_channel = "patch" # Automatic upgrade channels
node_os_upgrade_channel = "NodeImage"
azure_policy_enabled = true # Azure Policy for governance
private_cluster_enabled = true # Private cluster configuration
private_cluster_public_fqdn_enabled = false
private_dns_zone_id = "System"
local_account_disabled = true # Disable local accounts for enhanced security
oidc_issuer_enabled = true # Enable OIDC issuer and workload identity
workload_identity_enabled = true

default_node_pool {
name = "system"
node_count = var.default_node_count
vm_size = var.vm_size
vnet_subnet_id = var.aks_subnet_id

upgrade_settings {
max_surge = "10%"
}
}

identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.aks_identity.id]
}

kubelet_identity {
client_id = azurerm_user_assigned_identity.kubelet_identity.client_id
object_id = azurerm_user_assigned_identity.kubelet_identity.principal_id
user_assigned_identity_id = azurerm_user_assigned_identity.kubelet_identity.id
}

api_server_access_profile {
virtual_network_integration_enabled = true
subnet_id = azurerm_subnet.api_server_subnet.id
}

azure_active_directory_role_based_access_control {
azure_rbac_enabled = true
admin_group_object_ids = var.aks_admin_group_object_ids
}

network_profile {
network_plugin = "azure"
network_plugin_mode = "overlay"
outbound_type = "none"
pod_cidr = var.pod_cidr
service_cidr = var.service_cidr
dns_service_ip = var.dns_service_ip
}

oms_agent {
log_analytics_workspace_id = azurerm_log_analytics_workspace.aks.id
msi_auth_for_monitoring_enabled = true
}

bootstrap_profile {
artifact_source = "Cache"
container_registry_id = azurerm_container_registry.acr.id
}

maintenance_window_auto_upgrade {
frequency = "Weekly"
interval = 1
duration = 4
day_of_week = "Sunday"
start_time = "02:00"
utc_offset = "+00:00"
}

maintenance_window_node_os {
frequency = "Weekly"
interval = 1
duration = 4
day_of_week = "Sunday"
start_time = "06:00"
utc_offset = "+00:00"
}

}
42 changes: 42 additions & 0 deletions src/terraform/aks-managed-id/identity.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
resource "azurerm_user_assigned_identity" "aks_identity" {
name = "id-${var.application_name}-${var.environment_name}-cluster"
resource_group_name = var.resource_group_name
location = var.location
tags = var.tags
}

resource "azurerm_user_assigned_identity" "kubelet_identity" {
name = "id-${var.application_name}-${var.environment_name}-kubelet"
resource_group_name = var.resource_group_name
location = var.location
tags = var.tags
}


# AKS identity needs Network Contributor on VNet
resource "azurerm_role_assignment" "aks_network_contributor" {
scope = azurerm_virtual_network.vnet.id
role_definition_name = "Network Contributor"
principal_id = azurerm_user_assigned_identity.aks_identity.principal_id
}

# AKS identity needs Managed Identity Operator on kubelet identity
resource "azurerm_role_assignment" "aks_identity_operator" {
scope = azurerm_user_assigned_identity.kubelet_identity.id
role_definition_name = "Managed Identity Operator"
principal_id = azurerm_user_assigned_identity.aks_identity.principal_id
}

# Current user - Cluster Admin Role (control plane access)
resource "azurerm_role_assignment" "aks_cluster_admin_current_user" {
scope = azurerm_kubernetes_cluster.aks.id
role_definition_name = "Azure Kubernetes Service Cluster Admin Role"
principal_id = data.azurerm_client_config.current.object_id
}

# Current user - RBAC Cluster Admin (data plane access)
resource "azurerm_role_assignment" "aks_rbac_cluster_admin_current_user" {
scope = azurerm_kubernetes_cluster.aks.id
role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin"
principal_id = data.azurerm_client_config.current.object_id
}
8 changes: 8 additions & 0 deletions src/terraform/aks-managed-id/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
data "azurerm_client_config" "current" {}

resource "random_string" "suffix" {
length = 8
upper = false
special = false
}

29 changes: 29 additions & 0 deletions src/terraform/aks-managed-id/monitoring.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
########################################
# Log Analytics Workspace
########################################

resource "azurerm_log_analytics_workspace" "aks" {
name = "log-${var.application_name}-${var.environment_name}"
resource_group_name = var.resource_group_name
location = var.location
retention_in_days = var.log_analytics_retention_days
tags = var.tags
}

########################################
# Container Insights Solution
########################################

resource "azurerm_log_analytics_solution" "container_insights" {
solution_name = "ContainerInsights"
resource_group_name = var.resource_group_name
location = var.location
workspace_resource_id = azurerm_log_analytics_workspace.aks.id
workspace_name = azurerm_log_analytics_workspace.aks.name
tags = var.tags

plan {
product = "OMSGallery/ContainerInsights"
publisher = "Microsoft"
}
}
54 changes: 54 additions & 0 deletions src/terraform/aks-managed-id/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
variable "application_name" {
type = string
}
variable "environment_name" {
type = string
}
variable "resource_group_name" {
type = string
}
variable "location" {
type = string
}
variable "vm_size" {
type = string
}
variable "tags" {
type = map(string)
default = {}
}
variable "aks_sku_tier" {
type = string
default = "Standard"
}
variable "aks_admin_group_object_ids" {
type = list(string)
default = []
}
variable "kubernetes_version" {
type = string
default = "1.32.0"
}
variable "log_analytics_retention_days" {
type = number
default = 30
}
variable "default_node_count" {
type = number
default = 3
}
variable "aks_subnet_id" {
type = string
}
variable "acr_subnet_id" {
type = string
}
variable "pod_cidr" {
type = string
}
variable "service_cidr" {
type = string
}
variable "dns_service_ip" {
type = string
}
File renamed without changes.
5 changes: 5 additions & 0 deletions testing/prereq-name/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "random_string" "suffix" {
length = 8
upper = false
special = false
}
3 changes: 3 additions & 0 deletions testing/prereq-name/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "suffix" {
value = random_string.suffix.result
}
8 changes: 8 additions & 0 deletions testing/prereq-name/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
terraform {
required_providers {
random = {
source = "hashicorp/random"
version = "~> 3.7.2"
}
}
}
Loading