Creating Azure Kubernetes Service using Terraform
Being tasked to have an environment that can orchestrate my containers in my development subscription, I have decided to spin up an Azure Kubernetes Service (AKS) using Terraform to this subscription from my macOS terminal and get it up and running as soon as possible.
Why did I choose Terraform instead of using the Azure Portal? It is because I will need to repeat the same deployment in production subscription later. And it can also ensure the configuration state of the resources are validated and managed.
Therefore in this blog post, I am sharing my adventure on deploying Azure Kubernetes Service (AKS) using Terraform with the community in this step by step walkthrough below.
Create an Azure Kubernetes Service (AKS) Service Principal account
Before you start, you will need have a Service Principal account for this deployment. The Service Principal account need to be a Contributor role so that Kubernetes can create the Azure Load Balancer for the network.
You can create the Service Principal account using
az ad sp
command with
AzCLI or
New-AzADServicePrincipal
command with PowerShell. Once created, copy the AppId and Password values, and
input them as the client_id
and client_secret
default values in
variables.tf
Terraform file.
For more knowledge on how to create a Service Principal account, below are some useful links:
- Creating password-based ServicePrincipal using CLI with ease
- Microsoft Docs - Create an Azure service principal with Azure CLI
- Microsoft Docs - Create an Azure service principal with Azure PowerShell
↑Top
Create an Azure Storage Account for Terraform tfstate file
Although the Terraform state is generated and stored by default in a local file
named terraform.tfstate
, but it can also be stored remotely, which works
better in a team environment where your team members share access to the state
and modify Azure Kubenetes Service (AKS) configuration.
To create an Azure Storage Account for storing the *.tfstate
file, you can
learn on how to do that from this blog post below:
↑Top
Creating Terraform files to plan the Azure Kubernetes Service resources deployment
Let us start on how to create Azure Kubernetes Service (AKS) using Terraform.
↑Top
Create a main.tf Terraform file
Firsly, we will create a main.tf
file to contain the following Terraform
script language to define the provider and backend configuration.
1
2
3
4
5
6
7
provider "azurerm" {
version = "~>1.5"
}
terraform {
backend "azurerm" {}
}
↑Top
Create a variables.tf Terraform file
Next, you will have to create a variables.tf
file to store configurable
variable values.
Remember that you created an AKS Service Principal account previously? Now, you
will need to replace the default
value
“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
” for client_id
and client_secret
variables with the previously created AKS Service Principal AppID
and
Password
values.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# AKS Service Principal AppId
variable "client_id" {
default = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
# AKS Service Principal Password
variable "client_secret" {
default = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
variable "agent_count" {
default = 3
}
variable "ssh_public_key" {
default = "~/.ssh/id_rsa.pub"
}
variable "dns_prefix" {
default = "k8s"
}
variable cluster_name {
default = "cl-k8s"
}
variable resource_group_name {
default = "rg-k8s"
}
variable location {
default = "southeastasia"
}
variable log_analytics_workspace_name {
default = "log-k8s"
}
# refer https://azure.microsoft.com/global-infrastructure/services/?products=monitor for log analytics available regions
variable log_analytics_workspace_location {
default = "southeastasia"
}
# refer https://azure.microsoft.com/pricing/details/monitor/ for log analytics pricing
variable log_analytics_workspace_sku {
default = "PerGB2018"
}
variable tags {
default = {
CostCenter = "000000"
Department = "IT"
Environment = "Development"
Importance = "Low"
Project = "Kubernetes Service Blog Post"
Owner = "kiazhi.github.io"
}
}
↑Top
Create k8s.tf Terraform file
Then, you will need to create a k8s.tf
file where you will define your entire
AKS resources configuration incorporating with those variable values from the
variables.tf
file.
This k8s.tf
file demonstrates a basic AKS deployment for the need of a
project as an example. The deployment contains a resource group, log analytics
workspace, log analytics solution (ContainerInsights) and Azure Kubenetes
Service (AKS) with resource tagging that provides an end to end of the service.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
resource "azurerm_resource_group" "k8s" {
name = var.resource_group_name
location = var.location
tags = var.tags
}
resource "random_id" "log_analytics_workspace_name_suffix" {
byte_length = 8
}
resource "azurerm_log_analytics_workspace" "test" {
# The WorkSpace name has to be unique across the whole of azure, not just the current subscription/tenant.
name = "${var.log_analytics_workspace_name}-${random_id.log_analytics_workspace_name_suffix.dec}"
location = var.log_analytics_workspace_location
resource_group_name = azurerm_resource_group.k8s.name
sku = var.log_analytics_workspace_sku
tags = var.tags
}
resource "azurerm_log_analytics_solution" "test" {
solution_name = "ContainerInsights"
location = azurerm_log_analytics_workspace.test.location
resource_group_name = azurerm_resource_group.k8s.name
workspace_resource_id = azurerm_log_analytics_workspace.test.id
workspace_name = azurerm_log_analytics_workspace.test.name
plan {
publisher = "Microsoft"
product = "OMSGallery/ContainerInsights"
}
}
resource "azurerm_kubernetes_cluster" "k8s" {
name = var.cluster_name
location = azurerm_resource_group.k8s.location
resource_group_name = azurerm_resource_group.k8s.name
dns_prefix = var.dns_prefix
tags = var.tags
linux_profile {
admin_username = "ubuntu"
ssh_key {
key_data = file(var.ssh_public_key)
}
}
default_node_pool {
name = "agentpool"
node_count = var.agent_count
vm_size = "Standard_DS1_v2"
}
service_principal {
client_id = var.client_id
client_secret = var.client_secret
}
addon_profile {
oms_agent {
enabled = true
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
}
}
}
↑Top
Create an output.tf Terraform file
Finally, you can create a output.tf
file comprises of all the Terraform
provisioning outputs that you are interested and get them threw out on the
terminal at the end of the deployment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
output "client_key" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_key
}
output "client_certificate" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate
}
output "cluster_ca_certificate" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate
}
output "cluster_username" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.username
}
output "cluster_password" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.password
}
output "kube_config" {
value = azurerm_kubernetes_cluster.k8s.kube_config_raw
}
output "host" {
value = azurerm_kubernetes_cluster.k8s.kube_config.0.host
}
↑Top
Deploying Azure Kubernetes Service (AKS) to Azure using Terraform
Once those Terraform (*.tf
) files are created, you will need to initialize
the working directory containing those Terraform configuration files using the
terraform init
command.
1
2
3
4
5
terraform init \
-backend-config="storage_account_name=$storage_account_name" \
-backend-config="container_name=$storage_account_container_name" \
-backend-config="access_key=$storage_account_key" \
-backend-config="key=terraform.tfstate"
Next, you will need to use a Service Principal account with Contributor role
which terraform
command can utilise to communicate with Azure and initiate
the deployment. You will need store your Service Principal App ID for
ARM_CLIENT_ID
, Password for ARM_CLIENT_SECRET
, SubscriptionID for
ARM_SUBSCRIPTION_ID
and Tenant Id for ARM_TENANT_ID
environment variables
in your terminal.
1
2
3
4
5
export \
ARM_CLIENT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" \
ARM_CLIENT_SECRET="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" \
ARM_SUBSCRIPTION_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" \
ARM_TENANT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ;
Then, you will use the terrform plan
command to check the execution plan and
generate an output of the generated plan.
1
terraform plan -out out.plan
Finally, you are use terraform apply
command to apply the generated plan
changes to Azure.
1
terraform apply out.plan
Once the command execution completed, you will see the resource group containing the Azure Kurbernetes Service (AKS) and other resources deployed in the Azure Portal.
↑Top
References
- Microsoft Docs - Create a Kubernetes cluster with Azure Kubernetes Service using Terraform
- Terraform Docs - Configuration Language
- Terraform CLI - terraform init
- Terraform CLI - terraform plan
- Terraform CLI - terraform apply
- Getting started with Azure deployment using Terraform
- Creating a centralized secure storage for storing Terraform state
↑Top
Related Books
↑Top