Skip to content

Commit

Permalink
Merge pull request #22 from avinor/msi
Browse files Browse the repository at this point in the history
Use Managed Azure Active Directory
  • Loading branch information
yngveh authored Jun 5, 2023
2 parents ea4bf0a + cbdbb67 commit 0352d5b
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 138 deletions.
48 changes: 34 additions & 14 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 8 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
# Kubernetes

Terraform module to deploy a Kubernetes cluster on Azure by using the managed Kubernetes solution AKS. For security
reasons it will only deploy a rbac enabled clusters and requires an Azure AD application for authenticating users. This
account can be created with the
module [avinor/kubernetes-azuread-integration/azurerm](https://github.com/avinor/terraform-azurerm-kubernetes-azuread-integration)
. Service principal required can be created
with [avinor/service-principal/azurerm](https://github.com/avinor/terraform-azurerm-service-principal) module. It is not
required to grant the service principal any roles, this module will make sure to grant required roles. That does however
mean that the deployment has to run with Owner priviledges.
reasons it will only deploy a rbac enabled clusters.

From version 5.0.0 AKS is configured with a system assigned managed identity that is automatically created. It is not
required to grant the manged identity any roles, this module will make sure to grant required roles. That does however
mean that the deployment has to run with Owner privileges. Migrating from service principal identity from earlier
version is supported. Make sure to validate role assignments when upgrading to version 5.0.0 or higher.

From version 1.5.0 of module it will assign the first node pool defined as the default one, this cannot be changed
later. If changing any variable that requires node pool to be recreated it will recreate entire cluster, that includes
name, vm size etc. Make sure this node pool is not changed after first deployment. Other node pools can change later.

## Usage

This example deploys a simple cluster with one node pool. The service principal and Azure AD integration secrets need to
be changed.
This example deploys a simple cluster with one node pool.

```terraform
module "simple" {
source = "avinor/kubernetes/azurerm"
version = "1.5.0"
version = "5.0.0"
name = "simple"
resource_group_name = "simple-aks-rg"
location = "westeurope"
service_cidr = "10.0.0.0/24"
kubernetes_version = "1.15.5"
service_principal = {
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "00000000-0000-0000-0000-000000000000"
}
azure_active_directory = {
client_app_id = "00000000-0000-0000-0000-000000000000"
server_app_id = "00000000-0000-0000-0000-000000000000"
server_app_secret = "00000000-0000-0000-0000-000000000000"
}
agent_pools = [
{
name = "linux"
Expand Down
12 changes: 0 additions & 12 deletions examples/addons/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ module "addon" {
service_cidr = "10.241.0.0/24"
kubernetes_version = "1.23.8"

service_principal = {
object_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "00000000-0000-0000-0000-000000000000"
}

azure_active_directory = {
client_app_id = "00000000-0000-0000-0000-000000000000"
server_app_id = "00000000-0000-0000-0000-000000000000"
server_app_secret = "00000000-0000-0000-0000-000000000000"
}

agent_pools = [
{
name = "linux"
Expand Down
12 changes: 0 additions & 12 deletions examples/diagnostics/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ module "diagnostics" {
service_cidr = "10.241.0.0/24"
kubernetes_version = "1.18.14"

service_principal = {
object_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "00000000-0000-0000-0000-000000000000"
}

azure_active_directory = {
client_app_id = "00000000-0000-0000-0000-000000000000"
server_app_id = "00000000-0000-0000-0000-000000000000"
server_app_secret = "00000000-0000-0000-0000-000000000000"
}

agent_pools = [
{
name = "linux"
Expand Down
12 changes: 0 additions & 12 deletions examples/simple/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ module "simple" {
service_cidr = "10.241.0.0/24"
kubernetes_version = "1.18.14"

service_principal = {
object_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "00000000-0000-0000-0000-000000000000"
}

azure_active_directory = {
client_app_id = "00000000-0000-0000-0000-000000000000"
server_app_id = "00000000-0000-0000-0000-000000000000"
server_app_secret = "00000000-0000-0000-0000-000000000000"
}

agent_pools = [
{
name = "linux"
Expand Down
54 changes: 33 additions & 21 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ terraform {
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.51.0"
version = "~> 3.57.0"
}
azuread = {
source = "hashicorp/azuread"
version = "~> 2.39.0"
}
}
}
Expand Down Expand Up @@ -83,6 +87,13 @@ resource "azurerm_resource_group" "aks" {
tags = var.tags
}

resource "azurerm_user_assigned_identity" "msi" {
location = var.location
name = format("%s-msi", var.name)
resource_group_name = azurerm_resource_group.aks.name
tags = var.tags
}

resource "azurerm_kubernetes_cluster" "aks" {
name = "${var.name}-aks"
location = azurerm_resource_group.aks.location
Expand Down Expand Up @@ -115,11 +126,6 @@ resource "azurerm_kubernetes_cluster" "aks" {
}
}

service_principal {
client_id = var.service_principal.client_id
client_secret = var.service_principal.client_secret
}

dynamic "key_vault_secrets_provider" {
for_each = var.key_vault_secrets_provider.enabled ? [true] : []
content {
Expand Down Expand Up @@ -155,19 +161,23 @@ resource "azurerm_kubernetes_cluster" "aks" {
}

network_profile {
network_plugin = "azure"
network_policy = "azure"
dns_service_ip = cidrhost(var.service_cidr, 10)
service_cidr = var.service_cidr
network_plugin = "azure"
network_policy = "azure"
dns_service_ip = cidrhost(var.service_cidr, 10)
service_cidr = var.service_cidr

# Use Standard if availability zones are set, Basic otherwise
load_balancer_sku = local.load_balancer_sku
}

azure_active_directory_role_based_access_control {
client_app_id = var.azure_active_directory.client_app_id
server_app_id = var.azure_active_directory.server_app_id
server_app_secret = var.azure_active_directory.server_app_secret
managed = true
admin_group_object_ids = var.cluster_admins
}

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

Expand Down Expand Up @@ -206,11 +216,13 @@ resource "azurerm_monitor_diagnostic_setting" "aks" {
eventhub_name = local.parsed_diag.event_hub_auth_id != null ? var.diagnostics.eventhub_name : null
storage_account_id = local.parsed_diag.storage_account_id

dynamic "log" {
for_each = data.azurerm_monitor_diagnostic_categories.default.log_category_types
dynamic "enabled_log" {
for_each = {
for k, v in data.azurerm_monitor_diagnostic_categories.default.log_category_types : k => v
if contains(local.parsed_diag.log, "all") || contains(local.parsed_diag.log, v)
}
content {
category = log.value
enabled = contains(local.parsed_diag.log, "all") || contains(local.parsed_diag.log, log.value)
category = enabled_log.value

retention_policy {
enabled = false
Expand Down Expand Up @@ -240,31 +252,31 @@ resource "azurerm_role_assignment" "acr" {

scope = var.container_registries[count.index]
role_definition_name = "AcrPull"
principal_id = var.service_principal.object_id
principal_id = azurerm_user_assigned_identity.msi.principal_id
}

resource "azurerm_role_assignment" "subnet" {
count = length(local.agent_pool_subnets)

scope = local.agent_pool_subnets[count.index]
role_definition_name = "Network Contributor"
principal_id = var.service_principal.object_id
principal_id = azurerm_user_assigned_identity.msi.principal_id
}

resource "azurerm_role_assignment" "storage" {
count = length(var.storage_contributor)

scope = var.storage_contributor[count.index]
role_definition_name = "Storage Account Contributor"
principal_id = var.service_principal.object_id
principal_id = azurerm_user_assigned_identity.msi.principal_id
}

resource "azurerm_role_assignment" "msi" {
count = length(var.managed_identities)

scope = var.managed_identities[count.index]
role_definition_name = "Managed Identity Operator"
principal_id = var.service_principal.object_id
principal_id = azurerm_user_assigned_identity.msi.principal_id
}

# Configure cluster
Expand Down
5 changes: 5 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ output "host" {
value = azurerm_kubernetes_cluster.aks.kube_admin_config.0.host
sensitive = true
}

output "identity" {
description = "The AKs managed identity Object(principal) ID."
value = azurerm_user_assigned_identity.msi.principal_id
}
27 changes: 14 additions & 13 deletions test/go.mod
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module github.com/avinor/terraform-azurerm-kubernetes/test

go 1.19
go 1.20

require github.com/gruntwork-io/terratest v0.41.7
require github.com/gruntwork-io/terratest v0.42.0

require (
cloud.google.com/go v0.104.0 // indirect
cloud.google.com/go/compute v1.10.0 // indirect
cloud.google.com/go/iam v0.5.0 // indirect
cloud.google.com/go v0.105.0 // indirect
cloud.google.com/go/compute v1.12.1 // indirect
cloud.google.com/go/compute/metadata v0.2.1 // indirect
cloud.google.com/go/iam v0.7.0 // indirect
cloud.google.com/go/storage v1.27.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
Expand All @@ -19,10 +20,10 @@ require (
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.6.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.0 // indirect
github.com/hashicorp/go-getter v1.7.1 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
Expand All @@ -36,21 +37,21 @@ require (
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/stretchr/testify v1.8.1 // indirect
github.com/tmccombs/hcl2json v0.3.3 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/zclconf/go-cty v1.9.1 // indirect
go.opencensus.io v0.23.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.100.0 // indirect
google.golang.org/api v0.103.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c // indirect
google.golang.org/grpc v1.51.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 0352d5b

Please sign in to comment.