Terraform is not limited to resources it creates. Infrastructure that already exists — whether created manually in the Gcore Customer Portal, through the API, or by another Terraform configuration — can be brought under Terraform management without being recreated. This process is called import and is commonly used when teams migrate existing environments to infrastructure-as-code, recover from lost state files, or reorganize infrastructure between configurations.
Import process
Without import, Terraform does not know about resources outside its state file, so terraform plan shows them as + create — meaning it would create duplicates. Import solves this:
- Terraform reads the resource’s current state from the Gcore API using the resource ID.
- It writes that state into
terraform.tfstate.
- From that point,
terraform plan compares the configuration against the recorded state and reports only the actual differences.
Prepare for import
Every import requires a resource type and a resource ID; find both in the Import section of each resource’s page on the Terraform Registry.
| What | Example |
|---|
| The resource type as used in Terraform | gcore_cloud_project, gcore_cloud_network |
| The resource ID in the format the provider expects | 1186668 for a project, 1186668/76/abc-uuid for a network |
Terraform offers two import methods — choose based on scope and team workflow:
| terraform import | import block |
|---|
| Availability | All Terraform CLI versions | Terraform CLI 1.5+ |
Modifies .tf files | No | No (but can generate config) |
Visible in terraform plan | No | Yes |
| Can be committed to version control | No | Yes |
| Best for | Quick one-off imports | Team workflows, IaC pipelines |
Run an import command
The terraform import command binds an existing resource to a resource block in the configuration and writes its state immediately. It works with all Terraform CLI versions and requires no changes to .tf files beyond adding the resource block.
Step 1. Write a resource block
Create a resource block in the .tf configuration with at minimum the required fields, listed in the resource’s schema on Terraform Registry.
For a Gcore project:
resource "gcore_cloud_project" "default" {
name = "Default"
}
The import command format is:
terraform import <resource_address> '<resource_id>'
Where <resource_address> is <resource_type>.<local_name> — matching the resource block written in Step 1.
terraform import gcore_cloud_project.default '1186668'
Expected output:
gcore_cloud_project.default: Importing from ID "1186668"...
gcore_cloud_project.default: Import prepared!
Prepared gcore_cloud_project for import
gcore_cloud_project.default: Refreshing state... [name=Default]
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.
Run plan to verify there is no attribute drift between the configuration and the imported state:
gcore_cloud_project.default: Refreshing state... [name=Default]
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 terraform plan still shows changes, the resource block in .tf has attributes that do not match the imported state. Update the configuration until terraform plan reports no changes.
Add an import block to configuration
The import block is the recommended approach for team environments. It makes the import operation visible in terraform plan, so the intent is reviewable before state is modified.
Step 1. Write an import block
Add an import block to any .tf file alongside the target resource block:
resource "gcore_cloud_project" "default" {
name = "Default"
}
import {
id = "1186668"
to = gcore_cloud_project.default
}
The to field must match the <resource_type>.<local_name> of the resource block.
Run plan to preview the full resource state before the import is applied:
gcore_cloud_project.default: Preparing import... [id=1186668]
gcore_cloud_project.default: Refreshing state... [name=Default]
Terraform will perform the following actions:
# gcore_cloud_project.default will be imported
resource "gcore_cloud_project" "default" {
client_id = 1000503
created_at = "2026-04-17T12:43:36Z"
description = "Default project"
id = 1186668
is_default = true
name = "Default"
state = "ACTIVE"
}
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
The plan shows the full resource state that will be written to the state file.
Step 3. Apply
After reviewing the plan, apply to write the resource into state:
gcore_cloud_project.default: Importing... [id=1186668]
gcore_cloud_project.default: Import complete [id=1186668]
Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.
After a successful import, remove the import block from the configuration — it is no longer needed and will cause an error if left in place after the resource is already in state.
Generate configuration automatically
When importing a resource that has many attributes, writing the resource block manually is time-consuming. Use the -generate-config-out flag to generate the block automatically.
Step 1. Write only the import block (no resource block)
Add only an import block — no resource block. Terraform generates it automatically in the next step:
import {
id = "1186668"
to = gcore_cloud_project.default
}
Pass the flag to specify the output file name. Terraform generates the resource block and writes it to that file:
terraform plan "-generate-config-out=generated.tf"
terraform plan -generate-config-out=generated.tf
gcore_cloud_project.default: Preparing import... [id=1186668]
gcore_cloud_project.default: Refreshing state... [name=Default]
Terraform will perform the following actions:
# gcore_cloud_project.default will be imported
# (config will be generated)
resource "gcore_cloud_project" "default" {
...
}
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
Warning: Config generation is experimental
Terraform has generated configuration and written it to generated.tf. Please
review the configuration and edit it as necessary before adding it to version
control.
Step 3. Review and prune generated.tf
Terraform writes the full resource schema to generated.tf:
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform from "1186668"
resource "gcore_cloud_project" "default" {
description = "Default project"
name = "Default"
}
Remove read-only and default-value attributes from generated.tf, then move the pruned configuration into the main .tf files and delete generated.tf.
Config generation is marked experimental. The generated output may include read-only attributes that Terraform does not accept as input. Remove any attribute that the provider schema marks as read-only (client_id, created_at, id, is_default, state in this example) before running terraform apply.
Import ID reference
The import ID format varies by resource. Common Gcore resources:
| Resource | Import ID format | Example |
|---|
gcore_cloud_project | <project_id> | 1186668 |
gcore_cloud_network | <project_id>/<region_id>/<network_id> | 1186668/76/abc-uuid |
gcore_cloud_network_subnet | <project_id>/<region_id>/<subnet_id> | 1186668/76/xyz-uuid |
gcore_cloud_instance | <project_id>/<region_id>/<instance_id> | 1186668/76/def-uuid |
gcore_cloud_volume | <project_id>/<region_id>/<volume_id> | 1186668/76/ghi-uuid |
gcore_cloud_k8s_cluster | <project_id>/<region_id>/<cluster_id> | 1186668/76/jkl-uuid |
gcore_cloud_load_balancer | <project_id>/<region_id>/<lb_id> | 1186668/76/mno-uuid |
gcore_dns_zone | <zone_name> | example.com |
Find project and region IDs in the Gcore Customer Portal or via the data "gcore_cloud_project" and data "gcore_cloud_region" data sources; resource UUIDs appear in the portal URL and in Gcore API responses. Check the Import section of the specific resource page on Terraform Registry for the exact format.
Inspect and manage state
After import, use terraform state subcommands to inspect what is recorded:
# List all resources in state
terraform state list
gcore_cloud_project.default
# Show full details of a resource in state
terraform state show gcore_cloud_project.default
# gcore_cloud_project.default:
resource "gcore_cloud_project" "default" {
client_id = 1000503
created_at = "2026-04-17T12:43:36Z"
description = "Default project"
id = 1186668
is_default = true
name = "Default"
state = "ACTIVE"
}
# Remove a resource from state without destroying it
terraform state rm gcore_cloud_project.default
Removed gcore_cloud_project.default
Successfully removed 1 resource instance(s).
terraform state rm removes the resource from Terraform’s tracking only. The actual Gcore resource is not deleted. Use it to stop managing a resource with Terraform without destroying it.