Installing ArgoCD (gitops tool) on AKS and monitoring using Datadog

We’ll create the AKS and acr using terraform.

  1. Create child modules in a folder “High5infra_aksPOC“.

    a) acr

    ########################## main.tf ###############################
    
    resource "azurerm_container_registry" "main" {
      name                = "highregistry"
      location            = var.location
      resource_group_name = var.resource_group_name
      sku                 = "Premium"
      admin_enabled       = true
    
      identity {
        type         = "UserAssigned"
        identity_ids = [var.identity_id]
      }
    
      tags = {
        "Created By" = var.tag_CreatedBy
        "Created Date" = var.tag_CreatedDate
      }
    
      lifecycle {
        prevent_destroy = true               # Reference link https://developer.hashicorp.com/terraform/tutorials/state/resource-lifecycle#prevent-resource-deletion
      }  
    
    }
    
    resource "azurerm_role_assignment" "acr_pull" {
      scope              = azurerm_container_registry.main.id
      role_definition_name = "AcrPull"
      principal_id       = var.principal_id
    }
    
    output "login_server" {
      value = azurerm_container_registry.main.login_server
    }
    
    ########################## variables.tf ##########################
    
    variable "location" {}
    variable "resource_group_name" {}
    variable "identity_id" {}
    variable "principal_id" {}
    variable "tag_CreatedBy" {}
    variable "tag_CreatedDate" {}
    

    b) aks

    ########################## main.tf ###############################
    
    resource "azurerm_kubernetes_cluster" "aks" {
      name                = var.name
      location            = var.location
      resource_group_name = var.resource_group_name
      dns_prefix          = "exampleaks1"
    
    
      default_node_pool {
        name       = "default"
        node_count = 1
        vm_size    = "Standard_D2_v2"
        vnet_subnet_id = var.subnet_id
      }
    
      identity {
        type = "UserAssigned"
        identity_ids = [var.identity_id]
      }
    
      tags = {
        Created_By = var.tag_CreatedBy
        Created_Date = var.tag_CreatedDate
      }
    }
    
    ########################## variables.tf ##########################
    
    variable "name" {}
    variable "identity_id" {}
    variable "tag_CreatedBy" {}
    variable "tag_CreatedDate" {}
    variable "location" {}
    variable "resource_group_name" {}
    variable "subnet_id" {}
    

    c) LogAnalytics

    ########################## main.tf ###############################
    resource "azurerm_log_analytics_workspace" "main" {
      name                = var.name
      location            = var.location
      resource_group_name = var.resource_group_name
      sku                 = "PerGB2018"
      retention_in_days   = 30
    
      tags = {
        "Created By" = var.tag_CreatedBy
        "Created Date" = var.tag_CreatedDate
      }
    
    }
    
    output "workspace_id" {
      value = azurerm_log_analytics_workspace.main.id
    }
    
    ########################## variables.tf ##########################
    
    variable "location" {}
    variable "resource_group_name" {}
    variable "name" {}
    variable "tag_CreatedBy" {}
    variable "tag_CreatedDate" {}
    

    d) user_assigned_identity

    ########################## main.tf ###############################
    
    resource "azurerm_user_assigned_identity" "main" {
      name                = "Test-containerPull"
      location            = var.location
      resource_group_name = var.resource_group_name
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    output "id" {
      value = azurerm_user_assigned_identity.main.id
    }
    
    output "principal_id" {
      value = azurerm_user_assigned_identity.main.principal_id
    }
    
    ########################## variables.tf ##########################
    
    variable "location" {}
    variable "resource_group_name" {}
    

    e) vnet

    ########################## main.tf ###############################
    
    resource "azurerm_virtual_network" "main" {
      name                = var.virtual_network_name
      location            = var.location
      resource_group_name = var.resource_group_name
      address_space       = ["10.7.0.0/16"]
    
      tags = {
        "Created By" = var.tag_CreatedBy
        "Created Date" = var.tag_CreatedDate
      }
    
    }
    
    resource "azurerm_subnet" "main" {
      name                 = "AksSubnet"
      resource_group_name  = var.resource_group_name
      virtual_network_name = azurerm_virtual_network.main.name
      address_prefixes     = ["10.7.0.0/23"]
    
    #   delegation {
    #     name = "appservices-delegation"
    #     service_delegation {
    #       name = "Microsoft.App/environments"
    #       actions = [
    #         "Microsoft.Network/virtualNetworks/subnets/join/action",
    #         "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
    #       ]
    #     }
    #   }
    
    }
    
    output "vnet_id" {
      value = azurerm_virtual_network.main.id
    }
    
    output "subnet_id" {
      value = azurerm_subnet.main.id
    }
    
    ########################## variables.tf ##########################
    
    
    variable "location" {}
    variable "resource_group_name" {}
    variable "tag_CreatedBy" {}
    variable "tag_CreatedDate" {}
    variable "virtual_network_name" {}
    
  1. Now write the remaining terraform file in the root of the folder “High5infra_aksPOC”.

     ########################## main.tf ###############################
    
     resource "azurerm_resource_group" "aks" {
       name     = var.resource_group_name
       location = var.location
       tags = {
         Status = "Running application"
       }
     }
    
     module "log_analytics" {
       source              = "./modules/LogAnalytics"
       name                = var.log_analytics_name
       resource_group_name = azurerm_resource_group.aks.name
       location            = azurerm_resource_group.aks.location
       tag_CreatedBy       = var.tag_CreatedBy
       tag_CreatedDate     = var.tag_CreatedDate
    
       depends_on = [azurerm_resource_group.aks]
    
     }
    
     module "user_assigned_identity" {
       source              = "./modules/user_assigned_identity"
       resource_group_name = "High-ACR-RG"
       location            = azurerm_resource_group.aks.location
    
       depends_on = [azurerm_resource_group.aks]
     }
    
     module "acr" {
       source              = "./modules/acr"
       resource_group_name = "High-ACR-RG"
       location            = "centralus"
       identity_id         = module.user_assigned_identity.id
       principal_id        = module.user_assigned_identity.principal_id
       tag_CreatedBy       = var.tag_CreatedBy
       tag_CreatedDate     = var.tag_CreatedDate
    
       depends_on = [module.user_assigned_identity]
    
     }
    
     module "vnet" {
       source               = "./modules/vnet"
       resource_group_name  = var.resource_group_name
       location             = var.location
       virtual_network_name = var.vnet_name
       tag_CreatedBy        = var.tag_CreatedBy
       tag_CreatedDate      = var.tag_CreatedDate
    
       depends_on = [ module.user_assigned_identity ]
    
     }
    
     module "aks" {
       source              = "./modules/aks"
       resource_group_name = azurerm_resource_group.aks.name
       location            = azurerm_resource_group.aks.location
       name                = var.aksname
       subnet_id           = module.vnet.subnet_id
       identity_id         = module.user_assigned_identity.id
       tag_CreatedBy       = var.tag_CreatedBy
       tag_CreatedDate     = var.tag_CreatedDate
    
       depends_on = [module.vnet]
     }
    
     ########################## variables.tf ############################
    
     variable "location" {
       description = "The Azure region where the resources should be created."
       type        = string
     }
    
     variable "resource_group_name" {
       description = "The name of the resource group."
       type        = string
     }
    
     variable "aksname" {
       description = "The ingress port for the first container app."
       type        = string
     }
    
     variable "app2_ingress_port" {
       description = "The ingress port for the second container app."
       type        = number
     }
    
     variable "log_analytics_name" {
       description = "Log Analytics name."
       type        = string
     }
    
     variable "tag_CreatedBy" {
       description = "Created By ___"
       type        = string
     }
    
     variable "tag_CreatedDate" {
       description = "Enter Date of creation tag"
     }
    
     variable "vnet_name" {
       description = "Enter the name of the vnet"
       type        = string
     }
    
     ########################## terraform.tfvars #########################
    
     location            = "centralus"
     resource_group_name = "High-AKS"
     log_analytics_name  = "akslogAnalyticsWorkspace"
     aksname             = "testAKS"
     app2_ingress_port   = 5001
     tag_CreatedBy       = "Tara Prasad Sarangi"
     tag_CreatedDate     = "21-10-2024"
     vnet_name           = "AKSVNet"
    
     ############################## backend.tf ###########################
     # Here we will store terraform state file in the Azure storage 
    
     terraform {
        backend "azurerm" {
          storage_account_name = "terraformiacstorage"
          resource_group_name  = "DevOps_Tools"
          container_name       = "terraform-backend"
          key                  = "aks.terraform.tfstate"
          access_key           = "<your_access_key>"
        }
      }
    
  1. Now the AKS will be created with all the resources mentioned in terraform file.

  2. We will connect to AKS using our terminal.

    a) Install AzureCLI by following steps in the given link.

    b) Log into azure using az login command.

    c) Set the subscription using az account set --subscription "your-subscription-name-or-id" command if you have multiple subscriptions.

    d) Install kubectl using az aks install-cli command.

    e) Get the aks credential using az aks get-credentials --resource-group --name command.

    f) Verify the connection using kubectl get nodes command.

  3. Now install ArgoCD using below commands.

     kubectl create ns argocd-stage #create namespace argocd-stage
    
     kubectl apply -n argocd-stage -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml #download and install argocd in argocd-stage namespace
    
     kubectl get pods -n argocd-stage #list all the pods in argo-stage namespace
    
     kubectl edit svc argocd-server -n argocd-stage -o yaml #change the service from ClusterIP to LoadBalancer
    
     kubect get svc argocd-server -n argocd-stage -o yaml #check if service type is changed 
    
     kubectl -n argocd-stage get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 --decode  #(for Password, Username- admin)
    

  4. Now copy the Loadbalancer IP and paste it in browser. Argocd will open and paste the decoded password. Username is admin.

  1. Now we will create Datadog account for monitoring kubernetes

    a) Create a datadog account for free by clicking on this link. Per email account gets 14 days free trial period.

    b) To install the agent in the Kubernetes, In the Agents, choose kubernetes from left dock and follow the instruction.

    c) Create datadog-agent.yaml locally and write in the below format

    apiVersion: datadoghq.com/v2alpha1
    kind: DatadogAgent
    metadata:
      name: datadog
    spec:
      global:
        clusterName: <CLUSTER_NAME> # in my case this is testAKS
        site: <DATADOG_SITE> # in my case this is us5.datadoghq.com
        credentials:
          apiSecret:
            secretName: datadog-secret
            keyName: api-key
    

    d) Save the yaml and run the command kubectl apply -f datadog-agent.yaml.

    e) Now you will be able to see finish option at the bottom of the page.

    f) Now search “Kubernetes Overview”

    We can see all the details about the k8s.