AKS cluster

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

By creating the AKS cluster, we will be covering the following

things in order to configure a full-fledged AKS cluster.


a. Multi-node public AKS Cluster. Additional nodes will be created as
windows.
b. Azure Application Gateway as Ingress Controller.
c. Azure Firewall to manage egress traffic.
d. Azure Log Analytics.
e. Azure Container Registry.
f. Azure KeyVault.

Here is a rough diagram for this setup:

Azure Kubernetes Setup


By using this setup we will be achieving the below:
** Inbound traffic will come via App Gateway, we can configure that as
Web Application Firewall [WAF] as well.
** Outbound traffic will go via Azure Firewall, by default it will block
all the connections and only allow traffic which is allowed via firewall
rules. I have already explained the process in depth here.

Let’s get started with Terraform Code:

To create an ACR, am using the below configuration.

## Exisiting RG
data "azurerm_resource_group" "rg-name" {
name = var.resource_group_name
}

## Current User config


data "azurerm_client_config" "current" {}

## Container Registry
resource "azurerm_container_registry" "container-registry" {
location = data.azurerm_resource_group.rg-name.location
name = var.acr_name
resource_group_name = data.azurerm_resource_group.rg-name.name
sku = "Premium"

retention_policy {
days = 30
enabled = true
}
}

Create a Disk encryption Key, am storing the secret in a key vault to


keep the key secure.
## KeyVault
resource "azurerm_key_vault" "keyvault" {
location = data.azurerm_resource_group.rg-name.location
name = var.key_vault_name
resource_group_name = data.azurerm_resource_group.rg-name.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "premium"
enabled_for_disk_encryption = true
purge_protection_enabled = true
soft_delete_retention_days = 7
}

## Access Policies
resource "azurerm_key_vault_access_policy" "current_user" {
key_vault_id = azurerm_key_vault.keyvault.id
object_id = data.azurerm_client_config.current.object_id
tenant_id = data.azurerm_client_config.current.tenant_id
key_permissions = [
"Get",
"Create",
"Delete",
"GetRotationPolicy",
"Recover",
]
}

resource "azurerm_key_vault_access_policy" "des" {


key_vault_id = azurerm_key_vault.keyvault.id
object_id = azurerm_disk_encryption_set.des.identity[0].principal_id
tenant_id = azurerm_disk_encryption_set.des.identity[0].tenant_id
key_permissions = [
"Get",
"WrapKey",
"UnwrapKey"
]
}

## Des Key
resource "azurerm_key_vault_key" "des_key" {
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
key_type = "RSA-HSM"
key_vault_id = azurerm_key_vault.keyvault.id
name = "wescom-des-kv-key"
key_size = 2048
depends_on = [
azurerm_key_vault_access_policy.current_user
]
}

## Des Key with OS


resource "azurerm_disk_encryption_set" "des" {
key_vault_key_id = azurerm_key_vault_key.des_key.id
location = data.azurerm_resource_group.rg-name.location
name = "des"
resource_group_name = data.azurerm_resource_group.rg-name.name

identity {
type = "SystemAssigned"
}
}

To create an AKS, am using the AzureRM AKS module here, which I


found great to use. Using this module you can configure appGateway,
Log Analytics, enable RBAC etc. It’s an open source Module, you can
contribute as well.

resource "random_id" "prefix" {


byte_length = 6
}

## Config for Windows Nodepool


locals {
nodes = {
for i in range(1) : "worker${i}" => {
name = substr("win${i}${random_id.prefix.hex}", 0, 6)
vm_size = "Standard_D2s_v3"
os_type = "Windows"
os_sku = "Windows2019"
enable_auto_scaling = true
max_pods = 50
min_count = 1
max_count = 3
windows_profile = {
outbound_nat_enabled = true
}
}
}
}
module "aks" {
source = "Azure/aks/azurerm"
version = "6.8.0"

prefix = var.cluster_name
resource_group_name = data.azurerm_resource_group.rg-name.name
kubernetes_version = "1.25" # don't specify the patch version!
orchestrator_version = "1.25" # don't specify the patch version!
automatic_channel_upgrade = "patch"
agents_count = 3
agents_max_pods = 30
agents_size = "Standard_D2s_v3"
agents_pool_name = "nodepool"
only_critical_addons_enabled = false
agents_pool_linux_os_configs = [
{
transparent_huge_page_enabled = "always"
sysctl_configs = [{
fs_aio_max_nr = 65536
fs_file_max = 100000
fs_inotify_max_user_watches = 1000000
}]
}
]
agents_type = "VirtualMachineScaleSets"
node_pools = local.nodes
attached_acr_id_map = {
example = azurerm_container_registry.container-registry.id
}
azure_policy_enabled = true
disk_encryption_set_id =
azurerm_disk_encryption_set.des.id
enable_auto_scaling = false
enable_host_encryption = true
http_application_routing_enabled = true
ingress_application_gateway_enabled = true
ingress_application_gateway_name = var.app_gateway_name
ingress_application_gateway_subnet_cidr = var.app_gateway_subnet_cidr
local_account_disabled = true
log_analytics_workspace_enabled = true
cluster_log_analytics_workspace_name = var.log_analytics_name
net_profile_dns_service_ip = var.dns_service_ip
net_profile_service_cidr = var.dns_service_cidr
network_plugin = "azure"
network_policy = "azure"
os_disk_size_gb = 100
private_cluster_enabled = false
private_cluster_public_fqdn_enabled = false
public_network_access_enabled = true
rbac_aad = true
rbac_aad_azure_rbac_enabled = true
rbac_aad_managed = true
role_based_access_control_enabled = true
rbac_aad_admin_group_object_ids = ["xxxxxxxx-xxxx-xxxx-xxxx-
xxxxxxxxx"]
sku_tier = "Standard"
}

Azure Firewall setup we can configure to control the egress traffic,


which I have already covered in my previous post.

You can find the full terraform code here as well.

Once the code is ready, It’s time to run terraform commands to


proceed.
** terraform init
** terraform validate
** terraform plan
** terraform apply

As per the best practices store the tfstate in a remote repository such
as a storage account. Here is what am doing to initialize the
terraform with the remote repository [Azure Storage Blob].

To initialize with a storage account am running the below command.

access_key=$(az storage account keys list -g <rg-name> -n <sa-name> --query


[0].value -o tsv)
terraform init \
-backend-config "storage_account_name=<sa-name>" \
-backend-config "container_name=terraform-tfstate" \
-backend-config "access_key=$access_key" \
-backend-config "key=terraform-tfstate/aks/dev/terraform.tfstate"
Once the initialization is completed you can proceed with the below
commands as followed.
1. terraform validate
2. terraform plan
3. terraform apply

You might also like