Skip to content

Latest commit

 

History

History
258 lines (247 loc) · 9.06 KB

File metadata and controls

258 lines (247 loc) · 9.06 KB

StandardAKS

Terraform modules to provision AKS and bootstrap using ArgoCD AppOfApps pattern.

Base Code

Diagram

This is what you will be getting.

  • Terraform
    • Create VNET, Subnets, and NSGs.
    • Create a AKS cluster.
      • NSG for Agent Pool
      • Load balancer
      • Public IP address * 2
      • Managed Identity
      • Networking
        • Azure CNI
        • Calico
      • StorageClass
        • Managed Disk
        • Azure File
    • Create a storage account.
    • Create a key vault.
    • Deploy K8S resources.
      • Ingress-nginx - Ingress controller.
      • Cert-manager - Certificate management.
      • AKV2K8S - Manage secret using Azure Key Vault.
      • ArgoCD + KSOPS - Continuous delivery, Secret management using SOPS.
        • AKS bootstrap app
  • ArgoCD Bootstrap APP Using kulmam92/aks-argocd-bootstrap
    • Minio - Expose Azure storage as S3 compatible storage.
    • Kube-Prometheus-Stack - Monitoring.
    • K8S config App - Any K8S cluster level config.

Usage

Example showing deployment of Bootstrapped AKS.

Sample script to deploy is in /test/fixture.

Make sure to replace any thing that starts with "<MY-" from the ./test/fixture/terraform.tfvars file before use that.

component          = "AKSTest"
product            = "AKSTest"
environment        = "Sandbox"
datacenter         = "WestUS2"
location           = "WestUS2"
account_short_name = "aks"
tags = {
  DataCenter    = "WestUS2"
  Environment   = "Sandbox"
  Terraform     = true
  TerraformPath = "components/StandardAKS/test"
}
#################################
# Vnet
vnet_networking_object = {
  vnet = {
    name_overwrite  = null
    address_space   = ["10.1.0.0/16"]
    dns             = []
    enable_ddos_std = false
    ddos_id         = null
  }
  subnets = {
    subnet1 = {
      name_postfix                                   = "K8S"
      cidr                                           = ["10.1.0.0/22"]
      service_endpoints                              = ["Microsoft.Sql", "Microsoft.Storage", "Microsoft.KeyVault"]
      enforce_private_link_endpoint_network_policies = null
      enforce_private_link_service_network_policies  = null
      nsg_name_postfix                               = "K8S"
      nsg = [
        # ssh
        {
          name                       = "Allow-ssh"
          priority                   = 102
          direction                  = "Inbound"
          access                     = "Allow"
          protocol                   = "Tcp"
          source_port_range          = "*"
          destination_port_range     = "22"
          source_address_prefix      = "<MY-IP-Address>"
          destination_address_prefix = "*"
        },
        # HTTPS
        {
          name                       = "Allow-HTTPS"
          priority                   = 103
          direction                  = "Inbound"
          access                     = "Allow"
          protocol                   = "*"
          source_port_range          = "*"
          destination_port_range     = "443"
          source_address_prefix      = "*"
          destination_address_prefix = "*"
        },
        # HTTP
        {
          name                       = "Allow-HTTP"
          priority                   = 104
          direction                  = "Inbound"
          access                     = "Allow"
          protocol                   = "*"
          source_port_range          = "*"
          destination_port_range     = "80"
          source_address_prefix      = "*"
          destination_address_prefix = "*"
        }
      ]
      delegation = null
      # # subnet delegation for aci_connector_linux
      # delegation = {
      #   name = "aciDelegation"
      #   service_delegation = {
      #     name    = "Microsoft.ContainerInstance/containerGroups"
      #     actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
      #   }
      # }
    }
  }
}
#################################
# AKS cluster
aks_private_cluster_enabled = false
aks_dns_prefix              = "<MY-DNS-PREFIX>"
aks_sku_tier                = "Paid" # Paid/Free
# aks_kubernetes_version               = "1.18.10" # 1.9.3
aks_api_server_authorized_ip_ranges = ["<MY-IP-Address>"]
# aks_node_resource_group              = null
aks_linux_profile     = { username = "aksadmin", ssh_key = "" }
aks_windows_profile   = { username = "aksadmin", password = "<MY-password>" }
aks_service_principal = null # cluster infrastructure authentication - identity
aks_addons = {
  http_application_routing        = false
  dashboard                       = true
  oms_agent                       = false
  oms_agent_workspace_id          = null
  aci_connector_linux             = false
  aci_connector_linux_subnet_name = null
  policy                          = true
}
aks_network_profile = {
  network_plugin = "azure"        # kubenet
  network_policy = "calico"       # azure
  outbound_type  = "loadBalancer" # userDefinedRouting
  pod_cidr       = null           # network_plugin is set to kubenet.
  # This range should not be used by any network element on or connected to this VNet.
  # Service address CIDR must be smaller than /12.
  # docker_bridge_cidr, dns_service_ip and service_cidr should all be empty or all should be set.
  docker_bridge_cidr = null # IP address (in CIDR notation) used as the Docker bridge IP address on nodes.
  service_cidr       = null # The Network Range used by the Kubernetes service.
  dns_service_ip     = null # cidrhost(var.service_cidr, 10) IP address within the Kubernetes service address range that will be used by cluster service discovery (kube-dns).
}
#################################
# cluster node pool
aks_agent_pools = [
  {
    name = "linux"
    # node_count          = 1 # reuqired when enable_auto_scaling = flase
    vm_size = "Standard_D2_v3"
    # os_disk_size_gb     = each.value.os_disk_size_gb
    os_type             = "Linux"
    availability_zones  = [1, 2, 3]
    enable_auto_scaling = true
    min_count           = 1 # reuqired when enable_auto_scaling = true
    max_count           = 6 # reuqired when enable_auto_scaling = true
  }
]
# Will be set from the main.tf
# aks_agent_pool_subnet_name           = module.vnet.vnet_subnet_names[0]
# aks_agent_pool_vnet_name             = module.vnet.vnet_name
# aks_agent_pool_vnet_resource_group_name  = module.resource_group.name
#################################
# RBAC
aks_enable_role_based_access_control = true
aks_rbac_aad_managed                 = true
aks_rbac_aad_admin_group_names       = ["<MY-ADD-Admin-Group>"]
# aks_rbac_azure_active_directory      = # don't set when rbac_aad_managed = true
#################################
# log analytics
aks_enable_log_analytics_workspace = true
aks_log_analytics_workspace_sku    = "free" # "PerGB2018"
aks_log_retention_in_days          = 7      # 30
#################################
# diagnostics
# aks_diagnostics = {
#   destination = string
#   eventhub_name = string
#   logs = ["all"]
#   metrics = ["all"]
# }
#################################
# role
# aks_container_registries             = var.container_registries
# aks_storage_contributor              = var.storage_contributor
# aks_managed_identities               = var.managed_identities
#################################
# Configure cluster
# "ServiceAccount", "User", "Group"
aks_admins = [
  { kind = "User", name = "<MY-email>" },
  { kind = "Group", name = "<MY-AD-group-admin-email>" }
]
# aks_service_accounts                 = # List of service accounts to create and their roles
#################################
# Run "htpasswd -c auth admin" to generate auth
# username should be admin. KubernetesIsCool is password in this example
aks_prometheus_basic_auth = "admin:$apr1$8spKbCh4$2b8tAg9lWYiy8XtNF6hqb/"
aks_cert_manager_acme_email = "<MY-email>"

#################################
# storage account
# storage_account_name_override    = "saazusew2minio01"
storage_account_tier             = "Standard"
storage_account_replication_type = "LRS"
storage_account_kind             = "StorageV2"
storage_account_is_hns_enabled   = "true"
# only lowercase alphanumeric characters and hyphens allowed
storage_account_shares = [
  { name = "airflow-dags", quota = 10 },
  { name = "airflow-logs", quota = 10 }
]

#################################
# key vault
key_vault_sku_name = "premium"
key_vault_enable_rbac_authorization = true
key_vault_network_acls_ip_rules = ["<MY-IP-Address>"]
key_vault_role_assignments = [
  {
    name = "<MY-email>"
    role = "Key Vault Administrator"
    type = "user"
  },
  {
    name = "<MY-AD-admin-group>"
    role = "Key Vault Administrator"
    type = "group"
  },
  {
    name = "<MY-email>"
    role = "Key Vault Secrets Officer"
    type = "user"
  },
  {
    name = "<MY-AD-admin-group>"
    role = "Key Vault Secrets Officer"
    type = "group"
  },
]