Skip to content

Commit 79ed5c0

Browse files
committed
feat: Support adding the managed identity to a security group
Also uses the new terraform module tools for validation with some fixes
1 parent c3f964e commit 79ed5c0

File tree

5 files changed

+123
-29
lines changed

5 files changed

+123
-29
lines changed

README.md

+51-16
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@ All "System" mode pools must be able to reach all pods/subnets
2525

2626
## Requirements
2727

28-
No requirements.
28+
The following requirements are needed by this module:
29+
30+
- terraform (>=1.0.0)
31+
32+
- azuread (>=2.41.0)
33+
34+
- azurerm (>=3.63.0)
2935

3036
## Providers
3137

3238
The following providers are used by this module:
3339

34-
- azurerm
40+
- azuread (>=2.41.0)
41+
42+
- azurerm (>=3.63.0)
3543

3644
## Modules
3745

@@ -41,9 +49,11 @@ No modules.
4149

4250
The following resources are used by this module:
4351

52+
- [azuread_group_member.k8smember](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/group_member) (resource)
4453
- [azurerm_kubernetes_cluster.k8s](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster) (resource)
4554
- [azurerm_kubernetes_cluster_node_pool.additional](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster_node_pool) (resource)
4655
- [azurerm_public_ip.public-ip-outbound](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) (resource)
56+
- [azuread_group.ownersgroup](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) (data source)
4757

4858
## Required Inputs
4959

@@ -125,6 +135,21 @@ Type: `string`
125135

126136
The following input variables are optional (have default values):
127137

138+
### add\_identity\_to\_group
139+
140+
Description: The name of a group which is assigned to appropriate roles in the subscription to manage resources that are required by the AKS.
141+
Setting this to a non empty string will add the AKS managed identity to this group.
142+
143+
You need the following API permissions (with admin consent) on a service prinicpal to make this work:
144+
145+
* Directory.Read.All
146+
* Group.Read.All
147+
* Group.ReadWrite.All
148+
149+
Type: `string`
150+
151+
Default: `""`
152+
128153
### availability\_zones
129154

130155
Description: availability zones to spread the cluster nodes across, if omitted, only one avilability zone is used
@@ -258,53 +283,63 @@ The following outputs are exported:
258283

259284
### client\_certificate
260285

261-
Description: n/a
286+
Description: The Kubernetes client certificate for a kubectl config
262287

263288
### client\_certificate\_admin
264289

265-
Description: n/a
290+
Description: The Kubernetes client certificate for an admin access
266291

267292
### client\_key
268293

269-
Description: n/a
294+
Description: The Kubernetes client private key for a kubectl config
270295

271296
### client\_key\_admin
272297

273-
Description: n/a
298+
Description: The Kubernetes client private key for an admin access
274299

275300
### client\_token
276301

277-
Description: n/a
302+
Description: A client token for accessing the Cluster using kubectl
278303

279304
### client\_token\_admin
280305

281-
Description: n/a
306+
Description: A client token for accessing the Cluster using kubectl with an admin access
282307

283308
### cluster\_ca\_certificate
284309

285-
Description: n/a
310+
Description: The Kubernetes cluster ca certificate for a kubectl config
286311

287312
### cluster\_id
288313

289-
Description: n/a
314+
Description: The AKS cluster id
290315

291316
### cluster\_name
292317

293-
Description: n/a
318+
Description: The AKS cluster name
294319

295320
### fqdn
296321

297-
Description: n/a
322+
Description: The FQDN to the Kubernetes API server
298323

299324
### host
300325

301-
Description: n/a
326+
Description: The Kubernetes API host for a kubectl config
327+
328+
### managed\_identity\_object\_id
329+
330+
Description: The object ID of the service principal of the managed identity of the AKS
302331

303332
### node\_resource\_group
304333

305-
Description: n/a
334+
Description: The resource group the Kubernetes nodes were created in
306335

307336
### public\_outbound\_ips
308337

309-
Description: n/a
310-
<!-- END_TF_DOCS -->
338+
Description: The outbound public IPs
339+
<!-- END_TF_DOCS -->
340+
341+
## Development
342+
343+
Use [the terraform module tools](https://github.com/dodevops/terraform-module-tools) to check and generate the documentation by running
344+
345+
docker run -v "$PWD":/terraform ghcr.io/dodevops/terraform-module-tools:latest

managed_identity.tf

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Assign the k8s managed identity to a security group
2+
3+
data "azuread_group" "ownersgroup" {
4+
count = var.add_identity_to_group == "" ? 0 : 1
5+
display_name = var.add_identity_to_group
6+
}
7+
8+
resource "azuread_group_member" "k8smember" {
9+
count = var.add_identity_to_group == "" ? 0 : 1
10+
group_object_id = data.azuread_group.ownersgroup[0].object_id
11+
member_object_id = azurerm_kubernetes_cluster.k8s.identity[0].principal_id
12+
}

outputs.tf

+31-13
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,69 @@
11
output "host" {
2-
value = azurerm_kubernetes_cluster.k8s.kube_config[0].host
2+
value = azurerm_kubernetes_cluster.k8s.kube_config[0].host
3+
description = "The Kubernetes API host for a kubectl config"
34
}
45

56
output "client_certificate" {
6-
value = azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
7+
value = azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
8+
description = "The Kubernetes client certificate for a kubectl config"
79
}
810

911
output "client_key" {
10-
value = azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
12+
value = azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
13+
description = "The Kubernetes client private key for a kubectl config"
1114
}
1215

1316
output "cluster_ca_certificate" {
14-
value = azurerm_kubernetes_cluster.k8s.kube_config[0].cluster_ca_certificate
17+
value = azurerm_kubernetes_cluster.k8s.kube_config[0].cluster_ca_certificate
18+
description = "The Kubernetes cluster ca certificate for a kubectl config"
1519
}
1620

1721
output "fqdn" {
18-
value = azurerm_kubernetes_cluster.k8s.fqdn
22+
value = azurerm_kubernetes_cluster.k8s.fqdn
23+
description = "The FQDN to the Kubernetes API server"
1924
}
2025

2126
output "node_resource_group" {
22-
value = azurerm_kubernetes_cluster.k8s.node_resource_group
27+
value = azurerm_kubernetes_cluster.k8s.node_resource_group
28+
description = "The resource group the Kubernetes nodes were created in"
2329
}
2430

2531
output "cluster_name" {
26-
value = azurerm_kubernetes_cluster.k8s.name
32+
value = azurerm_kubernetes_cluster.k8s.name
33+
description = "The AKS cluster name"
2734
}
2835

2936
output "cluster_id" {
30-
value = azurerm_kubernetes_cluster.k8s.id
37+
value = azurerm_kubernetes_cluster.k8s.id
38+
description = "The AKS cluster id"
3139
}
3240

3341
output "client_certificate_admin" {
34-
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].client_certificate : azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
42+
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].client_certificate : azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
43+
description = "The Kubernetes client certificate for an admin access"
3544
}
3645

3746
output "client_key_admin" {
38-
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].client_key : azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
47+
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].client_key : azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
48+
description = "The Kubernetes client private key for an admin access"
3949
}
4050

4151
output "client_token" {
42-
value = azurerm_kubernetes_cluster.k8s.kube_config[0].password
52+
value = azurerm_kubernetes_cluster.k8s.kube_config[0].password
53+
description = "A client token for accessing the Cluster using kubectl"
4354
}
4455

4556
output "client_token_admin" {
46-
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].password : ""
57+
value = length(azurerm_kubernetes_cluster.k8s.kube_admin_config) > 0 ? azurerm_kubernetes_cluster.k8s.kube_admin_config[0].password : ""
58+
description = "A client token for accessing the Cluster using kubectl with an admin access"
4759
}
4860

4961
output "public_outbound_ips" {
50-
value = ["${azurerm_public_ip.public-ip-outbound.*.ip_address}"]
62+
value = [azurerm_public_ip.public-ip-outbound[*].ip_address]
63+
description = "The outbound public IPs"
64+
}
65+
66+
output "managed_identity_object_id" {
67+
value = azurerm_kubernetes_cluster.k8s.identity[0].principal_id
68+
description = "The object ID of the service principal of the managed identity of the AKS"
5169
}

terraform.tf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
terraform {
2+
required_version = ">=1.0.0"
3+
required_providers {
4+
azurerm = {
5+
source = "hashicorp/azurerm"
6+
version = ">=3.63.0"
7+
}
8+
azuread = {
9+
source = "hashicorp/azuread"
10+
version = ">=2.41.0"
11+
}
12+
}
13+
}

vars.tf

+16
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ variable "node_pools" {
9696
}
9797

9898
variable "load_balancer_sku" {
99+
type = string
99100
description = "The SKU for the used Load Balancer"
100101
default = "basic"
101102
}
@@ -165,3 +166,18 @@ variable "api_server_ip_ranges" {
165166
type = list(string)
166167
description = "The IP ranges to allow for incoming traffic to the server nodes. To disable the limitation, set an empty list as value."
167168
}
169+
170+
variable "add_identity_to_group" {
171+
type = string
172+
default = ""
173+
description = <<-EOF
174+
The name of a group which is assigned to appropriate roles in the subscription to manage resources that are required by the AKS.
175+
Setting this to a non empty string will add the AKS managed identity to this group.
176+
177+
You need the following API permissions (with admin consent) on a service prinicpal to make this work:
178+
179+
* Directory.Read.All
180+
* Group.Read.All
181+
* Group.ReadWrite.All
182+
EOF
183+
}

0 commit comments

Comments
 (0)