To monitor the performance of your IT infrastructure, you can create and manage health rules in your Cisco Cloud Observability Tenant by using the Terraform platform. Terraform is an open-source tool that enables you to create and provision your IT infrastructure through code.

For example, using Terraform, you have provisioned a new Amazon Web Services (AWS) account and added services such as EC2 and Load Balancer. You can write configuration files (scripts) using the same Terraform platform to create and manage health rules on these AWS entities.

Terraform makes requests to the Cisco Cloud Observability Public API to create and manage health rules. OAuth 2.0 protocol is used to get access to the Public API. As part of the OAuth process, you need to generate an access token, which is used to access the Public APIs on your Cloud Tenant. For more information on OAuth API, see Cisco AppDynamics OAuth API.

Prerequisites

Health Rule Operations using Terraform

You can perform the following operations for health rules using Terraform:

Create a Health Rule

To create a health rule, do the following:

  1. Create a directory on your local machine in which you will write the terraform configuration files (scripts) to create a health rule.
  2. Create a file named create.tf and add the following code:

    terraform {
      required_providers {
        http = {
          source = "hashicorp/http"
          version = "3.1.0"
        }
        local = {
          source = "hashicorp/local"
          version = "2.2.3"
        }
      }
    }
    
    provider "http" {
      # Configuration options
    }
    
    
    data "http" "get_auth_token" {
      provider = http
      url = "${var.appdURL}/auth/${var.tenant}/default/oauth2/token"
    
      request_headers = {
        Content-Type  =  "application/x-www-form-urlencoded"
        Authorization = "Basic ${base64encode("${var.clientId}:${var.clientSecret}")}"
      }
      request_body = "grant_type=client_credentials"
      method = "POST"
      lifecycle {
        postcondition {
          condition     = contains([200], self.status_code)
          error_message = "Status code invalid, Auth Token not generated successfully. ${self.response_body}"
        }
      }
    }
    
    
    locals {
      auth_response = jsondecode(data.http.get_auth_token.response_body)
      json_data = file("${path.module}/createHR.json")
    }
    
    
    
    data "http" "create_healthrule"{
    provider = http
      url = "${var.appdURL}/alerting/v1beta2/healthRules"
      request_headers = {
        Content-Type   = "application/json"
        Authorization  ="Bearer ${local.auth_response.access_token}"
        Appd-Tenant-Id = "${var.tenant}"
        Accept         = "application/json"
      }
      method = "POST"
      request_body = "${local.json_data}"
    }
    
    output "get_response" {
      value = "Health rule create response is ${data.http.create_healthrule.response_body} with response code ${data.http.create_healthrule.status_code}"
    }
    
    resource "local_file" "json-data" {
        content  = data.http.create_healthrule.response_body
        filename = "CreateHRResponse.json"
    }
    CODE



  3. Create a file named createHR.json and add the following code (as an example) that serves as the payload for the health rule:

    {
        "name": "Create HR Using terraform Script",
        "description": "Health Rule : Create HR Using terraform Script",
        "enabled": true,
        "scheduleName": "Always",
        "waitTimeAfterViolation": "5m",
        "evaluationObjects": "k8s:pod()",
        "criticalCriteria": {
            "criteriaExpression": "A",
            "conditions": [
                {
                    "name": "Condition 1",
                    "label": "A",
                    "conditionExpression": "metric:k8s.memory.usage.cmin(2m)>95",
                    "evaluateToTrueOnNoData": false,
                    "source": "infra-agent"
                }
            ]
        },
        "warningCriteria": {
            "criteriaExpression": "A",
            "conditions": [
                {
                    "name": "Condition 1",
                    "label": "A",
                    "conditionExpression": "metric:k8s.memory.usage.cmin(2m)>75",
                    "evaluateToTrueOnNoData": false,
                    "source": "infra-agent"
                }
            ]
        },
        "associateHealthTo": [
            {
                "objectExpr": "this"
            }
        ]
    }
    CODE



  4. Create a file named variables.tf. Add the following code and enter the default value of the variables for your environment:

    variable "appdURL" {
      description = "Endpoint of the Cisco Cloud Observability applications"
      type        = string
      default     = "<Your FSO Tenant URL>"
    }
    
    variable "tenant" {
      description = "Tenant ID"
      type        = string
      default     = "<Your FSO Tenant ID as per your Service Principals>"
    }
    
    variable "clientId" {
      description = "Generated Client ID"
      type        = string
      default     = "<Your Client ID as per your Service Principals>"
    }
    
    variable "clientSecret" {
      description = "Generated Client Secret"
      type        = string
      default     = "<Your Client Secret Key as per your Service Principals>"
    }
    CODE



  5. Run the following command to initialize your working directory:

    terraform init
    CODE
  6. Run the following command to execute the actions defined in the Terraform configuration files:

    terraform apply
    CODE

After executing the Terraform commands, the health rule gets created, and the responses are saved in the CreateHRResponse.json file in the same working directory.

Delete a Health Rule 

To delete a health rule, do the following:

  1. Create a directory on your local machine in which you will write the terraform configuration files (scripts) to delete the health rule.
  2. Create a file named deleteHR.tf and add the following code:

    terraform {
      required_providers {
        http-client = {
          source = "dmachard/http-client"
          version = "0.0.3"
        }
      }
    }
    
    provider "http-client" {
      # Configuration options
    }
    
    provider "http" {
      # Configuration options
    }
    
    
    data "http" "get_auth_token" {
      provider = http
      url = "${var.appdURL}/auth/${var.tenant}/default/oauth2/token"
    
      request_headers = {
        Content-Type  =  "application/x-www-form-urlencoded"
        Authorization = "Basic ${base64encode("${var.clientId}:${var.clientSecret}")}"
      }
      request_body = "grant_type=client_credentials"
      method = "POST"
      lifecycle {
        postcondition {
          condition     = contains([200], self.status_code)
          error_message = "Status code invalid, Auth Token not generated successfully. ${self.response_body}"
        }
      }
    }
    
    
    locals {
      auth_response = jsondecode(data.http.get_auth_token.response_body)
    }
    
    
    
    data "httpclient_request" "delete_healthrule"{
    provider = http-client
      url = "${var.appdURL}/alerting/v1beta2/healthRules/${var.hrID}"
      request_headers = {
        Content-Type   = "application/json"
        Authorization  ="Bearer ${local.auth_response.access_token}"
        Appd-Tenant-Id = "${var.tenant}"
        Accept         = "application/json"
      }
      request_method = "DELETE"
    }
    
    output "get_response_code" {
      value = data.httpclient_request.delete_healthrule.response_code
    }
    
    output "get_response_body" {
      value = data.httpclient_request.delete_healthrule.response_body
    }
    
    
    resource "local_file" "json-data" {
        content  = data.httpclient_request.delete_healthrule.response_body
        filename = "deleteHRResponse.json"
    }
    CODE
  3. Create a file named variables.tf. Add the following code and enter the default value of the variables for your environment:

    variable "appdURL" {
      description = "Value of the AppD application"
      type        = string
      default     = "<Your FSO Tenant URL>"
    }
    
    variable "tenant" {
      description = "tenant ID for the AppD login"
      type        = string
      default     = "<Your FSO Tenant ID as per your Service Principals>"
    }
    
    variable "clientId" {
      description = "Service principal client id"
      type        = string
      default     = "<Your Client ID as per your Service Principals>"
    }
    
    variable "clientSecret" {
      description = "Value of Service principal client secret"
      type        = string
      default     = "<Your Client Secret Key as per your Service Principals>"
    }
    
    variable "hrID" {
      description = "HR ID that needs to be deleted"
      type        = string
      default     = "<The Health Rule ID>"
    }
    
    
    CODE
  4. Run the following command to initialize your working directory:

    terraform init
    CODE
  5. Run the following command to execute the actions defined in the Terraform configuration files:

    terraform apply
    CODE

After executing the Terraform commands, the specified health rule gets deleted, and the responses are saved in the deleteHRResponse.json file in the same working directory.

Retrieve All Configured Health Rules 

To retrieve all the configured health rules, do the following:

  1. Create a directory on your local machine in which you will write the terraform configuration files (scripts) to retrieve all the configured health rules.
  2. Create a file named getAllHR.tf and add the following code:

    terraform {
      required_providers {
        http = {
          source = "hashicorp/http"
          version = "3.1.0"
        }
        local = {
          source = "hashicorp/local"
          version = "2.2.3"
        }
      }
    }
    
    provider "http" {
      # Configuration options
    }
    
    
    data "http" "get_auth_token" {
      provider = http
      url = "${var.appdURL}/auth/${var.tenant}/default/oauth2/token"
    
      request_headers = {
        Content-Type: "application/x-www-form-urlencoded"
        Authorization = "Basic ${base64encode("${var.clientId}:${var.clientSecret}")}"
      }
      request_body = "grant_type=client_credentials"
      method = "POST"
    }
    
    
    locals {
      auth_reponse = jsondecode(data.http.get_auth_token.response_body)
    }
    
    
    data "http" "get_healthrule"{
    provider = http
      url = "${var.appdURL}/alerting/v1beta2/healthRules/"
    
      request_headers = {
        Content-Type: "application/json"
        Authorization:"Bearer ${local.auth_reponse.access_token}"
        Appd-Tenant-Id: "${var.tenant}"
      }
      method = "GET"
    
    }
    
    output "get_response" {
      value = data.http.get_healthrule.response_body
    }
    
    resource "local_file" "json-data" {
        content  = data.http.get_healthrule.response_body
        filename = "getHR.json"
    }
    CODE
  3. Create a file named variables.tf. Add the following code and enter the default value of the variables for your environment:

    variable "appdURL" {
      description = "Endpoint of Cisco Cloud Observability application"
      type        = string
      default     = "<Your Cisco Observability Platform Tenant URL>"
    }
    
    variable "tenant" {
      description = "Tenant ID"
      type        = string
      default     = "<Your FSO Tenant ID as per your Service Principals>"
    }
    
    variable "clientId" {
      description = "Generated Client ID"
      type        = string
      default     = "<Your Client ID as per your Service Principals>"
    }
    
    variable "clientSecret" {
      description = "Generated Client Secret"
      type        = string
      default     = "<Your Client Secret Key as per your Service Principals>"
    }
    CODE
  4. Run the following command to initialize your working directory:

    terraform init
    CODE
  5. Run the following command to execute the actions defined in the Terraform configuration files:

    terraform apply
    CODE

After executing the Terraform commands, the details of all the configured health rules on your Cloud Tenant are saved in the getHR.json file in the same working directory.

Retrieve a Health Rule 

To retrieve a configured health rule, do the following:

  1. Create a directory on your local machine in which you will write the terraform configuration files (scripts) to retrieve a configured health rule.
  2. Create a file named getHR.tf and add the following code:

    terraform {
      required_providers {
        http = {
          source = "hashicorp/http"
          version = "3.1.0"
        }
        local = {
          source = "hashicorp/local"
          version = "2.2.3"
        }
      }
    }
    
    provider "http" {
      # Configuration options
    }
    
    
    data "http" "get_auth_token" {
      provider = http
      url = "${var.appdURL}/auth/${var.tenant}/default/oauth2/token"
    
      request_headers = {
        Content-Type: "application/x-www-form-urlencoded"
        Authorization = "Basic ${base64encode("${var.clientId}:${var.clientSecret}")}"
      }
      request_body = "grant_type=client_credentials"
      method = "POST"
    }
    
    
    locals {
      auth_reponse = jsondecode(data.http.get_auth_token.response_body)
    }
    
    
    data "http" "get_healthrule"{
    provider = http
      url = "${var.appdURL}/alerting/v1beta2/healthRules/${var.hrID}"
    
      request_headers = {
        Content-Type: "application/json"
        Authorization:"Bearer ${local.auth_reponse.access_token}"
        Appd-Tenant-Id: "${var.tenant}"
      }
      method = "GET"
    
    }
    
    output "get_response" {
      value = data.http.get_healthrule.response_body
    }
    
    resource "local_file" "json-data" {
        content  = data.http.get_healthrule.response_body
        filename = "getHR.json"
    }
    CODE
  3. Create a file named variables.tf. Add the following code and enter the default value of the variables for your environment:

    variable "appdURL" {
      description = "Endpoint of Cisco Cloud Observability"
      type        = string
      default     = "<Your FSO Tenant URL>"
    }
    
    variable "tenant" {
      description = "Tenant ID"
      type        = string
      default     = "<Your FSO Tenant ID as per your Service Principals>"
    }
    
    variable "clientId" {
      description = "Generated Client ID"
      type        = string
      default     = "<Your Client ID as per your Service Principals>"
    }
    
    variable "clientSecret" {
      description = "Generated Client Secret"
      type        = string
      default     = "<Your Client Secret Key as per your Service Principals>"
    }
    
    variable "hrID" {
      description = "The ID of the Health Rule that you want to retrieve"
      type        = string
      default     = "<The Health Rule ID>"
    }
    
    
    CODE
  4. Run the following command to initialize your working directory:

    terraform init
    CODE
  5. Run the following command to execute the actions defined in the Terraform plan:

    terraform apply
    CODE

After executing the Terraform commands, the details of specified health rule are saved in the getHR.json file in the same working directory.

Update a Health Rule

To update an existing health rule, do the following:

  1. Create a directory on your local machine in which you will write the terraform configuration files (scripts) to update a health rule.
  2. Create a file named UpdateHR.tf and add the following code:

    terraform {
      required_providers {
        http-client = {
          source = "dmachard/http-client"
          version = "0.0.3"
        }
      }
    }
    
    provider "http-client" {
      # Configuration options
    }
    
    provider "http" {
      # Configuration options
    }
    
    
    data "http" "get_auth_token" {
      provider = http
      url = "${var.appdURL}/auth/${var.tenant}/default/oauth2/token"
    
      request_headers = {
        Content-Type  =  "application/x-www-form-urlencoded"
        Authorization = "Basic ${base64encode("${var.clientId}:${var.clientSecret}")}"
      }
      request_body = "grant_type=client_credentials"
      method = "POST"
      lifecycle {
        postcondition {
          condition     = contains([200], self.status_code)
          error_message = "Status code invalid, Auth Token not generated successfully. ${self.response_body}"
        }
      }
    }
    
    
    locals {
      auth_response = jsondecode(data.http.get_auth_token.response_body)
      json_data = file("${path.module}/UpdateHR.json")
    }
    
    
    
    data "httpclient_request" "update_healthrule"{
    provider = http-client
      url = "${var.appdURL}/alerting/v1beta2/healthRules/${var.hrID}"
      request_headers = {
        Content-Type   = "application/json"
        Authorization  ="Bearer ${local.auth_response.access_token}"
        Appd-Tenant-Id = "${var.tenant}"
        Accept         = "application/json"
      }
      request_method = "PUT"
      request_body   = "${local.json_data}"
    }
    
    output "get_response_code" {
      value = data.httpclient_request.update_healthrule.response_code
    }
    
    output "get_response_body" {
      value = data.httpclient_request.update_healthrule.response_body
    }
    
    
    resource "local_file" "json-data" {
        content  = data.httpclient_request.update_healthrule.response_body
        filename = "UpdateHRResponse.json"
    }
    CODE
  3. Create a file named UpdateHR.json and add the following code (as an example) that serves as the payload for the health rule:

    {
        "name": "testTF-Check4-Update",
        "description": "Health Rule : testHRStatusFlowWarningUpgradeCriticalForPod",
        "enabled": true,
        "scheduleName": "Always",
        "waitTimeAfterViolation": "5m",
        "evaluationObjects": "k8s:pod().filter(attributes:k8s.pod.name in ('alert-pod-14'))",
        "criticalCriteria": {
            "criteriaExpression": "A",
            "conditions": [
                {
                    "name": "Condition 11",
                    "label": "A",
                    "conditionExpression": "metric:infra-agent:k8s.memory.usage.cmin(2m)>95",
                    "evaluateToTrueOnNoData": false
                }
            ]
        },
        "warningCriteria": {
            "criteriaExpression": "A",
            "conditions": [
                {
                    "name": "Condition 11",
                    "label": "A",
                    "conditionExpression": "metric:infra-agent:k8s.memory.usage.cmin(2m)>75",
                    "evaluateToTrueOnNoData": false
                }
            ]
        },
        "associateHealthTo": [
            {
                "objectExpr": "this"
            }
        ],
        "entityType": "k8s:pod",
        "createdAt": "2022-09-29T08:31:16Z",
        "updatedAt": "2022-09-29T08:32:41Z",
        "id": "633557d4a1113f3102195d08"
    }
    CODE
  4. Create a file named variables.tf. Add the following code and enter the default value of the variables for your environment:

    variable "appdURL" {
      description = "Value of Cisco Cloud Observability"
      type        = string
      default     = "<Your FSO Tenant URL>"
    }
    
    variable "tenant" {
      description = "Tenant ID"
      type        = string
      default     = "<Your FSO Tenant ID as per your Service Principals>"
    }
    
    variable "clientId" {
      description = "Generated Client ID"
      type        = string
      default     = "<Your Client ID as per your Service Principals>"
    }
    
    variable "clientSecret" {
      description = "Generated Client Secret"
      type        = string
      default     = "<Your Client Secret Key as per your Service Principals>"
    }
    
    variable "hrID" {
      description = "The ID of the health rule that you want to update"
      type        = string
      default     = "<The Health Rule ID>"
    }
    CODE
  5. Run the following command to initialize your working directory:

    terraform init
    CODE
  6. Run the following command to execute the actions defined in the Terraform configuration files:

    terraform apply
    CODE

After executing the Terraform commands, the specified health rule gets updated, and the responses are saved in the UpdateHRResponse.json file in the same working directory.