Importing Existing Dialogflow Agents into Terraform
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.
Problem: When Managing Dialogflow Agents with Terraform, building (or re-implementing) an entire Dialogflow agent with flows, pages, intents, transition routes, and other components in Terraform is difficult to do from scratch.
Solution: Build a basic representation of the Dialogflow agent using the
Dialogflow Console or client library (e.g., using the
Dialogflow Python client library),
then import the agent into Terraform using terraform import
and the process
outlined in this blog post.
In this post, we'll walk through the steps to import a Dialogflow agent into Terraform. Once imported into Terraform, 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.
Setup
There are a few things that you'll need to set up before you can import a Dialogflow agent with Terraform:
- Register for a Google Cloud account.
- Enable the Dialogflow API.
- Install and initialize the
Google Cloud
gcloud
CLI tool. - Create a service account and associated JSON key per the Terraform documentation and Google Cloud documentation.
- Finally, install
Terraform. If you're
using macOS, I recommend installing Terraform with
Homebrew. Or, even better, install
tfenv using
brew install tfenv
, then runtfenv install
so you can easily switch between versions of Terraform!
Create a new agent (or use an existing agent)
To get started with this approach, you can use an existing Dialogflow agent that you've created, start from a pre-built agent, or create an agent following the build an agent quickstart.

Define a provider in Terraform
Create a directory for your Terraform configuration files.
Then create a file called provider.tf
with the following contents, which will
define a Google Cloud provider:
provider "google" {
project = "your-project-id"
region = "us-central1"
zone = "us-central1-a"
}
You can substitute in your own Google Cloud project ID as well as your desired region and zone.
Initialize Terraform
From the directory that contains provider.tf
, run the following command in a
terminal:
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.47.0...
- Installed hashicorp/google v4.47.0 (signed by HashiCorp)
[...]
Terraform has been successfully initialized!
Import a resource into Terraform
To import an existing cloud resource such as a Dialogflow agent, page, flow, or intent into Terraform, we'll use the following steps:
- Define placeholder component in Terraform configuration files (
*.tf
) - Run
terraform import
to import the remote state from Google Cloud - Run
terraform plan
to check for mismatches between Terraform configuration files and imported state - Run
terraform show
, then modify the appropriate Terraform configuration files (*.tf
) by replacing the placeholder values with the values from the remote state - Repeat Steps 3 and 4 until the
terraform plan
command reports that there are no further changes to be made (hooray for idempotence!)
Once you've iterated through that process, you'll have everything that you need in your Terraform configuration file needed to re-provision a specific component from scratch (hooray destructible testing and development!).
Let's go through the process in detail to import a Dialogflow agent into Terraform.
Define a placeholder agent in Terraform
We'll start by importing the root component in Dialogflow, the agent itself.
Create a file called agents.tf
with the following contents, which will
define a placeholder for the agent that we want to manage in Terraform:
resource "google_dialogflow_cx_agent" "agent" {
display_name = ""
location = ""
default_language_code = ""
time_zone = ""
}
Import the remote resources into Terraform state
Now we can import the remote state of the agent in Google Cloud to our local
machine (or wherever you are running terraform import
from).
Run the following import command, and replace $PROJECT
, $LOCATON
, and
$AGENT
with your project ID, region, and Dialogflow agent ID, respectively
(note that you can obtain the Dialogflow agent ID from the Dialogflow Console):
terraform import google_dialogflow_cx_agent.agent "projects/$PROJECT/locations/$LOCATION/agents/$AGENT"
If successful, you'll see output similar to the following after Terraform imports the remote agent:
google_dialogflow_cx_agent.agent: Importing from ID "projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac"...
google_dialogflow_cx_agent.agent: Import prepared!
Prepared google_dialogflow_cx_agent for import
google_dialogflow_cx_agent.agent: Refreshing state... [id=projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
All of the Terraform state is now captured in the terraform.tfstate
file in
your current directory. Note that you can view the Terraform state in
human-readable format (and .tf
friendly format) using the terraform show
command.
Run Terraform plan to view differences
We're not quite done yet, we've just captured the remote state and saved it to
our local machine (or wherever you are running terraform import
from).
Now we need to invoke Terraform to see what would change if we were to run a
terraform apply
with our current Terraform configuration files. In other
words, we need to see what is mismatched between the remote state and our local
Terraform configuration files.
We can see what resources that Terraform would change by running the following command in a terminal:
terraform plan
If successful, you'll see output similar to the following after Terraform determines what would need to change such that the Terraform configuration files match the remote state:
google_dialogflow_cx_agent.agent: Refreshing state... [id=projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# google_dialogflow_cx_agent.agent must be replaced
-/+ resource "google_dialogflow_cx_agent" "agent" {
- default_language_code = "en" -> null # forces replacement
- display_name = "Small talk" -> null
~ id = "projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac" -> (known after apply)
- location = "us-central1" -> null # forces replacement
~ name = "5717be04-3519-4cb1-9d0e-378333aea9ac" -> (known after apply)
~ project = "your-project-id" -> (known after apply)
~ start_flow = "projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac/flows/00000000-0000-0000-0000-000000000000" -> (known after apply)
- time_zone = "America/Los_Angeles" -> null
}
Plan: 1 to add, 0 to change, 1 to destroy.
Modify Terraform configuration files to match remote state
Now comes the important part, we need to modify the Terraform configuration
files (*.tf
) so that they would reproduce the remote state that we captured
earlier. In other words, we are trying to solve for the problem of "what inputs
need to be in my Terraform configuration files such that it would identically
reproduce my existing Dialogflow agent?".
Referring to the output in the previous step, we can ignore any lines that
contain (known after apply)
since those will be handled after we apply the
configuration.
The lines that we care about are the ones that involve changes to the arguments in the Dialogflow agent that we defined in Terraform earlier, which are:
-/+ resource "google_dialogflow_cx_agent" "agent" {
- default_language_code = "en" -> null # forces replacement
- display_name = "Small talk" -> null
- location = "us-central1" -> null # forces replacement
- time_zone = "America/Los_Angeles" -> null
}
Taking those differences into account and running terraform show
to display
the Terraform state, let's update the agents.tf
file that we created earlier
to use the following values rather than the empty placeholder values:
resource "google_dialogflow_cx_agent" "agent" {
display_name = "Small talk"
location = "us-central1"
default_language_code = "en"
time_zone = "America/Los_Angeles"
}
Now we're ready to continue to the next step and test that our new Terraform configuration matches the Dialogflow agent.
Iterate until Terraform configuration files match remote state
Similar to the earlier step, we can see what resources that Terraform would change by running the following command in a terminal:
terraform plan
If you've successfully matched all of the remote state, you'll see output similar to the following:
google_dialogflow_cx_agent.agent: Refreshing state... [id=projects/your-project-id/locations/us-central1/agents/5717be04-3519-4cb1-9d0e-378333aea9ac]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
If you see a message similar to the above output: Awesome! We've successfully imported the root Dialogflow agent configuration into Terraform.
If you don't see a message similar to the about output, continue to iterate on
your Terraform configuration files and modify the arguments based on
terraform plan
and terraform show
.
Import other agent resources into Terraform
But we're not done yet!
Don't forget about all of the other components that make up your agents: flows, intents, entity types, pages, and so on.
You can repeat the above steps one-by-one to import each component that exists in your agent into your Terraform configuration files.
You might also find it helpful to keep a record of the terraform import
commands that you have run and the paths that you have used since they
correspond to a specific component in your agent, such as:
terraform import google_dialogflow_cx_agent.agent "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69"
terraform import google_dialogflow_cx_page.request "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/flows/00000000-0000-0000-0000-000000000000/pages/8806f1fb-c45e-43ba-ac16-47a668ddc9eb"
terraform import google_dialogflow_cx_intent.default_welcome_intent "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/intents/00000000-0000-0000-0000-000000000000"
terraform import google_dialogflow_cx_intent.agent.residence "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/intents/327ed726-043e-41b7-af1f-f34a10a0f1e6"
terraform import google_dialogflow_cx_intent.agent.hungry "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/intents/551e2b01-f2bf-49da-8ff4-92adf139b736"
terraform import google_dialogflow_cx_intent.user.testing_agent "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/intents/7608701f-a8f5-4519-9b05-97ec2094c634"
At this point, you'll probably also want to use the REST APIs or client libraries in Dialogflow to list and get detailed information about agents, flows, intents, entity types, and all of the other configuration that makes up your virtual agent. This is a good way to ensure that you capture all of the components in your agent.
Keep importing resources from Dialogflow into Terraform until you've completely reproduced your agent. Next, we'll talk about a couple of best practices that might be helpful along the way.
Additional best practices
When importing resources from Dialogflow into Terraform based on the output of
terraform plan
, you will often end up with lines in your Terraform
configuration files that contain static references to specific agents, flows,
pages, etc., such as:
page = "projects/your-project-id/locations/us-central1/agents/73696d8a-b312-460e-a88a-3fc00827ed69/flows/00000000-0000-0000-0000-000000000000/pages/e736abf0-bc00-4d65-936b-f56033d12433"
You'll want to convert these static references into variables, which you can find by referring to the Attributes References section in the Dialogflow Terraform documentation. Using this approach, you would change the above line into something like:
page = google_dialogflow_cx_page.request.id
That way, your Terraform configuration files will dynamically substitute the identifiers in the right places. Otherwise, you'll get errors when your new Dialogflow agent is trying to refer to a specific resource from a different agent that no longer exists or has changed!
One final tip, if you find that you are not able to use Terraform to manage
certain components or settings in your virtual agent, you can use the
REST APIs or
client libraries
in Dialogflow to configure certain settings. You can even templatize these calls
and manage them with Terraform using the null_resource
in conjunction with the
local_exec
provisioner. For an example of this, refer to this
example code that templatizes a Dialogflow REST API request in Terraform.
Next steps with Terraform and Dialogflow
Now that you've captured all of your Dialogflow agent settings and configuration
in Terraform, you are ready to check your Terraform scripts into version
control, spin up and destroy agents as you please using terraform apply
and
terraform destroy
, or even store remote Terraform state in Google Cloud using
the
GCS backend.
Refer to the following resources to get started importing Dialogflow agents into Terraform:
- Documentation for Dialogflow CX Terraform modules
- Reference for Dialogflow REST APIs
- Reference for Dialogflow client libraries
- Tutorial on Importing Terraform Configuration
- Documentation for
terraform import
Happy Importing!