Table of Contents
- Terraform
- Install terraform
- Create a new folder for infrastructure
- Create variables and outputs
- Add the following code to main.tf
- Create dev.tfvars
- Upgrade terraform
- Plan terraform with tfvars file
- Apply terraform with tfvars file with auto approve
- Destroy terraform with tfvars file with auto approve
- Conclusion
Terraform
Terraform is an open-source infrastructure as code software tool created by HashiCorp. It enables users to define and provision a datacenter infrastructure using a high-level configuration language known as Hashicorp Configuration Language (HCL), or optionally JSON. Terraform supports a number of cloud infrastructure providers such as Amazon Web Services Google Cloud Platform, Linode, Microsoft Azure, Oracle Cloud Infrastructure, Hetzner or VMware vSphere as well as OpenStack.
Install terraform
Download and install terraform from here.
Create a new folder for infrastructure
mkdir infrastructure
cd infrastructure
We will create all the terraform files in this folder. this will be only for infrastructure.
Create main.tf
new-item main.tf
This is where we will create all the resources.
create variables.tf
new-item variables.tf
This is where we will create all the variables. We will use these variables in main.tf file.
Create dev.tfvars
new-item dev.tfvars
This is where we will create all the variables values. We will use these variables values in main.tf file. This file will not be checked in to source control. You can add this file to .gitignore file. you can also use this file to override the variables values. you can create multiple tfvars files for different environments.
Create output.tf
new-item output.tf
This is where we will create all the outputs. We will use these outputs in main.tf file.
Create configs folder
mkdir configs
This is where we will create all the kube config files. We will use these kube config files to connect to AKS cluster.
Create variables and outputs
Add the following code to variables.tf
variable "location" {
default = "westeurope"
description = "The Azure Region in which all resources should be created."
type = string
}
variable "resource_group_tags" {
default = {
environment = "dev",
project = "projectname"
}
description = "A map of tags to add to all resources for this environment."
type = map(string)
validation {
condition = length(keys(var.resource_group_tags)) == 2
error_message = "The resource_group_tags map must contain exactly two elements."
}
validation {
condition = contains(keys(var.resource_group_tags), "environment")
error_message = "The resource_group_tags map must contain a key named \"environment\"."
}
validation {
condition = contains(keys(var.resource_group_tags), "project")
error_message = "The resource_group_tags map must contain a key named \"project\"."
}
}
Add the following code to output.tf
output "resource_group_id" {
value = azurerm_resource_group.rg.id
}
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "resource_group_location" {
value = azurerm_resource_group.rg.location
}
output "resource_group_tags" {
value = azurerm_resource_group.rg.tags
}
output "acr_id" {
value = azurerm_container_registry.acr.id
}
output "acr_name" {
value = azurerm_container_registry.acr.name
}
output "acr_login_server" {
value = azurerm_container_registry.acr.login_server
}
output "acr_admin_username" {
value = azurerm_container_registry.acr.admin_username
}
output "acr_admin_password" {
value = azurerm_container_registry.acr.admin_password
sensitive = true
}
output "aks_id" {
value = azurerm_kubernetes_cluster.aks.id
}
output "aks_name" {
value = azurerm_kubernetes_cluster.aks.name
}
output "aks_location" {
value = azurerm_kubernetes_cluster.aks.location
}
output "aks_node_resource_group" {
value = azurerm_kubernetes_cluster.aks.node_resource_group
}
output "aks_dns_prefix" {
value = azurerm_kubernetes_cluster.aks.dns_prefix
}
output "aks_kube_admin_config" {
value = azurerm_kubernetes_cluster.aks.kube_admin_config_raw
sensitive = true
}
output "aks_kube_config" {
value = azurerm_kubernetes_cluster.aks.kube_config_raw
sensitive = true
}
output "aks_identity" {
value = azurerm_kubernetes_cluster.aks.identity
}
Add the following code to main.tf
# Configure the Azure provider
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0.2"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.0.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0.0"
}
local = {
source = "hashicorp/local"
version = "~> 2.0.0"
}
}
required_version = ">= 1.1.0"
}
provider "azurerm" {
features {}
}
locals {
name_suffix = "${var.resource_group_tags["project"]}-${var.resource_group_tags["environment"]}"
}
resource "azurerm_resource_group" "rg" {
name = "${local.name_suffix}-rg"
location = var.location
tags = var.resource_group_tags
}
// create acr
resource "azurerm_container_registry" "acr" {
name = "${replace(local.name_suffix, "-", "")}acr"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
sku = "Basic"
admin_enabled = true
tags = var.resource_group_tags
}
provider "kubernetes" {
host = azurerm_kubernetes_cluster.aks.kube_config.0.host
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
}
provider "local" {
}
resource "local_file" "kube_config" {
filename = "${path.module}/configs/${local.name_suffix}.config"
content = <<EOT
${azurerm_kubernetes_cluster.aks.kube_config_raw}
EOT
}
// attach acr to aks
resource "azurerm_role_assignment" "aks_acr_role_assignment" {
depends_on = [azurerm_kubernetes_cluster.aks]
scope = azurerm_container_registry.acr.id
role_definition_name = "AcrPull"
principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
}
Create dev.tfvars
location = "westeurope"
resource_group_tags = {
environment = "dev"
project = "projectname"
}
Upgrade terraform
terraform init -upgrade
This will upgrade the terraform to latest version and download the latest provider. This will also update the lock file.
Note: terraform use azure cli to authenticate to azure. Make sure you have azure cli installed and logged in to azure.
Plan terraform with tfvars file
terraform plan -var-file="dev.tfvars"
Always plan before applying terraform. This will show you what resources will be created. This will also show you if there are any errors. This will not create any resources so it is safe to run this command.
Apply terraform with tfvars file with auto approve
terraform apply -var-file="dev.tfvars" -auto-approve
This will create all the resources. This will also create a kube config file in configs folder. This file will be used to connect to AKS cluster.
Destroy terraform with tfvars file with auto approve
terraform destroy -var-file="dev.tfvars" -auto-approve
This will destroy all the resources. I recommend you create and destroy the resources few times to and get familiar with terraform.
Conclusion
If you are new to terraform I recommend you to go through the official documentation. This will give you a good understanding of terraform. In the next post we prepare the aks cluster for deployment.
Related Posts
Build, Version and Publish .Net Application to ACR using GitHub Actions
In this article, we will see how to build, version and publish .Net application to Azure Container Registry (ACR) using GitHub Actions.
Cloudflare DNS for AKS Cluster with Terraform
In this we will setup Cloudflare DNS for AKS Cluster with Terraform
Cert Manager and Nginx Ingress Controller on AKS Cluster with static IP
In this we will setup Cert Manager and Nginx Ingress Controller on AKS Cluster