Skip to content

Feature/aks #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
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
47 changes: 47 additions & 0 deletions modules/azure/aks/backplane/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# AKS CLuster

This documentation is intended as a reference documentation for cloud foundation or platform engineers using this module.

## Permissions

This is a very simple building block, which means we let the SPN have access to AKS Clusters
across all subscriptions underneath a management group (typically the top-level management group for landing zones).

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 4.36.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_role_assignment.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/role_definition) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | name of the building block, used for naming resources | `string` | `"aks"` | no |
| <a name="input_principal_ids"></a> [principal\_ids](#input\_principal\_ids) | set of principal ids that will be granted permissions to deploy the building block | `set(string)` | n/a | yes |
| <a name="input_scope"></a> [scope](#input\_scope) | Scope where the building block should be deployable, typically the parent of all Landing Zones. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_documentation_md"></a> [documentation\_md](#output\_documentation\_md) | Markdown documentation with information about the AKS Building Block building block backplane |
| <a name="output_role_assignment_ids"></a> [role\_assignment\_ids](#output\_role\_assignment\_ids) | The IDs of the role assignments for the service principals. |
| <a name="output_role_assignment_principal_ids"></a> [role\_assignment\_principal\_ids](#output\_role\_assignment\_principal\_ids) | The principal IDs of the service principals that have been assigned the role. |
| <a name="output_role_definition_id"></a> [role\_definition\_id](#output\_role\_definition\_id) | The ID of the role definition that enables deployment of the building block to subscriptions. |
| <a name="output_role_definition_name"></a> [role\_definition\_name](#output\_role\_definition\_name) | The name of the role definition that enables deployment of the building block to subscriptions. |
| <a name="output_scope"></a> [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
<!-- END_TF_DOCS -->
18 changes: 18 additions & 0 deletions modules/azure/aks/backplane/documentation.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
output "documentation_md" {
value = <<EOF
# AKS Building Block

The Azure AKS Building Block configures a AKS (Kubernetes Service) cluster in the Azure cloud, which can be used to deploy and run containerized applications.

## Automation

We automate the deployment of a AKS Building Block using the common [Azure Building Blocks Automation Infrastructure](../automation.md).
In order to deploy this building block, this infrastructure receives the following roles.

| Role Name | Description | Permissions |
|-----------|-------------|-------------|
| `${azurerm_role_definition.buildingblock_deploy.name}` | ${azurerm_role_definition.buildingblock_deploy.description} | ${join("<br>", formatlist("- `%s`", azurerm_role_definition.buildingblock_deploy.permissions[0].actions))} |

EOF
description = "Markdown documentation with information about the AKS Building Block building block backplane"
}
28 changes: 28 additions & 0 deletions modules/azure/aks/backplane/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
resource "azurerm_role_definition" "buildingblock_deploy" {
name = "${var.name}-deploy"
scope = var.scope
description = "Enables deployment of the ${var.name} building block to subscriptions"

permissions {
actions = [
"Microsoft.ContainerService/managedClusters/*",
"Microsoft.ContainerService/managedClusters/accessProfiles/*",
"Microsoft.Network/virtualNetworks/*",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Network/networkSecurityGroups/*",
"Microsoft.Resources/deployments/*",
"Microsoft.Resources/subscriptions/resourceGroups/*",
"Microsoft.OperationalInsights/*",
"Microsoft.Insights/diagnosticSettings/*",
"Microsoft.Authorization/roleAssignments/read"
]
}
}

resource "azurerm_role_assignment" "buildingblock_deploy" {
for_each = var.principal_ids

role_definition_id = azurerm_role_definition.buildingblock_deploy.role_definition_resource_id
principal_id = each.value
scope = var.scope
}
24 changes: 24 additions & 0 deletions modules/azure/aks/backplane/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "role_definition_id" {
value = azurerm_role_definition.buildingblock_deploy.id
description = "The ID of the role definition that enables deployment of the building block to subscriptions."
}

output "role_definition_name" {
value = azurerm_role_definition.buildingblock_deploy.name
description = "The name of the role definition that enables deployment of the building block to subscriptions."
}

output "role_assignment_ids" {
value = [for id in azurerm_role_assignment.buildingblock_deploy : id.id]
description = "The IDs of the role assignments for the service principals."
}

output "role_assignment_principal_ids" {
value = [for id in azurerm_role_assignment.buildingblock_deploy : id.principal_id]
description = "The principal IDs of the service principals that have been assigned the role."
}

output "scope" {
value = var.scope
description = "The scope where the role definition and role assignments are applied."
}
3 changes: 3 additions & 0 deletions modules/azure/aks/backplane/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
provider "azurerm" {
features {}
}
27 changes: 27 additions & 0 deletions modules/azure/aks/backplane/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
variable "name" {
type = string
nullable = false
default = "aks"
description = "name of the building block, used for naming resources"
validation {
condition = can(regex("^[-a-z0-9]+$", var.name))
error_message = "Only alphanumeric lowercase characters and dashes are allowed"
}
}

variable "principal_ids" {
type = string
description = "Object ID of the SCP (Terraform SPN or federated identity)"
}

variable "scope" {
type = string
nullable = false
description = "Scope where the building block should be deployable, typically the parent of all Landing Zones."
}

variable "principal_ids" {
type = set(string)
nullable = false
description = "set of principal ids that will be granted permissions to deploy the building block"
}
10 changes: 10 additions & 0 deletions modules/azure/aks/backplane/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.5.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "4.36.0" # oder aktuelle getestete Version
}
}
}
74 changes: 74 additions & 0 deletions modules/azure/aks/buildingblock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
name: AKS Cluster
supportedPlatforms:
- azure
description: |
Provision a production-grade Azure Kubernetes Service (AKS) cluster with Azure AD, OIDC, Workload Identity, Log Analytics and custom VNet using Terraform.
---

# AKS Building Block

This Terraform module provisions a production-ready [Azure Kubernetes Service (AKS)](https://learn.microsoft.com/en-us/azure/aks/) cluster including:

- Azure AD-based authentication
- Workload Identity & OIDC issuer enabled
- Custom Virtual Network & Subnet
- Log Analytics integration (Monitoring)
- Auto-scaling node pool
- System-assigned managed identity

## 🚀 Features

- ✅ Production-grade configuration
- 🔐 Integrated Azure AD admin group
- ☁️ Log Analytics Workspace (LAW) with `oms_agent`
- 🧠 OIDC issuer & Workload Identity support
- 🌐 Custom virtual network and subnet
- 📈 Auto-scaling system node pool

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.0 |
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | 3.4.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 4.36.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_kubernetes_cluster.aks](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/kubernetes_cluster) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/log_analytics_workspace) | resource |
| [azurerm_resource_group.aks](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/resource_group) | resource |
| [azurerm_subnet.aks_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/subnet) | resource |
| [azurerm_virtual_network.vnet](https://registry.terraform.io/providers/hashicorp/azurerm/4.36.0/docs/resources/virtual_network) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_agent_count"></a> [agent\_count](#input\_agent\_count) | n/a | `number` | `3` | no |
| <a name="input_aks_admin_group_object_id"></a> [aks\_admin\_group\_object\_id](#input\_aks\_admin\_group\_object\_id) | Object ID of the Azure AD group used for AKS admin access | `string` | n/a | yes |
| <a name="input_aks_cluster_name"></a> [aks\_cluster\_name](#input\_aks\_cluster\_name) | n/a | `string` | `"prod-aks"` | no |
| <a name="input_dns_prefix"></a> [dns\_prefix](#input\_dns\_prefix) | n/a | `string` | `"prodaks"` | no |
| <a name="input_kubernetes_version"></a> [kubernetes\_version](#input\_kubernetes\_version) | n/a | `string` | `"1.29.2"` | no |
| <a name="input_location"></a> [location](#input\_location) | n/a | `string` | `"Germany West Central"` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | n/a | `string` | `"aks-prod-rg"` | no |
| <a name="input_vm_size"></a> [vm\_size](#input\_vm\_size) | n/a | `string` | `"Standard_DS3_v2"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_aks_identity_client_id"></a> [aks\_identity\_client\_id](#output\_aks\_identity\_client\_id) | Client ID of the AKS system-assigned managed identity |
| <a name="output_kube_config"></a> [kube\_config](#output\_kube\_config) | Kubeconfig raw output |
| <a name="output_law_id"></a> [law\_id](#output\_law\_id) | Log Analytics Workspace ID |
| <a name="output_oidc_issuer_url"></a> [oidc\_issuer\_url](#output\_oidc\_issuer\_url) | OIDC issuer URL for federated identity and workload identity setup |
| <a name="output_subnet_id"></a> [subnet\_id](#output\_subnet\_id) | Subnet ID used by AKS |
<!-- END_TF_DOCS -->
Binary file added modules/azure/aks/buildingblock/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions modules/azure/aks/buildingblock/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Resource Group
resource "azurerm_resource_group" "aks" {
name = var.resource_group_name
location = var.location
}

# VNet
resource "azurerm_virtual_network" "vnet" {
name = "aks-vnet"
address_space = ["10.0.0.0/8"]
location = var.location
resource_group_name = azurerm_resource_group.aks.name
}

# Subnet for AKS
resource "azurerm_subnet" "aks_subnet" {
name = "aks-subnet"
resource_group_name = azurerm_resource_group.aks.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.240.0.0/16"]
}

# Log Analytics Workspace
resource "azurerm_log_analytics_workspace" "law" {
name = "${var.aks_cluster_name}-law"
location = var.location
resource_group_name = azurerm_resource_group.aks.name
sku = "PerGB2018"
retention_in_days = 30
}

# AKS Cluster with AAD, Monitoring, OIDC, Workload Identity
resource "azurerm_kubernetes_cluster" "aks" {
name = var.aks_cluster_name
location = var.location
resource_group_name = azurerm_resource_group.aks.name
dns_prefix = var.dns_prefix

kubernetes_version = var.kubernetes_version

default_node_pool {
name = "system"
node_count = var.agent_count
vm_size = var.vm_size
vnet_subnet_id = azurerm_subnet.aks_subnet.id
os_disk_size_gb = 100
enable_auto_scaling = true
min_count = 2
max_count = 5
type = "VirtualMachineScaleSets"
mode = "System"
}

identity {
type = "SystemAssigned"
}

role_based_access_control_enabled = true

azure_active_directory_role_based_access_control {
managed = true
admin_group_object_ids = [var.aks_admin_group_object_id]
}

network_profile {
network_plugin = "azure"
network_policy = "azure"
service_cidr = "10.0.0.0/16"
dns_service_ip = "10.0.0.10"
docker_bridge_cidr = "172.17.0.1/16"
load_balancer_sku = "standard"
outbound_type = "loadBalancer"
}

addon_profile {
oms_agent {
enabled = true
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
}
}

oidc_issuer_enabled = true
workload_identity_enabled = true

tags = {
Environment = "production"
}

lifecycle {
ignore_changes = [
default_node_pool[0].node_count
]
}
}
25 changes: 25 additions & 0 deletions modules/azure/aks/buildingblock/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
output "kube_config" {
description = "Kubeconfig raw output"
value = azurerm_kubernetes_cluster.aks.kube_config_raw
sensitive = true
}

output "oidc_issuer_url" {
description = "OIDC issuer URL for federated identity and workload identity setup"
value = azurerm_kubernetes_cluster.aks.oidc_issuer_url
}

output "aks_identity_client_id" {
description = "Client ID of the AKS system-assigned managed identity"
value = azurerm_kubernetes_cluster.aks.identity[0].principal_id
}

output "law_id" {
description = "Log Analytics Workspace ID"
value = azurerm_log_analytics_workspace.law.id
}

output "subnet_id" {
description = "Subnet ID used by AKS"
value = azurerm_subnet.aks_subnet.id
}
6 changes: 6 additions & 0 deletions modules/azure/aks/buildingblock/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
provider "azurerm" {
features {}
}

provider "azuread" {}

Loading
Loading