Kubespot (Azure)

May 6, 2026 · View on GitHub

Compliance Oriented Kubernetes Setup for AWS, Google Cloud and Microsoft Azure.

Kubespot is an open source terraform module that attempts to create a complete compliance-oriented Kubernetes setup on AWS, Google Cloud and Azure. These add additional security such as additional system logs, file system monitoring, hard disk encryption and access control. Further, we setup the managed Redis and SQL on each of the Cloud providers with limited access to the Kubernetes cluster so things are further locked down. All of this should lead to setting up a HIPAA / PCI / SOC2 being made straightforward and repeatable.

This covers how we setup your infrastructure on AWS, Google Cloud and Azure. These are the three Cloud Providers that we currently support to run Kubernetes. Further, we use the managed service provided by each of the Cloud Providers. This document covers everything related to how infrastructure is setup within each Cloud, how we create an isolated environment for Compliance and the commonalities between them.

Tools & Setup

brew install kubectl kubernetes-helm google-cloud-sdk terraform

Keys

How to get key for cluster creation (client id and secret)

  1. Sign in to Azure portal
  2. Navigate to the Azure Active Directory
  3. Select "App registrations"
  4. If there is application already use existing one or create new one as follows
  5. Click on the "New registration" button to create a new application registration
  6. select the appropriate supported account type (e.g., "Accounts in this organizational directory only")
  7. Click on the "Register" button to create the application.
  8. After application is created, Under "Certificates & secrets," click on the "New client secret" button to create a new client secret.
  9. Copy the client id and client secret and pass it to cluster creation opszero module

Deployment

terraform init
terraform plan
terraform apply -auto-approve

Teardown

terraform destroy -auto-approve

Providers

NameVersion
azurermn/a

Inputs

NameDescriptionTypeDefaultRequired
acr_admin_enabledEnable admin access for Azure Container Registryboolfalseno
acr_idazure container resource id to provide access for aksstring""no
ad_group_idsActiveDirectory Groups that have access to this clusterlist[]no
ad_user_idsActiveDirectory users that have access to the kubernetes admin group and attached to the clusterlist[]no
address_spacesList of address spaces for the VNetlist(string)
[
"null"
]
no
aks_sku_tieraks sku tier. Possible values are Free ou Paidstring"Free"no
allocation_methodAllocation method for the public IPstring"Static"no
annotations_allowedn/astring"example.com/track,example.com/debug"no
azurerm_resource_group_enabledEnable creation of a new DDoS protection planbooltrueno
cidrThe address space that is used the virtual networkstring"10.0.0.0"no
cluster_namen/astring"aks"no
cmk_enabledFlag to control resource creation related to cmk encryption.boolfalseno
create_nat_gatewayFlag to create NAT Gatewayboolfalseno
default_node_poolDefault node pool configuration
object({
name = string
vm_size = string
os_disk_type = string
os_disk_size_gb = number
auto_scaling_enabled = bool
node_public_ip_enabled = bool
count = number
min_count = number
max_count = number
max_pods = number
type = string
})
n/ayes
default_tagsBase tags applied to all resourcesmap(string)
{
"ManagedBy": "OpsZero",
"Repositories": "https://github.com/opszero/terraform-azurerm-kubespot"
}
no
delegationDelegation of subnet resources
map(list(object({
name = string
service_delegation = list(object({
name = string
actions = list(string)
}))
})))
{}no
dns_serversList of DNS serverslist(string)[]no
drain_timeout_in_minutesn/anumber0no
edge_zoneSpecifies the Edge Zone within the Azure Region where this Managed Kubernetes Cluster should exist. Changing this forces a new resource to be created.stringnullno
enableEnable creation of a new DDoS protection planbooltrueno
enable_azure_policyEnable Azure Policy Addon.booltrueno
enable_ddos_ppEnable creation of a new DDoS protection planboolfalseno
enable_http_application_routingEnable HTTP Application Routing Addon (forces recreation).boolfalseno
enable_monitor_metricsn/aboolfalseno
enable_monitoringEnable OMS Agent for AKS monitoringboolfalseno
enable_route_tableFlag to enable Route Tableboolfalseno
enable_secret_providerEnable or disable the Key Vault Secrets Provider integrationboolfalseno
enable_upgrade_settingsn/abooltrueno
enabledEnable resource group creation and related resources.booltrueno
environment_nameName of the environment to create resourcesstring""no
existing_ddos_ppUse an existing DDoS protection plan IDstringnullno
image_cleaner_enabled(Optional) Specifies whether Image Cleaner is enabled.boolfalseno
image_cleaner_interval_hours(Optional) Specifies the interval in hours when images should be cleaned up. Defaults to 48.number48no
key_vault_idSpecifies the URL to a Key Vault Key (either from a Key Vault Key, or the Key URL for the Key Vault Secretstring""no
kubernetes_versionVersion of Kubernetes to deploystring"1.32.2"no
labels_allowedn/astring"app,component,environment"no
linux_profileUsername and ssh key for accessing AKS Linux nodes with ssh.
object({
username = string,
ssh_key = string
})
nullno
local_account_disabledWhether local account should be disable or notboolfalseno
locationThe Azure region where the resource group will be created.string"East US"no
lock_levelThe level of the lock. Can be 'CanNotDelete' or 'ReadOnly'.string"CanNotDelete"no
log_analytics_workspace_idLog Analytics Workspace IDstring""no
mariadb_sql_enabledSpecify whether the mariadb is enabledbooltrueno
mariadb_sql_versionSpecify the version of MariaDB to use. Possible values are 10.2 and 10.3string"10.2"no
max_surgen/astring"10%"no
msi_auth_for_monitoring_enabledEnable MSI auth for monitoringboolfalseno
nat_gateway_idle_timeoutTimeout in minutes for idle NAT Gatewaynumber4no
nat_ip_countNumber of public IP addresses to associate with the Azure NAT Gateway. These IPs will be used for outbound internet traffic from private subnets.number2no
network_pluginNetwork plugin to use for networking.string"azure"no
network_policy(Optional) Sets up network policy to be used with Azure CNI. Network policy allows us to control the traffic flow between pods. Currently supported values are calico and azure. Changing this forces a new resource to be created.stringnullno
node_resource_groupName of the resource group in which to put AKS nodes. If null default to MC_stringnullno
node_soak_duration_in_minutesn/anumber0no
nodes_desired_capacityThe number of Amazon EC2 instances that should be running in the groupnumber1no
nodes_poolsList of additional node pools
list(object({
name = string
vm_size = string
os_type = string
os_disk_type = string
os_disk_size_gb = number
auto_scaling_enabled = bool
node_count = number
min_count = number
max_count = number
max_pods = number
node_public_ip_enabled = bool
mode = string
orchestrator_version = string
node_taints = list(string)
host_group_id = string
# capacity_reservation_group_id = string
# workload_runtime = string
# zones = list(string)
}))
[]no
notesOptional notes about the lock.string"Resource group lock to prevent accidental deletion"no
outbound_typeThe outbound (egress) routing method which should be used for this Kubernetes Cluster. Possible values are loadBalancer and userDefinedRouting.string"loadBalancer"no
postgres_sql_enabledSpecify whether postgres sql is enabledboolfalseno
postgres_sql_versionSpecify the version of PostgreSQL to use. Valid values are 9.5, 9.6, 10, 10.0, and 11string"11"no
prefix(Optional) The prefix for the resources created in the specified Azure Resource Group. Omitting this variable requires both var.cluster_log_analytics_workspace_name and var.cluster_name have been set. Only one of var.prefix,var.dns_prefix_private_cluster can be specified.string""no
private_cluster_enabledConfigure AKS as a Private Cluster : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster#private_cluster_enabledboolfalseno
private_dns_zone_idId of the private DNS Zone when <private_dns_zone_type> is customstringnullno
private_dns_zone_typen/astringnullno
redis_capacityThe size of the Redis cache to deploynumber1no
redis_enabledSpecify whether the redis cluster is enabledboolfalseno
redis_familyThe SKU family/pricing group to use. Valid values are C (for Basic/Standard SKU family) and P (for Premium)string"C"no
redis_shard_countOnly available when using the Premium SKU The number of Shards to create on the Redis Clusternumber0no
redis_sku_nameThe SKU of Redis to use. Possible values are Basic, Standard and Premiumstring"Standard"no
regionThe Azure Region where the Resource Group should exist.string"Central US"no
registry_enabledSpecify whether the container registry is enabledbooltrueno
registry_namen/astring"acrprodtyj"no
resource_group_nameUse an existing DDoS protection plan IDstring""no
resource_lock_enabledFlag to enable resource lock on the resource group.boolfalseno
role_based_access_control_enabledWhether role based acces control should be enabled or notbooltrueno
route_table_nameName of the route tablestringnullno
routesRoutes to be added to the route table
list(object({
name = string
address_prefix = string
next_hop_type = string
next_hop_in_ip_address = string
}))
[]no
service_cidrCIDR used by kubernetes services (kubectl get svc).string"10.1.0.0/16"no
service_endpoint_policy_idsService Endpoint Policy IDs for subnetlist(string)nullno
service_endpointsService Endpoints for subnetlist(string)[]no
skuSKU for the Public IPstring"Standard"no
sku_nameSKU for NAT Gatewaystring"Standard"no
specific_name_subnetSpecific subnet names if neededboolfalseno
specific_subnet_namesn/alist(string)[]no
sql_master_passwordThe Password associated with the administrator_login for the PostgreSQL/MariaDB Serverstring""no
sql_master_usernameThe Administrator login for the PostgreSQL/MariabDB Serverstring"prod"no
sql_sku_nameSpecify the SKU Name for this PostgreSQL Serverstring"GP_Gen5_2"no
sql_storage_in_mbMax storage allowed for a MariaDB servernumber10240no
subnet_namesSubnet nameslist(string)[]no
subnet_prefixesSubnet prefixes for address allocationlist(string)[]no
tagsAdditional tags that override or extend default_tagsmap(string){}no
timeoutsTimeout values for resource group operations.
object({
create = optional(string, "30m")
read = optional(string, "5m")
update = optional(string, "30m")
delete = optional(string, "30m")
})
{}no
zonesZones for NAT Gatewaylist(string)[]no

Resources

NameType
azurerm_container_registry.acrresource
azurerm_disk_encryption_set.mainresource
azurerm_key_vault_access_policy.key_vaultresource
azurerm_key_vault_access_policy.kubelet_identityresource
azurerm_key_vault_access_policy.mainresource
azurerm_key_vault_key.exampleresource
azurerm_kubernetes_cluster.aksresource
azurerm_kubernetes_cluster_node_pool.node_poolsresource
azurerm_management_lock.defaultresource
azurerm_nat_gateway.natgwresource
azurerm_nat_gateway_public_ip_association.pip_assocresource
azurerm_network_ddos_protection_plan.mainresource
azurerm_postgresql_database.qaresource
azurerm_postgresql_server.defaultresource
azurerm_postgresql_virtual_network_rule.defaultresource
azurerm_public_ip.pipresource
azurerm_redis_cache.defaultresource
azurerm_resource_group.defaultresource
azurerm_role_assignment.aks_acr_access_object_idresource
azurerm_role_assignment.aks_acr_access_principal_idresource
azurerm_role_assignment.aks_system_identityresource
azurerm_role_assignment.aks_uai_private_dns_zone_contributorresource
azurerm_role_assignment.aks_uai_vnet_network_contributorresource
azurerm_role_assignment.aks_user_assignedresource
azurerm_role_assignment.azurerm_disk_encryption_set_key_vault_accessresource
azurerm_route_table.rtresource
azurerm_subnet.subnetresource
azurerm_subnet_nat_gateway_association.subnet_assocresource
azurerm_subnet_route_table_association.mainresource
azurerm_user_assigned_identity.aks_user_assigned_identityresource
azurerm_virtual_network.defaultresource
azurerm_client_config.currentdata source
azurerm_subscription.currentdata source

Outputs

NameDescription
aks_cluster_nameThe name of the AKS cluster
aks_fqdnFQDN of the AKS cluster
aks_kube_configRaw kubeconfig for the AKS cluster
nat_gateway_idThe ID of the NAT Gateway
redis_idID of the Redis cache
registry_nameName of the Azure Container Registry
resource_group_locationThe location of the created resource group
resource_group_nameThe name of the created resource group
subnet_idn/a
subnet_idsThe IDs of the created subnets
vnet_idThe ID of the created Virtual Network

🚀 Built by opsZero!

opsZero provides software and consulting for DevOps. With our decade plus of experience scaling some of the world’s most innovative companies we have developed deep expertise in Kubernetes, DevOps, FinOps, and Compliance.

Our software and consulting solutions enable organizations to:

  • migrate workloads to the Cloud
  • setup compliance frameworks including SOC2, HIPAA, PCI-DSS, ITAR, FedRamp, CMMC, and more.
  • FinOps solutions to reduce the cost of running Cloud workloads
  • Kubernetes optimized for web scale and AI workloads
  • finding underutilized Cloud resources
  • setting up custom AI training and delivery
  • building data integrations and scrapers
  • modernizing onto modern ARM based processors

We do this with a high-touch support model where you:

  • Get access to us on Slack, Microsoft Teams or Email
  • Get 24/7 coverage of your infrastructure
  • Get an accelerated migration to Kubernetes

Please schedule a call if you need support.



AWS Advanced Tier AWS DevOps Competency AWS EKS Delivery AWS Public Sector