Skip to content

Using Terraform to Templatize REST API calls to Dialogflow

Overview

Dialogflow is a powerful tool in Google Cloud that you can use to design conversational agents powered by Natural Language Understanding (NLU) to transform user requests into actionable data. You can integrate voice and/or chat agents in your app, website, or customer support systems to determine user intent and interact with users.

Default Flow for Greeting Bot Agent in Dialogflow CX

Problem: When managing Dialogflow agents with Terraform (or other things with Terraform), sometimes the Terraform module that you are working with doesn't have an argument for the specific setting you need, but the REST API does. If you were to make ad-hoc REST API calls (i.e., outside of Terraform), those configuration settings would not be managed the same way as all of your other infrastructure as code! 😭

Solution: Construct the REST API call that you want to use, then templatize and manage your REST API call within your Terraform configuration files. Now you can manage the custom settings that you need, and still get all of the benefits of Terraform and infrastructure as code principles. 🏆

Sample Terraform code

In this post, we'll use the Terraform modules for Dialogflow CX and walk through the steps to develop and templatize a REST API call in Terraform using the local-exec provisioner along with a null_resource. You can grab the Terraform + Dialogflow scripts and use them in your own Google Cloud account.

Try out the Terraform + Dialogflow scripts

Let's templatize some REST API calls in Terraform and cover some best practices for Dialogflow and Terraform along the way!

Setup

There are a few things that you'll need to set up before you can work with Dialogflow and Terraform to follow the steps in this post:

  1. Register for a Google Cloud account.
  2. Enable the Dialogflow API.
  3. Install and initialize the Google Cloud gcloud CLI tool.
  4. Create a service account and associated JSON key per the Terraform documentation and Google Cloud documentation.
  5. Finally, install Terraform. If you're using macOS, I recommend installing Terraform with Homebrew. Or, even better, install tfenv using brew install tfenv, then run tfenv install so you can easily switch between versions of Terraform!

Initial Terraform setup

We'll start by creating two Terraform configuration files, one for the cloud provider configuration, and one with variables that we'll throughout the configuration files.

First, in a new directory, create a file called variables.tf with the following contents:

variable "project_id" {
  default = "your-project-id"
  type    = string
}

variable "region" {
  default = "us-central1"
  type    = string
}

variable "zone" {
  default = "us-central1-a"
  type    = string
}

where project_id is your Google Cloud project ID, and region and zone refer to your desired Google Cloud region and zone, respectively. Be sure to replace the placeholder values on the default = "" lines with your preferred values.

Next, create a file called provider.tf with the following contents:

provider "google" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
}

You should now have a folder with two .tf files as in:

terraform/
├── provider.tf
└── variables.tf

From within the directory that contains your new Terraform configuration files, you can run the following command to initialize Terraform and install the required plugins:

terraform init

If successful, you'll see output similar to the following after Terraform installs the Google Cloud provider plugin:

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/google...
- Installing hashicorp/google v4.48.0...
- Installed hashicorp/google v4.48.0 (signed by HashiCorp)

[...]

Terraform has been successfully initialized!

Create a new Dialogflow agent

Next, we'll use Terraform to create a (very) simple agent in Dialogflow CX.

In the same directory as your other .tf files, create a file called agents.tf with the following contents:

resource "google_dialogflow_cx_agent" "agent" {
  display_name          = "Greeting Bot"
  location              = var.region
  default_language_code = "en"
  time_zone             = "America/Chicago"
}

You can also change the default_language_code and time_zone if you want.

Now, you can run the following command to apply the Terraform configuration:

terraform apply

You should then see output similar to the following after Terraform determines the plan for which resources to create:

Terraform will perform the following actions:

  # google_dialogflow_cx_agent.agent will be created
  + resource "google_dialogflow_cx_agent" "agent" {
      + default_language_code = "en"
      + display_name          = "Greeting Bot"
      + id                    = (known after apply)
      + location              = "us-central1"
      + name                  = (known after apply)
      + project               = (known after apply)
      + start_flow            = (known after apply)
      + time_zone             = "America/Chicago"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Enter yes to confirm the plan, then Terraform will create your Dialogflow agent:

google_dialogflow_cx_agent.agent: Creating...
google_dialogflow_cx_agent.agent: Creation complete after 2s [id=projects/your-project-id/locations/us-central1/agents/cfc938fc-c616-45f3-807e-2b7d68bc815d]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Switch to the Dialogflow Console in your browser and the project where you created your agent, where you can admire your newly created Greeting Bot agent.

Greeting Bot Agent in Dialogflow CX

Edit default welcome intent

When you create an agent, Dialogflow automatically creates a default welcome intent for you. Let's take a closer look at the default welcome intent, which you can find by navigating to Manage > Intents > Default Welcome Intent in the Dialogflow Console:

Default Welcome Intent for Greeting Bot Agent in Dialogflow CX

Now, let's assume that we want to modify the default welcome intent to use different training phrases instead of the default training phrases:

Default Training Phrases in Default Welcome Intent for Greeting Bot Agent in Dialogflow CX

Instead of using the default training phrases just going to say hi, heya, hello hi, howdy, hey there, hi there, greetings, hey, long time no see, and hello, we want to use the new training phrases hi how are you, greetings, howdy, hello, hello there, hi, nice to meet you, whats up, hows it going, hey.

We could modify the training phrases directly in the Dialogflow CX console, save the intent, and move on. But then we lose out on the benefits of an infrastructure as code approach! What about the reproducibility, change management, or version control of this modification?

Let's explore how to make that change with Terraform instead of doing it manually.

Terraform to the rescue, maybe

Can we use Terraform directly to modify the intent?

Easy enough, right? We'll just use the google_dialogflow_cx_intent module in Terraform to make the change, and move on to other things.

Let's create a new Terraform configuration file called intents.tf with the following contents:

resource "google_dialogflow_cx_intent" "default_welcome_intent" {
  parent       = google_dialogflow_cx_agent.agent.id
  display_name = "Default Welcome Intent"

  training_phrases {
    repeat_count = 1
    parts {
      text = "hi how are you"
    }
  }
}

Then we can apply the configuration by using terraform apply and confirm, and the result is:

google_dialogflow_cx_intent.default_welcome_intent: Creating...
╷
│ Error: Error creating Intent: googleapi: Error 409: com.google.apps.framework.request.AlreadyExistsException: Intent with display name 'Default Welcome Intent' already exists in the agent. Code: ALREADY_EXISTS
│
│   with google_dialogflow_cx_intent.default_welcome_intent,
│   on intents.tf line 1, in resource "google_dialogflow_cx_intent" "default_welcome_intent":
│    1: resource "google_dialogflow_cx_intent" "default_welcome_intent" {

Fighting with existing resources

What?! An error creating the intent. Oh no!

Remember that when we created the agent with Terraform, Dialogflow also created a default welcome intent, as it does with all new agents. So when we try to create an intent called Default Welcome Intent, it fails with an API error since a resource like that already exists, and Terraform isn't explicitly aware of the default welcome intent.

Given this behavior, how can we use Terraform to make a change if the requested resource already exists? How can we get beyond this conflict?

Can we import the resource into Terraform?

Ok, new plan. What if we import the resource into Terraform, modify the settings that we want, then apply the changes?

We could, but then we would need to apply an initial set of Terraform configuration files to create an agent, then import the default welcome intent, then re-apply the Terraform state, resolve conflicts and dependencies, re-apply, and so on. And the complexity of this approach would grow as we make additional customizations to other intents, flows, and other default components in Dialogflow.

While this is technically feasible, it's not the cleanest solution, and it's not the best pattern to use. We need another way of modifying the default welcome intent that works well with Terraform.

There must be a better way!

Since we can't modify the default welcome intent with Terraform, we could make a REST API call to modify the training phrases. 🤔 The REST API request would be represented as code, which means that we can also manage it with Terraform. 💡

In the following sections, we'll walk through the steps to make that happen!

Get information about an intent

Before we get into the details of Terraform and parameterizing REST API calls, let's first construct a valid REST API call that gets information about the default welcome intent. Otherwise we'll be trying to get too many things to work together at the same time, which will make for some complicated debugging later. Let's start simple instead!

Referring to the REST API documentation for Dialogflow CX, we see that there is a method to get information about an intent in Dialogflow. We can use this information to construct a REST API request with curl that uses your Google Cloud project ID, location, agent ID, and the default welcome intent ID, which you can then run in your terminal:

export PROJECT=your-project-id
export LOCATION=us-central1
export AGENT=5c6112d8-85bc-4432-b67e-c8d7090cc5c1
export INTENT=00000000-0000-0000-0000-000000000000

curl --location --request GET "https://$LOCATION-dialogflow.googleapis.com/v3/projects/$PROJECT/locations/$LOCATION/agents/$AGENT/intents/$INTENT" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)"

When you execute this REST API request in your terminal, you should see output with detailed information about the default welcome intent, including the same default training phrases that we saw in the console:

{
  "name": "projects/your-project-id/locations/us-central1/agents/5c6112d8-85bc-4432-b67e-c8d7090cc5c1/intents/00000000-0000-0000-0000-000000000000",
  "displayName": "default welcome intent",
  "trainingPhrases": [
    {
      "id": "19cd2285-4807-4ad5-b313-26f3191310e7",
      "parts": [
        {
          "text": "just going to say hi"
        }
      ],
      "repeatCount": 1
    },
    {
      "id": "59f99b0b-054e-415b-802b-f5901fcaf8c3",
      "parts": [
        {
          "text": "heya"
        }
      ],
      "repeatCount": 1
    },

[...]

}

Perfect! The default welcome intent object that we inspected contains exactly the training phrases that we want to modify. Now, rather than just asking for details about the intent, let's change the training phrases in the default welcome intent using a different REST API request.

In the following sections, we'll walk through a good, better, and best approach so that we can clearly see the benefits in each step along the way without having too many moving parts.

Good: Modify an intent manually

Let's construct a REST API call that makes the desired changes to the default welcome intent. Referring to the REST API documentation for Dialogflow CX, we see that there is a method to PATCH an intent in Dialogflow, which will modify the intent in-place.

We can use this information to construct a REST API request with curl that uses your Google Cloud project ID, location, agent ID, and the default welcome intent ID to modify the default welcome intent, which you can then run in your terminal:

export PROJECT=your-project-id
export LOCATION=us-central1
export AGENT=5c6112d8-85bc-4432-b67e-c8d7090cc5c1
export INTENT=00000000-0000-0000-0000-000000000000

curl --location --request PATCH "https://$LOCATION-dialogflow.googleapis.com/v3/projects/$PROJECT/locations/$LOCATION/agents/$AGENT/intents/$INTENT?updateMask=trainingPhrases" \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H 'Content-Type: application/json' \
    --data-raw "
    {
      'trainingPhrases': [
        {'parts': [{'text': 'hi how are you'}], 'repeatCount': 1},
        {'parts': [{'text': 'greetings'}], 'repeatCount': 1},
        {'parts': [{'text': 'howdy'}], 'repeatCount': 1},
        {'parts': [{'text': 'hello'}], 'repeatCount': 1},
        {'parts': [{'text': 'hello there'}], 'repeatCount': 1},
        {'parts': [{'text': 'hi'}], 'repeatCount': 1},
        {'parts': [{'text': 'nice to meet you'}], 'repeatCount': 1},
        {'parts': [{'text': 'whats up'}], 'repeatCount': 1},
        {'parts': [{'text': 'hows it going'}], 'repeatCount': 1},
        {'parts': [{'text': 'hey'}], 'repeatCount': 1}
      ]
    }
    "

When you execute this REST API request in your terminal, you should see a response with the newly configured information in the default welcome intent, including the new training phrases:

{
  "name": "projects/your-project-id/locations/us-central1/agents/5c6112d8-85bc-4432-b67e-c8d7090cc5c1/intents/00000000-0000-0000-0000-000000000000",
  "displayName": "default welcome intent",
  "trainingPhrases": [
    {
      "parts": [
        {
          "text": "hi how are you"
        }
      ],
      "repeatCount": 1
    },
    {
      "parts": [
        {
          "text": "greetings"
        }
      ],
      "repeatCount": 1
    },

[...]

}

Success! The new default welcome intent contains the new training phrases that we configured. Now, let's move on to how to templatize this REST API request and manage it with Terraform.

Better: Command in Terraform

A good approach is to save the REST API call from the previous section in a Bash script, version control it, and remember to run it after we provision our Dialogflow agent with Terraform. A better approach is to invoke the REST API call from Terraform so that it applies our customizations all in the same, single terraform apply command!

Terraform has provisioners for cloud platforms such as Google Cloud. In addition to provisioners for cloud platforms, it also has other provisioners such as the local-exec provisioner, which can be used to run shell commands on the machine that we are running Terraform from.

Terraform also has various resources, such as the modules that we are using for Dialogflow CX. A special type of resource in Terraform is called the null_resource, which can be used for arbitrary values/actions. This is perfect for us to use in conjunction with the local-exec provisioner to make our REST API call.

To accomplish this, you can put the following contents in a file called intents.tf, being sure to overwrite the (intentional) failed attempt that we tried earlier:

resource "null_resource" "default_welcome_intent" {
  provisioner "local-exec" {
    command = <<-EOT
    export PROJECT=your-project-id
    export LOCATION=us-central1
    export AGENT=5c6112d8-85bc-4432-b67e-c8d7090cc5c1
    export INTENT=00000000-0000-0000-0000-000000000000

    curl --location --request PATCH "https://$LOCATION-dialogflow.googleapis.com/v3/projects/$PROJECT/locations/$LOCATION/agents/$AGENT/intents/$DEFAULT_WELCOME_INTENT?updateMask=trainingPhrases" \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H 'Content-Type: application/json' \
        --data-raw "
        {
          'trainingPhrases': [
            {'parts': [{'text': 'hi how are you'}], 'repeatCount': 1},
            {'parts': [{'text': 'greetings'}], 'repeatCount': 1},
            {'parts': [{'text': 'howdy'}], 'repeatCount': 1},
            {'parts': [{'text': 'hello'}], 'repeatCount': 1},
            {'parts': [{'text': 'hello there'}], 'repeatCount': 1},
            {'parts': [{'text': 'hi'}], 'repeatCount': 1},
            {'parts': [{'text': 'nice to meet you'}], 'repeatCount': 1},
            {'parts': [{'text': 'whats up'}], 'repeatCount': 1},
            {'parts': [{'text': 'hows it going'}], 'repeatCount': 1},
            {'parts': [{'text': 'hey'}], 'repeatCount': 1}
          ]
        }
        "
   EOT
}

All we've done in this step is moved our REST API curl command (the command that modifies the default welcome intent) from the previous section into a Terraform configuration file.

Specifically, we now have the REST API command wrapped with a local-exec provisioner and contained within a null_resource. This means that Terraform will treat this as a resource of its own and run the curl command when we run terraform apply.

Best: Terraform with variables

The approach in the previous section is a decent solution for what we need to accomplish. However, what if you want to use a different Google Cloud project. Or what if you want to use a different agent? Or, can we populate the dynamic variables such as the agent ID using other information that Terraform knows about? You could manually change the values in the Terraform configuration files, but we can't have that kind of manual work in our best solution!

To improve upon the approach used in the previous section, let's convert the static values into templated values using Terraform. Instead of using export VARIABLE=value directly in the local-exec command, let's remove those export commands and instead use variables, templating, and interpolation, which are a few of the capabilities that make Terraform awesome to work with in situations like this.

To accomplish this, you can put the following contents in a file called intents.tf, being sure to overwrite all of the sample code from earlier attempts:

resource "null_resource" "default_welcome_intent" {
  provisioner "local-exec" {
    command = <<-EOT
    curl --location --request PATCH "https://$LOCATION-dialogflow.googleapis.com/v3/projects/$PROJECT/locations/$LOCATION/agents/$AGENT/intents/$DEFAULT_WELCOME_INTENT?updateMask=trainingPhrases" \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H 'Content-Type: application/json' \
        --data-raw "
        {
          'trainingPhrases': [
            {'parts': [{'text': 'hi how are you'}], 'repeatCount': 1},
            {'parts': [{'text': 'greetings'}], 'repeatCount': 1},
            {'parts': [{'text': 'howdy'}], 'repeatCount': 1},
            {'parts': [{'text': 'hello'}], 'repeatCount': 1},
            {'parts': [{'text': 'hello there'}], 'repeatCount': 1},
            {'parts': [{'text': 'hi'}], 'repeatCount': 1},
            {'parts': [{'text': 'nice to meet you'}], 'repeatCount': 1},
            {'parts': [{'text': 'whats up'}], 'repeatCount': 1},
            {'parts': [{'text': 'hows it going'}], 'repeatCount': 1},
            {'parts': [{'text': 'hey'}], 'repeatCount': 1}
          ]
        }
        "
   EOT

    environment = {
      PROJECT                = var.project_id
      LOCATION               = var.region
      AGENT                  = google_dialogflow_cx_agent.agent.name
      DEFAULT_WELCOME_INTENT = "00000000-0000-0000-0000-000000000000"
    }
  }

  depends_on = [
    google_dialogflow_cx_agent.agent
  ]
}

Great! Now we have templatized the REST API request in Terraform. In other words, we converted the static values into dynamic/templated values. This means that we shouldn't have to modify this Terraform configuration file in the future to change details such as the Google Cloud project ID, location, or the agent ID.

We could also configure the list of training phrases as a variable and render the JSON in the API request payload using for expressions in Terraform, but this blog post has to conclude at some point! 😅

Now let's run our new Terraform configuration! We can re-run the following command to initialize Terraform and install an additional plugin (since we added the null_resource provisioner):

terraform init

And we can re-run the following command to apply the Terraform configuration again:

terraform apply

You should then see output similar to the following after Terraform determines the plan for which resources to create (or you might also see Terraform attempting to create the agent if you destroyed or deleted previous versions of your agent, hooray for destructive infrastructure! 💥):

Terraform will perform the following actions:

  # null_resource.default_welcome_intent will be created
  + resource "null_resource" "default_welcome_intent" {
      + id = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Enter yes to confirm the plan, then Terraform will make the REST API call to change the training phrases:

null_resource.default_welcome_intent: Creating...
null_resource.default_welcome_intent: Provisioning with 'local-exec'...
null_resource.default_welcome_intent (local-exec): Executing: ["/bin/sh" "-c" "curl --location --request PATCH \"https://$LOCATION-dialogflow.googleapis.com/v3/projects/$PROJECT/locations/$LOCATION/agents/$AGENT/intents/$DEFAULT_WELCOME_INTENT?updateMask=trainingPhrases\" \\\n    -H \"Authorization: Bearer $(gcloud auth application-default print-access-token)\" \\\n    -H 'Content-Type: application/json' \\\n    --data-raw \"\n    {\n      'trainingPhrases': [\n        {'parts': [{'text': 'hi how are you'}], 'repeatCount': 1},\n        {'parts': [{'text': 'greetings'}], 'repeatCount': 1},\n        {'parts': [{'text': 'howdy'}], 'repeatCount': 1},\n        {'parts': [{'text': 'hello'}], 'repeatCount': 1},\n        {'parts': [{'text': 'hello there'}], 'repeatCount': 1},\n        {'parts': [{'text': 'hi'}], 'repeatCount': 1},\n        {'parts': [{'text': 'nice to meet you'}], 'repeatCount': 1},\n        {'parts': [{'text': 'whats up'}], 'repeatCount': 1},\n        {'parts': [{'text': 'hows it going'}], 'repeatCount': 1},\n        {'parts': [{'text': 'hey'}], 'repeatCount': 1}\n      ]\n    }\n    \"\n"]

[...]

null_resource.default_welcome_intent: Creation complete after 1s [id=9172766381648641447]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Success! Our new training phrases are now configured in the default welcome intent, and we configured them all from a managed and templated REST API call with Terraform!

Newly Configured Training Phrases in Default Welcome Intent for Greeting Bot Agent in Dialogflow CX

You can navigate to the simulator in the Dialogflow console to have a sample conversation with Greeting Bot and try things out interactively:

Sample Dialog with Greeting Bot Agent in Dialogflow CX

There's a lot of things going on in the final Terraform code sample, so let's review the key points and best practices that we implemented in this step.

Handling multi-line commands

What's that EOT doing in the code for our command?! That's a heredoc style that we can use in the shell command to break our large command up across multiple lines and make it easier to read and maintain. Your future self will thank you for using heredoc directives. You can learn more about using heredoc style strings in the Terraform documentation.

PATCHing with update masks

You might have noticed a URL parameter in our PATCH request called updateMask=trainingPhrases. When updating Dialogflow agent data via the API, you can choose to overwrite only specific fields to avoid accidentally overwriting all of the other data contained within the intent, agent, or other component. This also reduces the number of settings we have to repeat or duplicate in our API request payload. You can learn more about updating data with field masks in the Dialogflow documentation.

Using environment variables

Rather than defining the environment variables directly in the templated REST API curl command, we moved the environment variables to the environment block and defined them there. This makes it easier to manage and edit the environment variables in the future using Terraform's interpolation and templating functionality. You can learn more about using environment variables in the Terraform documentation for the local-exec provisioner.

Input variables in Terraform

Some of the environment variables that we've defined such as the PROJECT and LOCATION are referring to Terraform variables that we've defined elsewhere. In this case, we defined the input variables in a separate file called variables.tf in the earlier section on Terraform setup. Now, if we ever need to change the project or region, we can change it in one location without having to search and replace all of our Terraform configuration files. You can learn more about using input variables in the Terraform documentation.

Referencing Terraform attributes

Instead of using a static value for the agent ID variable, we changed the reference to refer to the name attribute of the Terraform-managed Dialogflow agent resource (i.e., the one that we defined in agents.tf) by adding the following environment variable definition within the local-exec provisioner:

environment = {
  AGENT = google_dialogflow_cx_agent.agent.name
}

This is also a helpful way to have Terraform use the full identifiers for Dialogflow resources such as intents or pages (e.g., projects/{project}/locations/{location}/agents/{name}), which is very convenient when you are configuring settings such as transition routes in flows. You can learn more about using attributes from resources in the Terraform documentation for the Dialogflow CX module.

Handling dependencies

You might also have noticed that we used a depends_on block in the null_resource because we want to ensure that the REST API call only runs after the agent is created. Otherwise the REST API call might fail (or even worse, have non-deterministic behavior! ☠️) if it is run before the Dialogflow agent exists.

In general, the fact that we referenced an attribute (google_dialogflow_cx_agent.agent.name) from the Dialogflow agent in the null_resource means that Terraform will do the right thing and handle the dependency of resources properly. In other words, Terraform knows that it cannot determine the name of the agent before it exists. However, it's always good to be explicit rather than implicit when possible, especially since null_resources and local-execs can be used for arbitrary tasks! You can learn more about using handling hidden resources in the Terraform documentation.

Congratulations, you made it all the way through to the best solution and learned about all of the best practices that we followed along the way! 🎉

Handling more complex cases

In this example, I tried to keep things simple(r) and focused on the methodology to work with REST API calls in Terraform by using a very simple Dialogflow agent with minimal configuration.

However, in practice, when you use REST API calls to modify custom settings for more complex Dialogflow agents, subsequent Terraform runs will often fail when you try to change, manage, or destroy resources and components since you've changed these settings outside of Terraform via a REST API call, which can have a cascading effect on other components.

Terraform Graph of Dialogflow CX Agent

To this end, if you want to explore a slightly more complex example that modifies transition routes in the default start flow and requires the use of a destroy-time provisioner and triggers in Terraform, refer to the previous post on Managing Dialogflow Agents with Terraform and the accompanying Terraform + Dialogflow code sample on GitHub. In particular, you can examine the terraform/flows.tf file there since you know more about managing REST API calls with Terraform after reading this blog post. 😁

Summary

In this post, we walked through the steps to construct and templatize a REST API call to Dialogflow CX by using the local-exec provisioner, null_resource, and environment variables in Terraform. In this example, we modified the default welcome intent to use different training phrases instead of the default training phrases.

You can also use this same approach to manage all of your custom Dialogflow agent settings that are available in the Dialogflow CX API while retaining all of the benefits of Terraform and infrastructure as code principles.

Once you represent your agent configuration and REST API calls in Terraform, then you can manage all of your agents and their settings programmatically, version control and track the state of your agents, spin up agents in dev/QA/prod environments for testing, and all of the other neat functionality that you get by using Terraform.

If you haven't already, now is a good time to get the Terraform + Dialogflow scripts and try them in your own Google Cloud account!

Try out the Terraform + Dialogflow scripts

Happy templatizing!