Showing posts with label Terraform. Show all posts
Showing posts with label Terraform. Show all posts

Sunday, 14 August 2022

Kubecost on AKS Part 02

 Hi all, continuing from previous post on part 1, this blog post will focus on enabling kubecost with cloud integration . 


First, do the Azure Cost Management export to a Storage Account 


fill in all the required details especially on the storage account . The report in this storage account alter will be access by kubecost to view in on the kubecost dashboard . 

do note this may takes hours to be populated. 

Step 2 -Create A custom role and assigned a SPN with that custom role to your subscription

# Create kubecost custom role
   resource "azurerm_role_definition" "kubecost" {
   name        = "kubecost_rate_card_query"
   scope       = "/subscriptions/${var.sub-id}"
   description = "kubecost Rate Card query role"
 
  permissions {
    actions     = [
     "Microsoft.Compute/virtualMachines/vmSizes/read",
      "Microsoft.Resources/subscriptions/locations/read",
      "Microsoft.Resources/providers/read",
      "Microsoft.ContainerService/containerServices/read",
      "Microsoft.Commerce/RateCard/read",
    ]
    not_actions = []
  }

  assignable_scopes = [
    "/subscriptions/${var.sub-id}"
  ]
}
#Assign Role to SPN at Subcription level
resource "azurerm_role_assignment" "kubecost" {
  scope                = "/subscriptions/${var.sub-id}"
  role_definition_name = azurerm_role_definition.kubecost.name
  principal_id         = var.spn-id
}

you may also use create this using powershell or az cli, link in the reference

Step 3 - For this one it can divided into two the hard way or the gui way . dont worry i will cover both 

Let get to know the easier way first , hard requiredment is it must be running kubecost version 1.96 which was release few day ago as the blog is drafted. 

Once u deploy the kubecost with just setting up with the kubetoken. Access the kubecost dashboard by port forward to port 9090 and go to the setting. 

scroll until u find this option 


Click update and fill the details 


After click on submit, wait for sometimes and the data on cloud integration to be populated. 

So here come the hard way , all the component in easier method will be converted into line of code start with creating a kubernetes secret containing all the details 

resource "kubernetes_secret" "kubecost_sec" {
  metadata {
    name      = "kubecost-sec"
    namespace = kubernetes_namespace.kubecost.metadata[0].name
  }
  data = {
      "cloud-integration.json" = "\r\n{\r\n    \"azure\": [\r\n        {\r\n          \"azureSubscriptionID\": \"${var.sub-id}\",\r\n          \"azureStorageAccount\": \"${var.saname}\",\r\n          \"azureStorageAccessKey\": \"${var.sakey}\",\r\n          \"azureStorageContainer\": \"${var.sacontainer}\",\r\n          \"azureContainerPath\": \"${var.sapath}\",\r\n          \"azureCloud\": \"${var.azcloud}\"\r\n        }\r\n    ]\r\n}"
   
  }
  type = "Opaque"
}

on the helm value , point the cloud integration value to the secret that been created . 

  set {
    name  = "kubecostProductConfigs.cloudIntegrationSecret"
    value = kubernetes_secret.kubecost_sec.metadata[0].name
  }

Both of the method will get you to have kubecost cloud integration with azure 


now it is all concluded, list of the reference as below 

1. Deploy AKS + Kubecost with Terraform - Code it Yourself... (mendible.com)

2. Azure Config – Kubecost

3. poc-common-configurations/cloud-integration.json at main · kubecost/poc-common-configurations (github.com)

4. Kubernetes secret with json · Issue #1801 · hashicorp/terraform-provider-kubernetes (github.com)

5.Cost governance with Kubecost - Cloud Adoption Framework | Microsoft Docs

6. Kubecost team who has provide a good insight in their slack to the community 

enjoy the learning and thanks for reading, the sample code is available on my github 

Sunday, 19 June 2022

AKS Ingress with Traefik via Terraform

 Hi All, 

continue from my previous post on AKS AGIC addon, you can utilize azure application gateway to do so but if you like kind of open source project , from what i know , there are two option which is traefik and nginx . 

As for this post , i will be explaining on how to deploy traefik in aks by utilizing helm chart for traefik and terraform for easier deployment. 

These are some component and tools involved in this deployment 

1. Azure Kubernetes Service 

2. Service Principle from Azure AD 

3. Traefik helm chart 

4. Terraform 


Let start, At first please make sure u have azure virtual network for AKS to "sit" in or u may deploy a new one 


module "vnet00" {

  source        = "../modules/network/vnet"
  vnet-location = "eastus"
  vnet-rg       = "DEV-VNET-EASTUS"
  vnet-name     = "DEV-VNET-EASTUS"
  vnet-range    = ["172.25.0.0/20"]
  subnets-name  = ["subnet01", "aks-subnet"]
  subnets-range = ["172.25.0.0/24", "172.25.1.0/24"]
}

following with Service Principle 

module "aks-spn" {
source      = "../modules/aad-spn"
spn-name    = "AKSDEV-SPN"
secret-name = "aksdev-spn-secret"

}

we gonna use of reference for this SPN later ... after both of this is deployed, AKS can be deployed referencing to both of the output from this vnet and spn module. 



module "myaks" {
source = "../modules/k8s/dev"
aks-name = "aks01"
aks-dns = "aks01-dns"
aks-version = "1.24.0"
aks-region = "eastus"
aks-subnet-id = module.vnet00.vnet_subnets.1
admin = "adminlogin"
ssh = "ssh-rsa AAAAB3N"
winpass = "P@ssw0rd1234"
client_id = module.aks-spn.client_id
client_sec = module.aks-spn.client_secret
depends_on = [module.aks-spn]
}

then arrive to the main topic of today which is traefik deployment 

module "traefik" {

  source    = "../modules/network/traefik"
  loc       = "eastus"
  aks-rg    = module.myaks.aks-rg.id
  aks-name  = module.myaks.aks-name
  aks-spnid = module.aks-spn.object_id-entapp
  depends_on = [module.myaks]

}

this module will do few thing like creating public ip for traefik and assign permission accordingly . Traefik public ip will be bind to the same load balancer that aks deployed 


permission 

then u may do terraform apply and once completed , you may browse your traefik dashboard by http://<yourtraefikoublicip>:9000/dashbaord nad here is mine



your deployment is completed and u may use traefik as ingress for your app in aks 

Thanks for reading , please leave a comment if you have some doubt and here are some reference that i use to complete traefik deployment 

1. https://stackoverflow.com/questions/69269097/unable-to-pass-service-annotations-when-deploying-helm-chart-via-terraform

2. https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release 

Saturday, 21 May 2022

AKS AGIC addon via Terrafrom

 Hello All, 

my testing has been alot with aks lately  and surely i cannot run away on setting up an ingress controller for all my test application on aks , So i would like to share my journey on setting Appling gateway Ingress controller (AGIC) using aks addon via terraform. 

There are two method on setting AGIC which is via aks addon or helm chart. There are pro and cons for each method but if your Application Gateway just for AKS to be use , using addon will be better. 

More details on the different can be read from here - Microsoft Docs 

I will be using terraform module that i created for this example . 

 Component Involved 

1. Azure Kubernetes Service (AKS)

2. Application Gateway 

3. Service Principle 

4. Azure Virtual Network 


you may download my module to test but we will start as below 

1.  Virtual Network creation 

module "vnet00" {
  source             = "./modules/network/vnet"
  vnet-name       = "vNet-00-aks"
  vnet-range       = ["192.168.16.0/24", "172.16.0.0/22"]
  subnets-name  = ["subnet01", "aks-subnet", "ApplicationGatewaySubnet"]
  subnets-range  = ["192.168.16.0/28", "172.16.0.0/24", "192.168.16.128/26"]
}

2. SPN creation 

module "aks-spn" {
  source             = "./modules/aad-spn"
  spn-name        = "AKSAGIC-SPN"
  secret-name    = "akstfk-spn-secret"
}

3. Application Gateway 

module "appgw01" {
  source               = "./modules/network/appgw"
  agsnetname       = module.vnet00.vnet_subnets_name.2
  agsnetid            = module.vnet00.vnet_subnets.2
  
  depends_on = [module.vnet00]
}

4. AKS 


 module "myaks" {
  source        = "./modules/k8s/dev-appgw"
  aks-name      = "aks01"
  aks-dns       = "aks01-dns"
  aks-version   = "1.23.3"
  aks-subnet-id = module.vnet00.vnet_subnets.1
  admin         = "username"
  ssh           = "ssh-rsa xx"
  winpass       = "password"
  client_id     = module.aks-spn.client_id
  client_sec    = module.aks-spn.client_secret
  aks-spn = module.aks-spn.object_id-entapp
  appgwid = module.appgw01.appgwid
  appgwrg = module.appgw01.appgwrg
  #appgwname = module.appgw01.appgwname
  #appgwnetid =  module.vnet00.vnet_subnets.2
  #appgwnetcidr = xxx
  depends_on = [module.aks-spn,module.appgw01] 
}

Notice there are some line  is commented. this is because u can either use the existing Application gateway as AGIC or You let the AKS create it for you but i choose on the first one. 


Reason for this structure because the same spn will be use in AKS setup and for AGIC which is the read permission on AGIC resource group and contributor to AGIC. 



after all the component has been deployed, you may download the kubeconfig file and test with this command 

1.  kubectl apply -f https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/aspnetapp.yaml

2. Kubectl get ingress 

Then the sample aspnet app details will appear as the setup was done successfully. 


Link to my terraform github repo is here with sample module call  -  
GitHub - munir94/TFLAB

That all for now , im planning to cover traefik and nginx ingress deployment also in future, thanks for reading and you may leave comment for enquiry or improvement . 

Wednesday, 1 December 2021

K8s Dashboard via Terraform

 Hi all,  this post just to share my code and experience on deploying kubernetes dashboard terraform.


 

some component involved in this are : 

1. Terraform 

2. AKS (Azure Kubernetes Service)

3. k2tf 

If anyone did test AKS, it does provide its own view on the cluster information together with all the pod that has been deploy. However, for me there are some view that is missing which the load of each pod received is no there in the portal. It may work if the AKS has sent the log to Log Analytic and the AKS workbook is configure. 

Just for this case, the Log analytic is not present due to some reason as in this cluster just for development.  There some guide provided via microsoft docs since im using AKS and the Kubernetes itself, how ever , those guide is not deploy via "Kubectl" which is ok . As i did the AKS deployment via terraform, why not put that dashboard deployment together so it will appear one the cluster is deployed. 

Here are the default guide 

1. Manage an Azure Kubernetes Service cluster with the web dashboard - Azure Kubernetes Service | Microsoft Docs 

2. Deploy and Access the Kubernetes Dashboard | Kubernetes 

So here is what i did, is download the deployment.yaml for k8s dashboard and convert to terraform (.yaml to .tf). For that, i have discover one useful tool to convert it which is K2TF . 


So here is the close after being converted to terraform 

provider "kubernetes" {
    #load_config_file       = "false"
    host                   =  var.host
    client_certificate     =  var.client_certificate
    client_key             =  var.client_key
    cluster_ca_certificate =  var.cluster_ca_certificate
}


resource "null_resource" "main" {
  provisioner "local-exec" {
    command = "az aks disable-addons -g ${var.aks-rg} -n ${var.aks-name} -a kube-dashboard"
  }
}
resource "kubernetes_namespace" "kubernetes_dashboard" {
  metadata {
    name = "kubernetes-dashboard"
  }
}

resource "kubernetes_service_account" "kubernetes_dashboard" {
  metadata {
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }
}

resource "kubernetes_service" "kubernetes_dashboard" {
  metadata {
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  spec {
    port {
      port        = 443
      target_port = "8443"
    }

    selector = {
      k8s-app = "kubernetes-dashboard"
    }
  }
}

resource "kubernetes_secret" "kubernetes_dashboard_certs" {
  metadata {
    name      = "kubernetes-dashboard-certs"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  type = "Opaque"
}

resource "kubernetes_secret" "kubernetes_dashboard_csrf" {
  metadata {
    name      = "kubernetes-dashboard-csrf"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  type = "Opaque"
}

resource "kubernetes_secret" "kubernetes_dashboard_key_holder" {
  metadata {
    name      = "kubernetes-dashboard-key-holder"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  type = "Opaque"
}

resource "kubernetes_config_map" "kubernetes_dashboard_settings" {
  metadata {
    name      = "kubernetes-dashboard-settings"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }
}

resource "kubernetes_role" "kubernetes_dashboard" {
  metadata {
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  rule {
    verbs          = ["get", "update", "delete"]
    api_groups     = [""]
    resources      = ["secrets"]
    resource_names = ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
  }

  rule {
    verbs          = ["get", "update"]
    api_groups     = [""]
    resources      = ["configmaps"]
    resource_names = ["kubernetes-dashboard-settings"]
  }

  rule {
    verbs          = ["proxy"]
    api_groups     = [""]
    resources      = ["services"]
    resource_names = ["heapster", "dashboard-metrics-scraper"]
  }

  rule {
    verbs          = ["get"]
    api_groups     = [""]
    resources      = ["services/proxy"]
    resource_names = ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
  }
}

resource "kubernetes_cluster_role" "kubernetes_dashboard" {
  metadata {
    name = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  rule {
    verbs      = ["get", "list", "watch"]
    api_groups = ["metrics.k8s.io"]
    resources  = ["pods", "nodes"]
  }
}

resource "kubernetes_role_binding" "kubernetes_dashboard" {
  metadata {
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  subject {
    kind      = "ServiceAccount"
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = "kubernetes-dashboard"
  }
}

resource "kubernetes_cluster_role_binding" "kubernetes_dashboard" {
  metadata {
    name = "kubernetes-dashboard"
  }

  subject {
    kind      = "ServiceAccount"
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "kubernetes-dashboard"
  }
}

resource "kubernetes_deployment" "kubernetes_dashboard" {
  metadata {
    name      = "kubernetes-dashboard"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "kubernetes-dashboard"
    }
  }

  spec {
    replicas = 1

    selector {
      match_labels = {
        k8s-app = "kubernetes-dashboard"
      }
    }

    template {
      metadata {
        labels = {
          k8s-app = "kubernetes-dashboard"
        }
      }

      spec {
        volume {
          name = "kubernetes-dashboard-certs"

          secret {
            secret_name = "kubernetes-dashboard-certs"
          }
        }

        volume {
          name      = "tmp-volume"
          #empty_dir = {}
        }

        container {
          name  = "kubernetes-dashboard"
          image = "kubernetesui/dashboard:v2.4.0"
          args  = ["--auto-generate-certificates", "--namespace=kubernetes-dashboard"]

          port {
            container_port = 8443
            protocol       = "TCP"
          }

          volume_mount {
            name       = "kubernetes-dashboard-certs"
            mount_path = "/certs"
          }

          volume_mount {
            name       = "tmp-volume"
            mount_path = "/tmp"
          }

          liveness_probe {
            http_get {
              path   = "/"
              port   = "8443"
              scheme = "HTTPS"
            }

            initial_delay_seconds = 30
            timeout_seconds       = 30
          }

          image_pull_policy = "Always"

          security_context {
            run_as_user               = 1001
            run_as_group              = 2001
            read_only_root_filesystem = true
          }
        }

        node_selector = {
          "kubernetes.io/os" = "linux"
        }

        service_account_name = "kubernetes-dashboard"

        toleration {
          key    = "node-role.kubernetes.io/master"
          effect = "NoSchedule"
        }
      }
    }

    revision_history_limit = 10
  }
}

resource "kubernetes_service" "dashboard_metrics_scraper" {
  metadata {
    name      = "dashboard-metrics-scraper"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "dashboard-metrics-scraper"
    }
  }

  spec {
    port {
      port        = 8000
      target_port = "8000"
    }

    selector = {
      k8s-app = "dashboard-metrics-scraper"
    }
  }
}

resource "kubernetes_deployment" "dashboard_metrics_scraper" {
  metadata {
    name      = "dashboard-metrics-scraper"
    namespace = "kubernetes-dashboard"

    labels = {
      k8s-app = "dashboard-metrics-scraper"
    }
  }

  spec {
    replicas = 1

    selector {
      match_labels = {
        k8s-app = "dashboard-metrics-scraper"
      }
    }

    template {
      metadata {
        labels = {
          k8s-app = "dashboard-metrics-scraper"
        }
      }

      spec {
        volume {
          name      = "tmp-volume"
          #empty_dir = {}
        }

        container {
          name  = "dashboard-metrics-scraper"
          image = "kubernetesui/metrics-scraper:v1.0.7"

          port {
            container_port = 8000
            protocol       = "TCP"
          }

          volume_mount {
            name       = "tmp-volume"
            mount_path = "/tmp"
          }

          liveness_probe {
            http_get {
              path   = "/"
              port   = "8000"
              scheme = "HTTP"
            }

            initial_delay_seconds = 30
            timeout_seconds       = 30
          }

          security_context {
            run_as_user               = 1001
            run_as_group              = 2001
            read_only_root_filesystem = true
          }
        }

        node_selector = {
          "kubernetes.io/os" = "linux"
        }

        service_account_name = "kubernetes-dashboard"

        toleration {
          key    = "node-role.kubernetes.io/master"
          effect = "NoSchedule"
        }
      }
    }

    revision_history_limit = 10
  }
}

# resource "null_resource" "proxy" {
#   provisioner "local-exec" {
#     command = "kubectl proxy"
#   }
# }

# resource "null_resource" "web" {
#   provisioner "local-exec" {
#     command = "start-process http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/pod?namespace=default"
#   }
# }

so , if you are keen to do like i did , you may copy the code and run it together with your terraform for AKS deployment. 

Details on k2tf is here 

1. sl1pm4t/k2tf: Kubernetes YAML to Terraform HCL converter (github.com) 

2. And how i discover it - My Experience in Converting Yaml Files into Terraform Scripts: Challenges and Common Mistakes | by Hiranya Perera | Medium 

until next post, stay safe and happy testing 

Saturday, 20 November 2021

Do this on your AGIC

 Hi all, 

i would like to share some finding you are deploying application gateway ingress controller or AGIC in short form. 


There behavior of it keep deploying defaultaddresspool and the address pool that u specify in your terraform code. 

 backend_address_pool {

   name = "${var.agname}-beap"

   fqdns = [

        "dummy"

      ]

So let say your var.agname is AGIC.. so defaultaddresspool  and AGIC-beap backend pool will replacing each other everytime you  run terraform apply. 

After searching then i found there some workaround which some lifecycle management has been added to ignore the changes of the block listed in it. 

  lifecycle {

  ignore_changes = [

    backend_address_pool,

    backend_http_settings,

    frontend_port,

    http_listener,

    probe,

    redirect_configuration,

    request_routing_rule,

    ssl_certificate,

    tags,

    url_path_map,

  ]

}

source : stackoverflow 

some other workaround i tested before getting to this is edit the gateway time and set the agic reconcile  

after all been added according and i try to deploy 3 sample with agic, it is all running smoothly,,



 so why not i reshare the finding on stackoverflow and what i done here for your reading, sample to try this available on my terraform github .




Thursday, 11 November 2021

Adding an S make it work

 Hi all, 

this is just quick sharing on the issue i just face this morning . While creating and NSG rule for terraform i for an error mentioning that the parameter should be in string but i have already put it in string format 


after a while searching, i found this github issue - [HELP WANTED] NSG - Multiple Ports in One Rule · Issue #4518 · Azure/azure-quickstart-templates · GitHub

so to make it works, just and an S to it, from range becomes ranges .


yup, that all needed..

Thanks for reading and enjoy the rest of your day 


Sunday, 29 August 2021

Enable Boot Diagnostic Via Terraform Part 2

For this posting, it is more like an update as i recently found a better way in github (link here) to enable the boot diagnostic to Azure VM . 

This is code segment that i use previously 


  boot_diagnostics{
          enabled = true
          storage_uri = "Https://${azurerm_storage_account.hub-core-vmdiag.name}
                        .blob.core.windows.net"
}

so i did my own experiment to test that and turn out it is easier to be implemented 
here is code up 

1. AzureRM_virtual_machine resource block
 
 boot_diagnostics {
      enabled = true
      storage_uri = azurerm_storage_account.hub-core-vmdiag.primary_blob_endpoint
    }

2. AzureRM_windows_virtual_machine resource block 

 boot_diagnostics { 
      storage_account_uri = azurerm_storage_account.hub-core-vmdiag.primary_blob_endpoint
    }

that all.. thanks for reading and stay safe

Saturday, 28 August 2021

Importing Existing Azure Vnet into Terraform

Previously i have posted a way to import a resource group into terraform. so today it will a continue process to that where it time to import virtual network into terraform . 

This will be a bit challenging as it got some dependencies to another resources like Subnet and NSG. 

So let begin, so always start with creating a empty of your vnet but for this scenario i will suggest to import NSG first as it was bind with subnet. 


resource "azurerm_network_security_group" "nsg-app" {
 
}

Then run the terraform import for this nsg 

 Terraform import azurerm_network_security_group.nsg-app xx/xxx/xxx/NSG-APP

After that, use terraform show to check what are the information needed for NSG block to match with deployment. 


for my case, i just add in the name and few importance information without all the additional rule created in the NSG. 


this step need to be repeat to all   NSG created before touching on Virtual Network and can be skip if no NSG being created or attach to subnet. 

continuing from that, you may start importing the virtual network with the same step and continue with the subnet . i was planning to use one resource block to address vnet and subnet like here 


but seem like create separate block for each subnet will be easier as less information needed for the subnet block. 




repeat for all the subnet available and check if there more changes needed with terraform plan . For me this is enough to import all. 

Thanks for reading and stay safe. 

Saturday, 21 August 2021

Import Azure Existing Resource Group to Terraform

 As part of using terraform to manage the architecture, there a time when the environment has existing resources or the resource being deploy via portal instead of terraform 

So, in order to keep all the control in terraform, the resource need to be imported to terraform so it can be manage from there. 

In this case , Azure Resource Group will be imported to terraform, as we all aware, all resource in azure need to be located in resource 


1.Start with create an empty block the resource ;

resource "azurerm_resource_group" "prod-rg" {
    
}

"prod-rg" is just a block name, can be name with any name but i prefer to tally with the resource group name created on Azure. 

2. Get the RG resource id from azure portal 


3. Import command need to parameter which is resource and resource id 

For this case - terraform import azurerm_resource_group.prod-rg /xxx/xxx/resourcegroup/PROD-RG

4. After import is complete, some info need to be added into resource group block. 

4.1 you may run terraform show to see what need to be added 

  

 Not all need to be added 

5. Edit the RG block as follow 

resource "azurerm_resource_group" "prod-rg" {
    name = "PROD-RG"
    location = "southeastasia"
}

6. run terraform plan to check if any more information need to be add, but as for now, that two information is enough


That all i have for now, feel free to leave a feedback in the comment, happy terraforming and stay safe 

Tuesday, 23 June 2020

Lesson Learn -- OS profile in Terraform

Hello All,

Throughout my journey on learning terraform and start deploying resources mainly Virtual Machine, i just realize that i miss out one of most important parameter in OS Profile config which did not specify the code as below.


         os_profile_windows_config{
             enable_automatic_upgrades = false # For windows Update
             provision_vm_agent = true  #install and enable Azure VM agent 
            }


The VM will be still be deploy as normal but you will notice the vm name would not appear .

Sample As below 

1 VM01 was deploy without the specify the code as mention on top 


2. VM02 was deploy with the code 




 after certain research done and end up i found the solution in the github but one thing to clarify, even if you add the code into VM01 code in Terraform it wont be able to change it anymore. There a few way to solve it either via redeploy it , PowerShell and azure resourcer explore. 

Hope this will help for those who is still beginner in terraform like me, Cheer 😊😊