{"id":61,"date":"2019-12-24T00:22:39","date_gmt":"2019-12-23T23:22:39","guid":{"rendered":"http:\/\/aymen-segni.com\/?p=61"},"modified":"2020-07-23T02:10:17","modified_gmt":"2020-07-23T00:10:17","slug":"create-a-kubernetes-cluster-with-azure-aks-using-terraform","status":"publish","type":"post","link":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/","title":{"rendered":"Create a Kubernetes cluster with Azure AKS using Terraform"},"content":{"rendered":"\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>This written  Infra as Code (IaC) workshop show how to create AKS cluster using Hashicorp<a href=\"https:\/\/www.terraform.io\"> <\/a><a rel=\"noreferrer noopener\" aria-label=\"Terraform (opens in a new tab)\" href=\"https:\/\/www.terraform.io\" target=\"_blank\"><span style=\"text-decoration: underline;\">Terraform<\/span><\/a><\/p>\n\n\n\n<p><strong>Azure Kubernetes Service (AKS)<\/strong> is a highly available, secure, and fully managed <span style=\"text-decoration: underline;\"><a href=\"https:\/\/kubernetes.io\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Kubernetes (opens in a new tab)\">Kubernetes<\/a> <\/span>service of Microsoft Azure.<br><br>The fully managed Azure Kubernetes Service (AKS) makes deploying and managing containerized applications easy. It offers serverless Kubernetes, an integrated continuous integration and continuous delivery (CI\/CD) experience, and enterprise-grade security and governance. Unite your development and operations teams on a single platform to rapidly build, deliver, and scale applications with confidence.<\/p>\n\n\n\n<p>Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.<\/p>\n\n\n\n<p>Admitting, there are number of Cloud provisioning IaC tools, each with its own implementation. With the object of this lab, We will focus exclusively on deploying AKS cluster on Azure.<\/p>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Objectives<\/h2>\n\n\n\n<p>This guide walks you through how to the following tasks:<\/p>\n\n\n\n<ol class=\"ul-black wp-block-list\"><li>\u2705 Learn HCL (HashiCorp Language) and Terraform best practices by doing<\/li><li>\u2705 Use Terraform and AKS to create a Kubernetes cluster<\/li><li>\u2705 Use the kubectl tool to test the availability of a Kubernetes cluster<\/li><\/ol>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Assumptions and Prerequisites<\/h2>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li>You have basic knowledge of<span style=\"text-decoration: underline;\"><code> <a rel=\"noreferrer noopener\" aria-label=\"Azure (opens in a new tab)\" href=\"https:\/\/azure.microsoft.com\/en-us\/\" target=\"_blank\">Azure<\/a><\/code><\/span><\/li><li>Have basic knowledge of <code>Kubernetes<\/code><\/li><li>You have <code>Terraform<\/code> installed in your local machine<\/li><li>Azure subscription: Sign up for an Azure account, if you don&#8217;t own one already. You will receive USD200 in free credits.<\/li><\/ul>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Software Dependencies<\/h2>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li><a rel=\"noreferrer noopener\" aria-label=\"Terraform (opens in a new tab)\" href=\"https:\/\/www.terraform.io\/downloads.html\" target=\"_blank\">Terraform<\/a>&nbsp;0.12.x<\/li><li>Terraform <a href=\"https:\/\/www.terraform.io\/docs\/providers\/azurerm\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Azure Provider&nbsp; (opens in a new tab)\"><span style=\"text-decoration: underline;\">Azure Provider&nbsp;<\/span><\/a>plugin v2.4<\/li><\/ul>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Why use Terraform (or any other IaC tool) to create an AKS cluster ?<\/h2>\n\n\n\n<p>Using the Azure Portal you can create a cluster with few clicks. <br>However, it usually a better idea to keep the configuration for your cluster under version control. Assuming you accidentally delete your cluster or decide to provision a copy in another region, you can  easily replicate the same configuration. And if you&#8217;re working as part of a team, source control gives you peace of mind. You know precisely why changes occurred and who made them.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"has-text-color has-background has-very-light-gray-color has-vivid-purple-background-color\">\u2b50\ufe0fInfrastructure as Code, in simple terms, is a means by which we can write declarative definitions for the infrastructure we want to exist and using them with a provisioning tool that deals with the actual deployment. <br>This means that we can code what we want built, provide necessary credentials for the given provider, kick off the provisioning process, pop the kettle on and come back to find all your services purring along nicely in the cloud\u2026 or a terminal screen full of ominous warnings about failed deployment and \u201cunrecoverable state\u201d and a deep sense of growing unease (but not often, don\u2019t worry \ud83d\udc4d).<\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/IoC_twitterpost01_dc3eac7bbbbe620b391cff9aaebf16f3.jpg\" alt=\"Using Terraform to create AKS cluster\" class=\"wp-image-73\" width=\"580\" height=\"291\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/IoC_twitterpost01_dc3eac7bbbbe620b391cff9aaebf16f3.jpg 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/IoC_twitterpost01_dc3eac7bbbbe620b391cff9aaebf16f3.jpg 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/IoC_twitterpost01_dc3eac7bbbbe620b391cff9aaebf16f3.jpg 768w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Define AKS cluster with Terraform<\/h2>\n\n\n\n<p>The first step is to obtain the source code from my Github repository. <br>This will clone the sample repository and make it the current directory:<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-light-gray-color has-very-dark-gray-background-color\">git clone https:\/\/github.com\/AymenSegni\/azure-aks-k8s-tf.git<br>cd azure-aks-k8s-tf<\/p>\n\n\n\n<p>The directory that holds the Terraform configuration files for this lab has a special tree structure. <br>Obviously, there are 2 main subfolders: <code><strong>deployment<\/strong><\/code> and <strong><code>modules<\/code><\/strong>. In order to see the source code structure you can run <code>t<em>ree <\/em><\/code> <br><\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05-1024x734.png\" alt=\"Tree project create AKS cluster with Terraform\" class=\"wp-image-626\" width=\"610\" height=\"437\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05.png 1446w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.00.05.png 1280w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><\/figure>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\">Project structure <\/h4>\n\n\n\n<p><strong>1- <code>modules<\/code><\/strong>: represent here in this layout the Terraform modules (general re-used functions) . In this lab, we have basically 4 modules: <br>&#8211; <code>aks_cluste<\/code>r: the main unit providing the AKS service<br>&#8211;<code> aks_identities<\/code>: the cluster identity unit that manage the cluster service principal <br>&#8211; <code>aks_network:<\/code> Create the cluster Virtual Network and subnetwork on Azure<br><strong>&#8211; <\/strong><code>log_analytics<\/code>: Formally Azure Operational Insight is the unit that  manages logs and cluster health checks<br><br><strong><code>2- Deployment<\/code>: <\/strong> is the main function of this layout, responsible of the AKS Kubernetes cluster deployment on Azure.<br>In <strong><code>main.tf<\/code><\/strong> we define the Terraform modules already created in <code>\/modules<\/code> sub-folder with the appropriate inputs defined in<strong><code> variables.tf<\/code><\/strong> or in a <code>terraform.tfvars<\/code> file (wich is not covered in this guide).<\/p>\n\n\n\n<p><br>Stay tuned, in the next section, we\u2019re going to talk about how to create reusable infrastructure with Terraform.<\/p>\n\n\n\n<h3 class=\"has-very-dark-gray-color has-text-color wp-block-heading\">Terraform modules<\/h3>\n\n\n\n<p>With Terraform, you can put a bunch of code inside of a&nbsp;<code>Terraform module<\/code>&nbsp;and reuse that module in multiple places throughout your code. Instead of having the same code copy\/pasted in the <code>staging and production environments<\/code>, you\u2019ll be able to have both environments reuse code from the same module.<br>This is a big deal. Modules are the key ingredient to writing reusable, maintainable, and testable Terraform code.<\/p>\n\n\n\n<p>Every Terraform configuration has at least one module, known as its&nbsp;<em>root module<\/em> (the<code> \/deployment<\/code> in this lab context), which consists of the resources defined in the&nbsp;<code>.tf<\/code>&nbsp;files in the main working directory.<\/p>\n\n\n\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\"><strong>Terraform module structure<\/strong><\/h4>\n\n\n\n<p>In this lab we have a well defined structure of the TF Modules. Let\u2019s go through  the <code>aks_identities<\/code> module as an example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.10.55-1024x246.png\" alt=\"Create AKS cluster with Terraform\nmodule tree\n\" class=\"wp-image-627\" width=\"605\" height=\"145\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.10.55.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.10.55.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.10.55.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/04\/Screenshot-2020-04-05-at-17.10.55.png 1272w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>The module is a container for multiple resources that are used together.<\/p>\n\n\n\n<ol class=\"ul-black wp-block-list\"><li><code>main.tf:<\/code> the aks cluster resources are packaged in the main.tf file <\/li><li><code>variables.tf<\/code>: In Terraform, modules can have input parameters, too. To define them, you use a mechanism input variables.<\/li><li><code>output.tf<\/code>:  In Terraform, a module can also return values. Again, this is done using a mechanism: output variables.<\/li><\/ol>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/i-know-tf-module.jpeg\" alt=\"Now, you know all the Terraform modules secrets! pride \ud83d\ude0a ^^\" class=\"wp-image-134\" width=\"455\" height=\"256\"\/><figcaption>Now, you know all the Terraform modules secrets! pride \ud83d\ude0a&nbsp;^^<\/figcaption><\/figure><\/div>\n\n\n\n<p>In this stage, will see together a full example of the aks cluster module.<\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li>main resources: defined in the main.tf configuration file<\/li><\/ul>\n\n\n\n<pre title=\"# aks cluster main.tf\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">resource \"azurerm_kubernetes_cluster\" \"cluster\" {\n  name                = var.cluster_name\n  location            = var.location\n  resource_group_name = var.resource_group_name\n  dns_prefix          = var.dns_prefix\n  kubernetes_version  = var.kubernetes_version\n\n  default_node_pool {\n    name            = var.default_pool_name\n    node_count      = var.node_count\n    vm_size         = var.vm_size\n    os_disk_size_gb = var.os_disk_size_gb\n    vnet_subnet_id  = var.vnet_subnet_id\n    max_pods        = var.max_pods\n    type            = var.default_pool_type\n\n    enable_auto_scaling = true\n    min_count           = var.min_count\n    max_count           = var.max_count\n\n    tags = merge(\n    {\n       \"environment\" = \"runitoncloud\"\n    },\n    {\n      \"aadssh\" = \"True\"\n    },\n  )\n  }\n\n\n  network_profile {\n    network_plugin     = var.network_plugin\n    network_policy     = \"calico\"\n    service_cidr       = var.service_cidr\n    dns_service_ip     = \"10.0.0.10\"\n    docker_bridge_cidr = \"172.17.0.1\/16\"\n  }\n\n  service_principal {\n    client_id     = var.client_id\n    client_secret = var.client_secret\n  }\n\n\n  tags = {\n    Environment = \"Development\"\n  }\n\n  lifecycle {\n    prevent_destroy = true\n  }\n}\n\nresource \"azurerm_monitor_diagnostic_setting\" \"aks_cluster\" {\n  name                       = \"${azurerm_kubernetes_cluster.cluster.name}-audit\"\n  target_resource_id         = azurerm_kubernetes_cluster.cluster.id\n  log_analytics_workspace_id = var.diagnostics_workspace_id\n\n  log {\n    category = \"kube-apiserver\"\n    enabled  = true\n\n    retention_policy {\n      enabled = false\n    }\n  }\n\n  log {\n    category = \"kube-controller-manager\"\n    enabled  = true\n\n    retention_policy {\n      enabled = false\n    }\n  }\n\n  log {\n    category = \"cluster-autoscaler\"\n    enabled  = true\n\n    retention_policy {\n      enabled = false\n    }\n  }\n\n  log {\n    category = \"kube-scheduler\"\n    enabled  = true\n\n    retention_policy {\n      enabled = false\n    }\n  }\n\n  log {\n    category = \"kube-audit\"\n    enabled  = true\n\n    retention_policy {\n      enabled = false\n    }\n  }\n\n  metric {\n    category = \"AllMetrics\"\n    enabled  = false\n\n    retention_policy {\n      enabled = false\n    }\n  }\n}\n<\/code><\/pre>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\"><strong>Terraform resources<\/strong><\/h4>\n\n\n\n<p><code>resource \"azurerm_kubernetes_cluster\" \"cluster\" {}<\/code><br>This block is responsible for creating the AKS cluster<\/p>\n\n\n\n<p><em>Resources<\/em>&nbsp;are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.<\/p>\n<\/div><\/div>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li> Variables:  define the resources inputs<\/li><\/ul>\n\n\n\n<pre title=\"# aks cluster variables.tf\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">variable \"dns_prefix\" {\n  description = \"DNS prefix\"\n}\nvariable \"location\" {\n  description = \"azure location to deploy resources\"\n}\nvariable \"cluster_name\" {\n  description = \"AKS cluster name\"\n}\nvariable \"resource_group_name\" {\n  description = \"name of the resource group to deploy AKS cluster in\"\n}\nvariable \"kubernetes_version\" {\n  description = \"version of the kubernetes cluster\"\n}\nvariable \"api_server_authorized_ip_ranges\" {\n  description = \"ip ranges to lock down access to kubernetes api server\"\n  default     = \"0.0.0.0\/0\"\n}\n# Node Pool config\nvariable \"agent_pool_name\" {\n  description = \"name for the agent pool profile\"\n  default     = \"default\"\n}\nvariable \"agent_pool_type\" {\n  description = \"type of the agent pool (AvailabilitySet and VirtualMachineScaleSets)\"\n  default     = \"AvailabilitySet\"\n}\nvariable \"node_count\" {\n  description = \"number of nodes to deploy\"\n}\nvariable \"vm_size\" {\n  description = \"size\/type of VM to use for nodes\"\n}\nvariable \"os_disk_size_gb\" {\n  description = \"size of the OS disk to attach to the nodes\"\n}\nvariable \"vnet_subnet_id\" {\n  description = \"vnet id where the nodes will be deployed\"\n}\nvariable \"max_pods\" {\n  description = \"maximum number of pods that can run on a single node\"\n}\n\n#Network Profile config\nvariable \"network_plugin\" {\n  description = \"network plugin for kubenretes network overlay (azure or calico)\"\n  default     = \"azure\"\n}\nvariable \"service_cidr\" {\n  description = \"kubernetes internal service cidr range\"\n  default     = \"10.0.0.0\/16\"\n}\nvariable \"diagnostics_workspace_id\" {\n  description = \"log analytics workspace id for cluster audit\"\n}\nvariable \"min_count\" {\n  default     = 1\n  description = \"Minimum Node Count\"\n}\nvariable \"max_count\" {\n  default     = 5\n  description = \"Maximum Node Count\"\n}\nvariable \"default_pool_name\" {\n  description = \"name for the agent pool profile\"\n  default     = \"default\"\n}\nvariable \"default_pool_type\" {\n  description = \"type of the agent pool (AvailabilitySet and VirtualMachineScaleSets)\"\n  default     = \"VirtualMachineScaleSets\"\n}\nvariable \"client_id\" {  \n}\nvariable \"client_secret\" {\n}<\/code><\/pre>\n\n\n\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\"><strong>Terraform variabels<\/strong><\/h4>\n\n\n\n<p class=\"has-text-color has-background has-very-dark-gray-color has-very-light-gray-background-color\">variable cluster_name {  <br>     description = &#8220;AKS cluster name&#8221;<br>     default     = &#8220;run-it-on-cloud&#8221;<br>}<\/p>\n\n\n\n<p>Input variables serve as parameters for a Terraform module, allowing aspects of the module to be customized without altering the module&#8217;s own source code, and allowing modules to be shared between different configurations.<\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li>Outputs: define the resources outputs<\/li><\/ul>\n\n\n\n<pre title=\"# aks cluster outouts.tf\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">output \"azurerm_kubernetes_cluster_id\" {\n  value = azurerm_kubernetes_cluster.cluster.id\n}\n\noutput \"azurerm_kubernetes_cluster_fqdn\" {\n  value = azurerm_kubernetes_cluster.cluster.fqdn\n}\n\noutput \"azurerm_kubernetes_cluster_node_resource_group\" {\n  value = azurerm_kubernetes_cluster.cluster.node_resource_group\n}<\/code><\/pre>\n\n\n\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\"><strong>Terraform output<\/strong><\/h4>\n\n\n\n<p class=\"has-text-color has-background has-very-dark-gray-color has-very-light-gray-background-color\">output &#8220;azurerm_kubernetes_cluster_id&#8221; {<br>   value = azurerm_kubernetes_cluster.cluster.id<br>}<\/p>\n\n\n\n<p>Output values are like the return values of a Terraform module.<\/p>\n\n\n\n<p>Well, we have discovered what\u2019s the main components of a Terraform module. Now, is a good time to call this function -module- in the root deployment, as well as all the other Terraform modules that define the AKS cluster<\/p>\n\n\n\n<pre title=\"# deployment root module\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\"># Cluster Resource Group\nresource \"azurerm_resource_group\" \"aks\" {\n  name     = var.resource_group_name\n  location = var.location\n}\n\n# AKS Cluster Network\nmodule \"aks_network\" {\n  source              = \"..\/modules\/aks_network\"\n  subnet_name         = var.subnet_name\n  vnet_name           = var.vnet_name\n  resource_group_name = azurerm_resource_group.aks.name\n  subnet_cidr         = var.subnet_cidr\n  location            = var.location\n  address_space       = var.address_space\n}\n\n# AKS IDs\nmodule \"aks_identities\" {\n  source       = \"..\/modules\/aks_identities\"\n  cluster_name = var.cluster_name\n}\n\n# AKS Log Analytics\nmodule \"log_analytics\" {\n  source                           = \"..\/modules\/log_analytics\"\n  resource_group_name              = azurerm_resource_group.aks.name\n  log_analytics_workspace_location = var.log_analytics_workspace_location\n  log_analytics_workspace_name     = var.log_analytics_workspace_name\n  log_analytics_workspace_sku      = var.log_analytics_workspace_sku\n}\n\n# AKS Cluster\nmodule \"aks_cluster\" {\n  source                   = \"..\/modules\/aks-cluster\"\n  cluster_name             = var.cluster_name\n  location                 = var.location\n  dns_prefix               = var.dns_prefix\n  resource_group_name      = azurerm_resource_group.aks.name\n  kubernetes_version       = var.kubernetes_version\n  node_count               = var.node_count\n  min_count                = var.min_count\n  max_count                = var.max_count\n  os_disk_size_gb          = \"1028\"\n  max_pods                 = \"110\"\n  vm_size                  = var.vm_size\n  vnet_subnet_id           = module.aks_network.aks_subnet_id\n  client_id                = module.aks_identities.cluster_client_id\n  client_secret            = module.aks_identities.cluster_sp_secret\n  diagnostics_workspace_id = module.log_analytics.azurerm_log_analytics_workspace\n}<\/code><\/pre>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\"><div class=\"wp-block-group__inner-container\"><\/div><\/div>\n\n\n\n<h3 class=\"has-very-dark-gray-color has-text-color wp-block-heading\"> Define the cluster deployment<\/h3>\n\n\n\n<p><br>&#8211; As you can see, we start building  the cluster by defining a cluster resource group. You can learn more about Azure resource group<span style=\"text-decoration: underline;\"> <a aria-label=\"here (opens in a new tab)\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-resource-manager\/resource-group-overview#resource-groups\" target=\"_blank\">here<\/a><\/span>.<br>&#8211; Next, we create the AKS Cluster Network by create the cluster Vnet and subnet using the TF network module already defined in the modules. <br>&#8211; The next block is for the AKS IDs. learn more about Azure SPs <a aria-label=\"here\n- (opens in a new tab)\" rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/develop\/app-objects-and-service-principals\" target=\"_blank\"><span style=\"text-decoration: underline;\">here<\/span><br><\/a>&#8211; Now everything is ready to create the AKS cluster.<br>&#8211; The last section of this deployment consists of logs and the cluster health checks <\/p>\n<\/div><\/div>\n\n\n\n<p>The root module -deployment- contains also tow other Terraform files:<br><\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li><strong><code>provider<\/code><\/strong><code>.<\/code><strong><code>tf<\/code><\/strong>: While&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/resources.html\"><span style=\"text-decoration: underline;\">r<\/span><\/a><span style=\"text-decoration: underline;\"><a rel=\"noreferrer noopener\" aria-label=\"esources (opens in a new tab)\" href=\"https:\/\/www.terraform.io\/docs\/configuration\/resources.html\" target=\"_blank\">esources<\/a><\/span>&nbsp;are the primary construct in the Terraform language, the&nbsp;<em>behaviors<\/em>&nbsp;of resources rely on their associated resource types, and these types are defined by&nbsp;<em>providers<\/em>.<br>Learn more about Terraform provider <a href=\"https:\/\/www.terraform.io\/docs\/configuration\/providers.html\"><span style=\"text-decoration: underline;\">h<\/span><\/a><span style=\"text-decoration: underline;\"><a rel=\"noreferrer noopener\" aria-label=\"ere (opens in a new tab)\" href=\"https:\/\/www.terraform.io\/docs\/configuration\/providers.html\" target=\"_blank\">ere<\/a><\/span><br>In the next section will discuss the project provider configuration.<\/li><\/ul>\n\n\n\n<pre title=\"# tf providers\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">terraform {\n  backend \"azurerm\" {}\n}\n\nprovider \"azurerm\" {\n  version = \"~> 2.4\"\n  features {}\n}<\/code><\/pre>\n\n\n\n<p>A provider configuration is created using a&nbsp;<code>provider<\/code>&nbsp;block:<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-dark-gray-color has-very-light-gray-background-color\">provider &#8220;azurerm&#8221; {<br>   version = &#8220;~&gt;2.4&#8221;<br>}<\/p>\n\n\n\n<p>The name given in the block header (<code>azurem Cloud provider)<\/code> is the name of the provider to configure. Terraform associates each resource type with a provider by taking the first word of the resource type name<\/p>\n\n\n\n<p>Each time a new provider is added to configuration &#8212; either explicitly via a&nbsp;<code>provider<\/code>&nbsp;block or by adding a resource from that provider &#8212; Terraform must initialize the provider before it can be used. Initialization downloads and installs the provider&#8217;s plugin so that it can later be executed.<\/p>\n\n\n\n<h4 class=\"has-vivid-purple-color has-text-color wp-block-heading\"><strong>Initialization<\/strong><\/h4>\n\n\n\n<p>Provider initialization is one of the actions of&nbsp;<code>terraform init<\/code>. <br>Running this command will download and initialize any providers that are not already initialized.<\/p>\n\n\n\n\n<pre class=\"terminal\"><code><br>terraform init<br><\/code><\/pre>\n\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"787\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-init-1024x787.png\" alt=\"Terraform init to create AKS cluster \" class=\"wp-image-186\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-init.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-init.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-init.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-init.png 1286w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>Terraform init<\/figcaption><\/figure><\/div>\n\n\n\n<p>A Terraform backend storage (<code> terraform state<\/code> ) is create using a terraform black:<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-dark-gray-color has-very-light-gray-background-color\">terraform { <br>  backend &#8220;azurerm&#8221; {}<br>}<\/p>\n\n\n\n<p>In the second part of this lab will set up Azure storage to store Terraform state.<\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li><strong>version.tf<\/strong>: The&nbsp;<code>required_version<\/code>&nbsp;setting can be used to constrain which versions of the Terraform CLI can be used with your configuration.<br><strong>Note<\/strong>: that all the lab code are written for <code>Terraform 0.12.x.<\/code><\/li><\/ul>\n\n\n\n<p>Once you\u2019ve declared all your resources, defined your necessary variables and provided your credentials, you\u2019re all set to let Terraform do its magic! To check if everything will work and there\u2019s no errors, run&nbsp;<code>terraform validate<\/code> and <code>terraform plan<\/code>&nbsp;from within the directory. <br>If all is well and you\u2019re happy with what it plans to build, kick off the process with&nbsp;<code>terraform apply<\/code>, one final approval, then wait for your infrastructure to be deployed \ud83d\ude42 <\/p>\n\n\n\n<p>Are you still exited to run your Kubernetes cluster on Cloud ? \ud83d\ude2c&nbsp;<br>So,  let Terraform do its magic!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"949\" height=\"500\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-apply-1.jpg\" alt=\"Terraform apply AKS deploy\" class=\"wp-image-175\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-apply-1.jpg 949w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-apply-1.jpg 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-apply-1.jpg 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>terraform magic<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Set up Azure storage to store Terraform state<\/h2>\n\n\n\n<p>Terraform tracks state locally via the&nbsp;<code>terraform.tfstate<\/code>&nbsp;file. <br>This pattern works well in a single-person environment. <br>However, in a multi-person environment,<span style=\"text-decoration: underline;\">&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/storage\/\">A<\/a><a rel=\"noreferrer noopener\" aria-label=\"zure storage (opens in a new tab)\" href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/storage\/\" target=\"_blank\">zure storage<\/a>&nbsp;<\/span>is used to track the <code>tf state<\/code>.<\/p>\n\n\n\n<p>In this section, we will see how to do the following tasks:<\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li>Retrieve storage account information (account name and account key)<\/li><li>Create a storage container into which Terraform state information will be stored.<\/li><\/ul>\n\n\n\n<ol class=\"ul-black wp-block-list\"><li>In the Azure portal, select&nbsp;<code>All services&nbsp;<\/code>in the left menu.<\/li><li>Select&nbsp;<code>Storage accounts<\/code>.<\/li><li>On the&nbsp;<code>Storage accounts&nbsp;<\/code>tab, select the name of the storage account into which Terraform is to store state. For example, you can use the storage account created when you opened Cloud Shell the first time. The storage account name created by Cloud Shell typically starts with&nbsp;<code>cs<\/code>&nbsp;followed by a random string of numbers and letters. Take note of the storage account you select. This value is needed later.<\/li><li>On the storage account tab, select&nbsp;<code>Access keys.<\/code><\/li><li>Make note of the<code>&nbsp;key1&nbsp;key<\/code>&nbsp;value. (Selecting the icon to the right of the key copies the value to the clipboard.)<\/li><\/ol>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"478\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05-1024x478.png\" alt=\"Terraform state blob storage to create AKS cluster using Terraform\" class=\"wp-image-161\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05.png 1430w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.49.05.png 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>Azure cloud blob storage<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"361\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49-1024x361.png\" alt=\"terraform state keys\" class=\"wp-image-162\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49.png 1420w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-23-at-21.50.49.png 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>Azure storage key<\/figcaption><\/figure><\/div>\n\n\n\n<p>Using your terminal, create a container in your Azure storage account. Replace the placeholders with appropriate values for your environment.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">az storage container create -n tfstate --account-name  &lt;YourAzureStorageAccountName> --account-key  \\&lt;YourAzureStorageAccountKey><\/code><\/pre>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Create AKS using Terraform<\/h2>\n\n\n\n<p>In this section, you see how to use the&nbsp;<code>terraform init<\/code>&nbsp;command to create the resources defined the configuration files you created in the previous sections.<\/p>\n\n\n\n<p>1. In your local terminal, initialize Terraform. Replace the placeholders with appropriate values for your environment<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">cd src\/deployment\nterraform init -backend-config=\"storage_account_name=&lt;YourAzureStorageAccountName>\" -backend-config=\"container_name=tfstate\" -backend-config=\"access_key=&lt;YourStorageAccountAccessKey>\" -backend-config=\"key=codelab.microsoft.tfstate\"<\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>terraform init<\/code>&nbsp;command displays the success of initializing the backend and provider plug-in:<\/p>\n\n\n\n<p>2. Export your service principal credentials. Replace the placeholders with appropriate values from your service principal<\/p>\n\n\n\n\n<pre class=\"terminal\"><code><br>export TF_VAR_client_id=&lt;service-principal-appid> <br><\/code><\/pre>\n\n\n\n\n\n<pre class=\"terminal\"><code><br>export TF_VAR_client_secret=&lt;service-principal-password> <br><\/code><\/pre>\n\n\n\n\n<p>3. Run the&nbsp;<code>terraform plan<\/code>&nbsp;command to create the Terraform plan that defines the infrastructure elements.<\/p>\n\n\n\n\n<pre class=\"terminal\"><code><br>terraform plan -out out.plan<br><\/code><\/pre>\n\n\n\n\n<p>The&nbsp;<code>terraform plan<\/code>&nbsp;command displays the resources that will be created when you run the&nbsp;<code>terraform apply<\/code>&nbsp;command.<br>There\u2019s an Terraform plan output example:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"1024\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan-811x1024.png\" alt=\"Terraform plan AKS deployment \" class=\"wp-image-187\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 811w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 238w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 1217w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 1420w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/tf-plan.png 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>Terraform plan<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"870\" height=\"1024\" src=\"http:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04-870x1024.png\" alt=\"Terraform plan of create AKS cluster using Terraform\" class=\"wp-image-188\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04.png 870w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04.png 255w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04.png 1306w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-24-at-00.17.04.png 1530w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>Terraform plan output<\/figcaption><\/figure><\/div>\n\n\n\n<p>4. Run the&nbsp;<code>terraform apply<\/code>&nbsp;command to apply the plan to create the Kubernetes cluster. The process to create a Kubernetes cluster can take several minutes.<\/p>\n\n\n\n\n<pre class=\"terminal\"><code><br>terraform apply out.plan<br><\/code><\/pre>\n\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"966\" src=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44-1024x966.png\" alt=\"\" class=\"wp-image-805\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 1536w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 1602w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.51.44.png 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>tf apply example<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"417\" src=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11-1024x417.png\" alt=\"\" class=\"wp-image-806\" srcset=\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 1024w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 300w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 768w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 1536w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 2048w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 1280w, https:\/\/aymen-segni.com\/wp-content\/uploads\/2020\/07\/Screenshot-2020-07-23-at-01.54.11.png 1920w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><figcaption>AKS Cluster created on Azure portal<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Test the Kubernetes AKS cluster<\/h2>\n\n\n\n<p>To manage a Kubernetes cluster, you use\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/user-guide\/kubectl\/\">kubectl<\/a>, the Kubernetes command-line client. If you use Azure Cloud Shell,\u00a0<code>kubectl<\/code>\u00a0is already installed. To install\u00a0<code>kubectl<\/code>\u00a0locally, use the\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/cli\/azure\/aks?view=azure-cli-latest#az-aks-install-cli\">az aks install-cli<\/a>\u00a0command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">az aks install-cli<\/code><\/pre>\n\n\n\n<p>To configure\u00a0<code>kubectl<\/code>\u00a0to connect to your Kubernetes cluster, use the\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/cli\/azure\/aks?view=azure-cli-latest#az-aks-get-credentials\">az aks get-credentials<\/a>\u00a0command. This command downloads credentials and configures the Kubernetes CLI to use them. (make sure to use your own created resource group and AKS names)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">az aks get-credentials --resource-group runitoncloud --name runItOnCloud<\/code><\/pre>\n\n\n\n<p>To verify the connection to your cluster, use the\u00a0<a href=\"https:\/\/kubernetes.io\/docs\/reference\/generated\/kubectl\/kubectl-commands#get\">kubectl get<\/a>\u00a0command to return a list of the cluster nodes.<\/p>\n\n\n\n<p>You should see the details of your worker nodes, and they should all have a status&nbsp;<strong>Ready<\/strong>, as shown in the following example:<\/p>\n\n\n\n<pre title=\"#  list of the cluster nodes\" class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">|~\/run-it-on-cloud\/azure-aks-k8s-tf\/src\/deployment \ud83d\udcbb --\u2446 master \ud83d\udd27 \n|\n|--\u2af8  kubectl get nodes                                                                                                                  \nNAME                              STATUS   ROLES   AGE   VERSION\naks-default-17028763-vmss000000   Ready    agent   16m   v1.16.10\naks-default-17028763-vmss000001   Ready    agent   16m   v1.16.10<\/code><\/pre>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\" id=\"monitor-health-and-logs\">Monitor health and logs<\/h2>\n\n\n\n<p>When the AKS cluster was created, monitoring was enabled to capture health metrics for both the cluster nodes and pods. These health metrics are available in the Azure portal. For more information on container health monitoring, see&nbsp;<span style=\"text-decoration: underline;\"><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-monitor\/insights\/container-insights-overview\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Monitor Azure Kubernetes Service healt (opens in a new tab)\">Monitor Azure Kubernetes Service healt<\/a><\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-monitor\/insights\/container-insights-overview\"><span style=\"text-decoration: underline;\">h<\/span><\/a>.<\/p>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\">Next steps<\/h2>\n\n\n\n<p>If you make changes to your code, running the&nbsp;<code>plan<\/code>&nbsp;and&nbsp;<code>apply<\/code>&nbsp;commands again will let Terraform use its knowledge of the deployed resources <code>(.tfstate)<\/code> to calculate what changes need to be made, whether building or destroying. Finally, when you want to bring down your infrastructure, simply issue a&nbsp;<code>terraform&nbsp;destroy<\/code> command and down it comes.<\/p>\n\n\n\n<p>The setup described is only the beginning, if you&#8217;re provisioning production-grade infrastructure you should look into:<\/p>\n\n\n\n<ul class=\"ul-black wp-block-list\"><li>how to structure your Terraform in global and environment-specific layers<\/li><li>managing Terraform state and how to work with the rest of your team<\/li><\/ul>\n\n\n\n<h2 class=\"has-vivid-cyan-blue-color has-text-color wp-block-heading\" id=\"that-s-all-folks-\">That&#8217;s all folks!<\/h2>\n\n\n\n<p>That\u2019s all for this lab, thanks for reading! Later posts may cover how to <a href=\"https:\/\/aymen-segni.com\/index.php\/2020\/01\/03\/secure-aks-at-the-deployment-part-1\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"secure your AKS deployment (opens in a new tab)\"><span style=\"text-decoration: underline;\">secure your AKS deployment<\/span><\/a>, as well as a fully configured cluster with hundreds of microservices deployed in one click!<\/p>\n\n\n\n<p>Be the first to be notified when a new article, running it on Cloud or Kubernetes experiment is published.<br>Don&#8217;t miss the next article!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster<\/p>\n","protected":false},"author":1,"featured_media":93,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9,8,10],"tags":[11,6,2],"class_list":["post-61","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud","category-devops","category-kubernetes","tag-azure","tag-devops","tag-kubernetes"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create a Kubernetes cluster with Azure AKS using Terraform<\/title>\n<meta name=\"description\" content=\"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create a Kubernetes cluster with Azure AKS using Terraform\" \/>\n<meta property=\"og:description\" content=\"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster\" \/>\n<meta property=\"og:url\" content=\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\" \/>\n<meta property=\"og:site_name\" content=\"Run It On Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-23T23:22:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-07-23T00:10:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/terraform-azure-1.png?fit=2048%2C1024&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"2048\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"aymen-segni\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/x.com\/axsegni\" \/>\n<meta name=\"twitter:site\" content=\"@axsegni\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"aymen-segni\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\"},\"author\":{\"name\":\"aymen-segni\",\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d\"},\"headline\":\"Create a Kubernetes cluster with Azure AKS using Terraform\",\"datePublished\":\"2019-12-23T23:22:39+00:00\",\"dateModified\":\"2020-07-23T00:10:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\"},\"wordCount\":2182,\"commentCount\":17,\"publisher\":{\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d\"},\"keywords\":[\"Azure\",\"devops\",\"kubernetes\"],\"articleSection\":[\"Cloud\",\"Devops\",\"Kubernetes\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\",\"url\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\",\"name\":\"Create a Kubernetes cluster with Azure AKS using Terraform\",\"isPartOf\":{\"@id\":\"https:\/\/aymen-segni.com\/#website\"},\"datePublished\":\"2019-12-23T23:22:39+00:00\",\"dateModified\":\"2020-07-23T00:10:17+00:00\",\"description\":\"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster\",\"breadcrumb\":{\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/aymen-segni.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create a Kubernetes cluster with Azure AKS using Terraform\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/aymen-segni.com\/#website\",\"url\":\"https:\/\/aymen-segni.com\/\",\"name\":\"Run It On Cloud\",\"description\":\"Accelerate your Cloud &amp; MLOps Journey\",\"publisher\":{\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/aymen-segni.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d\",\"name\":\"aymen-segni\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2025\/02\/72799.jpg\",\"contentUrl\":\"https:\/\/aymen-segni.com\/wp-content\/uploads\/2025\/02\/72799.jpg\",\"width\":896,\"height\":1152,\"caption\":\"aymen-segni\"},\"logo\":{\"@id\":\"https:\/\/aymen-segni.com\/#\/schema\/person\/image\/\"},\"description\":\"Staff Engineer with over a decade of experience in building, scaling, and leading MLOPS, Cloud Native, SRE, and DevOps platforms across high-growth and enterprise environments. I specialize in architecting production-grade systems with a strong emphasis on resilience, security, and developer experience; bringing together deep expertise in distributed systems, Kubernetes, and modern platform engineering to empower engineering teams and accelerate business value. My work spans Cloud (AWS, GCP, Azure, OpenStack), Kubernetes, SRE (SLOs, observability, incident response), AI infrastructure and AgentOps (vLLM, Nvidia, RayServe, etc), and Platform Engineering (Backstage, Keptn, GitOps, self-service). I\u2019ve led teams through Cloud Native transformations, established scalable SRE practices, and built internal platforms that streamline operations and reduce cognitive load. With a strong programming background, and Infrastructure as Code (Terraform, Helm, Ansible), I drive automation-first approaches to eliminate toil, ensure reliability, and enable secure, compliant deployment pipelines. My focus today is on building Cloud Native AI platforms, where DevOps meets AI Infrastructure Stacks to support scalable, production-ready LLMs and AI Platforms. As a dedicated mentor, both within my teams and through platforms like MentorCruise, I am passionate about helping engineers perform at their best and assisting organizations in scaling with confidence. Driven by systems thinking, platform-as-a-product mindset, and engineering excellence, I help teams ship faster, operate smarter, and scale with confidence.\",\"sameAs\":[\"https:\/\/aymen-segni.com\",\"https:\/\/www.linkedin.com\/in\/aymen-segni\",\"https:\/\/twitter.com\/https:\/\/x.com\/axsegni\"],\"url\":\"https:\/\/aymen-segni.com\/index.php\/author\/admin8647\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Create a Kubernetes cluster with Azure AKS using Terraform","description":"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/","og_locale":"en_US","og_type":"article","og_title":"Create a Kubernetes cluster with Azure AKS using Terraform","og_description":"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster","og_url":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/","og_site_name":"Run It On Cloud","article_published_time":"2019-12-23T23:22:39+00:00","article_modified_time":"2020-07-23T00:10:17+00:00","og_image":[{"width":2048,"height":1024,"url":"https:\/\/i0.wp.com\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/terraform-azure-1.png?fit=2048%2C1024&ssl=1","type":"image\/png"}],"author":"aymen-segni","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/x.com\/axsegni","twitter_site":"@axsegni","twitter_misc":{"Written by":"aymen-segni","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#article","isPartOf":{"@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/"},"author":{"name":"aymen-segni","@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d"},"headline":"Create a Kubernetes cluster with Azure AKS using Terraform","datePublished":"2019-12-23T23:22:39+00:00","dateModified":"2020-07-23T00:10:17+00:00","mainEntityOfPage":{"@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/"},"wordCount":2182,"commentCount":17,"publisher":{"@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d"},"keywords":["Azure","devops","kubernetes"],"articleSection":["Cloud","Devops","Kubernetes"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/","url":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/","name":"Create a Kubernetes cluster with Azure AKS using Terraform","isPartOf":{"@id":"https:\/\/aymen-segni.com\/#website"},"datePublished":"2019-12-23T23:22:39+00:00","dateModified":"2020-07-23T00:10:17+00:00","description":"\u2705Learn HCL and Terraform best practices by doing \u2705Use Terraform and AKS to create a Kubernetes cluster \u2705Use kubectl to test the availability of K8S cluster","breadcrumb":{"@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/aymen-segni.com\/index.php\/2019\/12\/24\/create-a-kubernetes-cluster-with-azure-aks-using-terraform\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/aymen-segni.com\/"},{"@type":"ListItem","position":2,"name":"Create a Kubernetes cluster with Azure AKS using Terraform"}]},{"@type":"WebSite","@id":"https:\/\/aymen-segni.com\/#website","url":"https:\/\/aymen-segni.com\/","name":"Run It On Cloud","description":"Accelerate your Cloud &amp; MLOps Journey","publisher":{"@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/aymen-segni.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/32033966e7bd410bbaf1b79c7e94b59d","name":"aymen-segni","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/image\/","url":"https:\/\/aymen-segni.com\/wp-content\/uploads\/2025\/02\/72799.jpg","contentUrl":"https:\/\/aymen-segni.com\/wp-content\/uploads\/2025\/02\/72799.jpg","width":896,"height":1152,"caption":"aymen-segni"},"logo":{"@id":"https:\/\/aymen-segni.com\/#\/schema\/person\/image\/"},"description":"Staff Engineer with over a decade of experience in building, scaling, and leading MLOPS, Cloud Native, SRE, and DevOps platforms across high-growth and enterprise environments. I specialize in architecting production-grade systems with a strong emphasis on resilience, security, and developer experience; bringing together deep expertise in distributed systems, Kubernetes, and modern platform engineering to empower engineering teams and accelerate business value. My work spans Cloud (AWS, GCP, Azure, OpenStack), Kubernetes, SRE (SLOs, observability, incident response), AI infrastructure and AgentOps (vLLM, Nvidia, RayServe, etc), and Platform Engineering (Backstage, Keptn, GitOps, self-service). I\u2019ve led teams through Cloud Native transformations, established scalable SRE practices, and built internal platforms that streamline operations and reduce cognitive load. With a strong programming background, and Infrastructure as Code (Terraform, Helm, Ansible), I drive automation-first approaches to eliminate toil, ensure reliability, and enable secure, compliant deployment pipelines. My focus today is on building Cloud Native AI platforms, where DevOps meets AI Infrastructure Stacks to support scalable, production-ready LLMs and AI Platforms. As a dedicated mentor, both within my teams and through platforms like MentorCruise, I am passionate about helping engineers perform at their best and assisting organizations in scaling with confidence. Driven by systems thinking, platform-as-a-product mindset, and engineering excellence, I help teams ship faster, operate smarter, and scale with confidence.","sameAs":["https:\/\/aymen-segni.com","https:\/\/www.linkedin.com\/in\/aymen-segni","https:\/\/twitter.com\/https:\/\/x.com\/axsegni"],"url":"https:\/\/aymen-segni.com\/index.php\/author\/admin8647\/"}]}},"jetpack_featured_media_url":"https:\/\/aymen-segni.com\/wp-content\/uploads\/2019\/12\/terraform-azure-1.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":122,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"predecessor-version":[{"id":906,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/posts\/61\/revisions\/906"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/media\/93"}],"wp:attachment":[{"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aymen-segni.com\/index.php\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}