Cloud Deployment Manager will reach end of support onDecember 31, 2025. If you currently use Deployment Manager, please migrate to Infrastructure Manager or an alternative deployment technology by December 31, 2025 to ensure your services continue without interruption.
Stay organized with collectionsSave and categorize content based on your preferences.
Best practices for converting to Terraform
State
Thestate filestores information about the resources Terraform manages.
By default, Terraform storesstatelocally on disk.
If you store state remotely, you can allow for distributed collaboration,
protect sensitive information, and run Terraform in continuous integration (CI).
After you convert your Deployment Manager template to Terraform and
optionally import resources, we recommend that you follow the steps tostore state remotely in Cloud Storage.
Modules
If you want to reduce complexity, enforce consistency, and promote reusability
of your configuration,
you can useTerraform modulesto encapsulate collections of resources.
To use modules, you can do either of the following:
Create a custom modulefrom the resources exported by
DM Convert. This gives you the most flexibility.
Move "google_bigquery_dataset.bigquerydataset" to "module.bq.google_bigquery_dataset.bigquerydataset"
Successfully moved 1 object(s).
Move "google_bigquery_table.bigquerytable" to "module.bq.google_bigquery_table.bigquerytable"
Successfully moved 1 object(s).
Validate that no resources have changed, by running the following command:
terraformplan
The following is an example of the output you receive after you run the command:
No changes. Your infrastructure matches the configuration.
Identify configuration options for the module by reading the module's
documentation.
Create an instance of the module configured to your current resource
configuration.
For example, if you want to movegoogle_bigquery_datasetandgoogle_bigquery_tableinto the officialBigQuery module, the following example shows what your module might look like:
To view any changes to the configuration, run the following command:
terraformplan
If the published module you selected has different default settings or is configured differently than your configuration, you might see differences highlighted in the output from running the command.
If you want to bootstrap creation of triggers and simplify authentication,
you can choose to use theCloud Build Workspaceblueprint.
Structure
Each converted configuration from DM Convert is asingle root configurationmapped to a single state file. We don't recommend setting up a single state file
to hold a large number of resources. After you've converted your configuration,
we recommend that you ensure that your new configuration follows thebest practices for root modules.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[[["\u003cp\u003ePre-GA products and features are subject to the "Pre-GA Offerings Terms," are available "as is," and may have limited support.\u003c/p\u003e\n"],["\u003cp\u003eTerraform state should be stored remotely, such as in Cloud Storage, to allow for distributed collaboration, protect sensitive data, and enable continuous integration.\u003c/p\u003e\n"],["\u003cp\u003eTerraform modules, either custom-created or published, should be utilized to enhance consistency, reduce complexity, and promote reusability of the configuration.\u003c/p\u003e\n"],["\u003cp\u003eTo incorporate existing resources into modules, move resource configurations into the module directory and update the main configuration file, then use \u003ccode\u003eterraform state mv\u003c/code\u003e to move state into module instances.\u003c/p\u003e\n"],["\u003cp\u003eContinuous integration (CI) systems are recommended to automate running Terraform at scale, and the Cloud Build Workspace blueprint can simplify the creation of triggers and authentication.\u003c/p\u003e\n"]]],[],null,["# Best practices for using DM Convert\n\n| **Preview**\n|\n|\n| This product or feature is subject to the \"Pre-GA Offerings Terms\" in the General Service Terms section\n| of the [Service Specific Terms](/terms/service-terms#1).\n|\n| Pre-GA products and features are available \"as is\" and might have limited support.\n|\n| For more information, see the\n| [launch stage descriptions](/products#product-launch-stages).\n\nBest practices for converting to Terraform\n------------------------------------------\n\n### State\n\nThe [state file](https://developer.hashicorp.com/terraform/language/state)\nstores information about the resources Terraform manages.\nBy default, Terraform stores [state](https://developer.hashicorp.com/terraform/language/state)\nlocally on disk.\nIf you store state remotely, you can allow for distributed collaboration,\nprotect sensitive information, and run Terraform in continuous integration (CI).\n\nAfter you convert your Deployment Manager template to Terraform and\noptionally import resources, we recommend that you follow the steps to\n[store state remotely in Cloud Storage](/docs/terraform/resource-management/store-state#change_the_backend_configuration).\n\n### Modules\n\nIf you want to reduce complexity, enforce consistency, and promote reusability\nof your configuration,\nyou can use [Terraform modules](https://developer.hashicorp.com/terraform/tutorials/modules/module)\nto encapsulate collections of resources.\n\nTo use modules, you can do either of the following:\n\n- [Create a custom module](#custom-modules) from the resources exported by\n DM Convert. This gives you the most flexibility.\n\n- [Use a published module](#published-modules) from Google Cloud's\n collection of [official modules](/docs/terraform/blueprints/terraform-blueprints)\n or the [Terraform registry](https://registry.terraform.io/).\n\nFor most use cases, we recommend that you [use a published module](#published-modules).\n\n#### Create a custom module\n\n1. After you've [converted your configuration](/deployment-manager/docs/dm-convert/docs/dm-convert/convert#view_the_conversions)\n ,identify which resources you want to move into a module.\n\n2. Move the configurations of those resources into a module directory, and\n convert required variables into parameters.\n\n The following example shows how to move `google_bigquery_dataset` and\n `google_bigquery_table` into a module: \n\n # bq-module/main.tf\n resource \"google_bigquery_dataset\" \"bigquerydataset\" {\n provider = google-beta\n\n default_table_expiration_ms = 36000000\n location = \"us-west1\"\n dataset_id = var.dataset_id\n project = var.project_id\n }\n\n resource \"google_bigquery_table\" \"bigquerytable\" {\n provider = google-beta\n\n labels = {\n data-source = \"external\"\n schema-type = \"auto-junk\"\n }\n dataset_id = var.dataset_id\n project = var.project_id\n table_id = var.table_id\n\n depends_on = [\n google_bigquery_dataset.bigquerydataset\n ]\n }\n\n # bq-module/variables.tf\n variable \"project_id\" {\n description = \"Project ID\"\n type = string\n }\n\n variable \"dataset_id\" {\n description = \"Dataset ID\"\n type = string\n }\n\n variable \"table_id\" {\n description = \"Table ID\"\n type = string\n }\n\n3. In the exported `main.tf` file, replace the original configuration with the\n module you created.\n\n The following example shows this replacement using the module created in the example from the previous step. \n\n # main.tf\n module \"bq\" {\n source = \"./bq-module\"\n\n project_id = \"PROJECT_ID\"\n dataset_id = \"bigquerydataset\"\n table_id = \"bigquerytable\"\n }\n\n4. To initialize the local module, run the following command:\n\n terraform init\n\n5. [Move](https://developer.hashicorp.com/terraform/cli/commands/state/mv)\n the Terraform state associated with the resources into the module instance.\n\n To move the module from the example in the previous step, run the following command: \n\n terraform state mv google_bigquery_dataset.bigquerydataset module.bq.google_bigquery_dataset.bigquerydataset\n terraform state mv google_bigquery_table.bigquerytable module.bq.google_bigquery_table.bigquerytable\n\n For this example, the output from the move is: \n\n Move \"google_bigquery_dataset.bigquerydataset\" to \"module.bq.google_bigquery_dataset.bigquerydataset\"\n Successfully moved 1 object(s).\n Move \"google_bigquery_table.bigquerytable\" to \"module.bq.google_bigquery_table.bigquerytable\"\n Successfully moved 1 object(s).\n\n6. Validate that no resources have changed, by running the following command:\n\n terraform plan\n\n The following is an example of the output you receive after you run the command: \n\n No changes. Your infrastructure matches the configuration.\n\n#### Use a published module\n\n1. After you've [converted your configuration](/deployment-manager/docs/dm-convert/docs/dm-convert/convert#view_the_conversions),\n identify a [published module](/docs/terraform/blueprints/terraform-blueprints)\n and the resources that you want to move into it.\n\n2. Identify configuration options for the module by reading the module's\n documentation.\n\n3. Create an instance of the module configured to your current resource\n configuration.\n\n For example, if you want to move `google_bigquery_dataset` and\n `google_bigquery_table` into the official\n [BigQuery module](https://github.com/terraform-google-modules/terraform-google-bigquery)\n , the following example shows what your module might look like: \n\n module \"bq\" {\n source = \"terraform-google-modules/bigquery/google\"\n version = \"~\u003e 5.0\"\n\n project_id = \"PROJECT_ID\"\n dataset_id = \"bigquerydataset\"\n location = \"us-west1\"\n deletion_protection = true\n\n tables = [\n {\n table_id = \"bigquerytable\",\n friendly_name = \"bigquerytable\"\n time_partitioning = null,\n range_partitioning = null,\n expiration_time = null,\n clustering = [],\n schema = null,\n labels = {\n data-source = \"external\"\n schema-type = \"auto-junk\"\n },\n }\n ]\n }\n\n4. To initialize the local module, run the following command:\n\n terraform init\n\n5. Read the [module source code](https://github.com/terraform-google-modules/terraform-google-bigquery/blob/v5.4.1/main.tf)\n to identify resource addresses within the upstream module and construct the\n [move](https://developer.hashicorp.com/terraform/cli/commands/state/mv) commands.\n\n terraform state mv google_bigquery_dataset.bigquerydataset module.bq.google_bigquery_dataset.main\n terraform state mv google_bigquery_table.bigquerytable 'module.bq.google_bigquery_table.main[\"bigquerytable\"]'\n\n6. To view any changes to the configuration, run the following command:\n\n terraform plan\n\nIf the published module you selected has different default settings or is configured differently than your configuration, you might see differences highlighted in the output from running the command.\n\n### Actuation\n\nWe recommend that you use a continuous integration (CI) system, such as\nCloud Build, Jenkins, or GitHub Actions, to automate running Terraform at\nscale. For more information, visit\n[Managing infrastructure as code with Terraform, Cloud Build, and GitOps](/deployment-manager/docs/dm-convert/architecture/managing-infrastructure-as-code).\n\nIf you want to bootstrap creation of triggers and simplify authentication,\nyou can choose to use the [Cloud Build Workspace](https://github.com/terraform-google-modules/terraform-google-bootstrap/tree/master/modules/tf_cloudbuild_workspace)\nblueprint.\n\n### Structure\n\nEach converted configuration from DM Convert is a [single root configuration](https://developer.hashicorp.com/terraform/language/modules#the-root-module)\nmapped to a single state file. We don't recommend setting up a single state file\nto hold a large number of resources. After you've converted your configuration,\nwe recommend that you ensure that your new configuration follows the\n[best practices for root modules](/docs/terraform/best-practices-for-terraform#root-modules)."]]