From Our CEO: Save Money, Do More in Economic Downturn -
Read the Article

Terraform helps you define and manage your cloud and on-prem resources, but it can be challenging to configure, especially when you want to create dynamic dashboards. In this blog, you’ll learn how to use NRQL (New Relic Query Language) to dynamically create a dashboard based on live data.

This is part three of the series. Part one shows how to create a New Relic dashboard in Terraform using JSON templates. Part two shows you how to build complex dynamic dashboards from simple input data.

For this example, you’ll use global API data that's available for free in every New Relic account. You’ll use NRQL to build a dashboard for the five most popular APIs over the past 24 hours—and you’ll be able to do so without making any alterations to your Terraform configuration. This differs from part two, where you learn to dynamically create dashboards, but the rows of any dashboards you create are static based on the input you provide. In this case, the rows that will display are based on the data itself. In this particular example, the rows change based on which APIs are receiving the most calls.

In order to create this kind of dashboard, you can leverage a Terraform provider to query the New Relic GraphQL API, get data on the top five APIs, and then generate a dashboard based on that data. You can apply this example to automatically generate dashboards for top-performing apps, products, overloaded servers, or any other interesting data that may change over time.

The finished dashboard will look something like this:

The Terraform configuration for the dashboard can be found at  dash_nrql_composed.tf.

Defining your query

First, you need to define your GraphQL query. The example here looks up the top five domains using count(). You can define this in a separate file from your Terraform configuration, making it easier to see and update the query code on its own. In this case, the file is called getTopFiveApis.gql.

query ($accountId: Int!) {
  actor {
    account(id: $accountId) {
      nrql(query: "SELECT count(*) from Public_APICall facet api as domain  since 1 day ago limit 5") {
        results
      }
    }
  }
}

After you’ve defined your query, you need to specify how it will be called. You can do this with the GraphQL provider’s data function. Note that you must supply an API key which can be defined as an input variable. The following code can be found in dash_nrql_composed.tf:

variable NEW_RELIC_API_KEY { 
    type = string
}

provider "graphql" {
  url = "https://api.newrelic.com/graphql" #US data center API url
  headers = {
    "API-Key" = var.NEW_RELIC_API_KEY
  }
}

data "graphql_query" "basic_query" {
  query_variables = { 
    accountId = var.accountId
  }
  query     = file("./getTopFiveApis.gql")
}

What's going on here? First, you need to define a new input variable for the New Relic API key. The GraphQL provider uses your key to access New Relic. The provider also needs the account ID but this is already defined in provider.tf. If you’re using the runtf.sh file in the provided repository then this is done for you. Otherwise, you just need to pass your account ID as an argument to your Terraform command as described in the README

Next, you need to configure the GraphQL provider by specifying the API URL and the header “API-Key,” which is required to authenticate. If your account is in the EU data center, you should use the EU API URL: api.eu.newrelic.com.

Finally, use the graphql_query data function from the provider to query the New Relic GraphQL API, specifying the account ID as a query variable and referencing the GraphQL query file you created earlier.

Generate the dashboard

Next, you need to pass the result of the NRQL query into the CONFIG value of the templatefile() function. The following code can be found in /dash_nrql_composed.

locals {
  composed_render = templatefile(
               "${path.module}/dashboards/nrql_composed_widgets.json.tftpl",
               {
                 ACCOUNTID = var.accountId
                 CONFIG = jsondecode(data.graphql_query.basic_query.query_response).data.actor.account.nrql.results
               }
        )
}

resource "newrelic_one_dashboard_json" "nrql_dashboard" {
   json = local.composed_render
}

The jsondecode() function extracts the data we need from the results and assigns it to the CONFIG variable. The shape of the CONFIG data is slightly different from how it looked in previous parts in order to accommodate the query result data.

jsondecode(data.graphql_query.basic_query.query_response).data.actor.account.nrql.results

The template file dashboards/nrql_composed_widgets.json.tftpl iterates through the APIs returned by the NRQL query in the CONFIG object, generating a dashboard row for each API. To learn more about how this file works, read the section on generating dashboard widgets in part two of this series, which also uses iteration to dynamically create a dashboard.

After you apply this Terraform configuration, you’ll get a list of the top five public APIs by total calls. Each time you apply the changes, the latest data will be used to derive the dashboard.

Conclusion

In this blog, you learned how to use Terraform and JSON to generate a dynamic dashboard in New Relic based on an NRQL query. You can use this approach to build dashboards that change based on real-world data. For instance, you could generate a dashboard based on popular products, calendar events, poorly performing servers, and the like.

In order to properly leverage this pattern, you do need to frequently re-apply your dashboard configuration. This could be scheduled or triggered by an event and is best maintained using a CI/CD workflow such as those discussed in our observability as code guide.

If you haven't had a chance to dig deeper into the code for this series yet, check out the nr-terraform-json-dashboard-examples repository. You can use it to quickly bootstrap your own custom dashboards!