In this post, we talk about `terraform import`, what it’s used for, why you probably shouldn’t use it . . . but how you can use it anyways (because we’re not the boss of you). Read on!
Accelerate your career in cloud
Table of contents
What is `terraform import`used for?
Terraform is a popular open source tool for managing all sorts of infrastructure as code (IaC) — both cloud platforms and some on-prem solutions. (For the purposes of this post, we’re only gonna talk about cloud management, being A Cloud Guru and all).
It lets you define resources like VMs, databases, and networking configurations as Terraform code. Terraform then translates that code into resources in the cloud. It can be a really cool feeling to watch your whole system spin up as you listen to Disney Karaoke (or maybe that’s just me)
Terraform is used to create resources and to update resources that have been created by Terraform — and its very good at that. However, when most places first get started with Terraform, they have some infrastructure that was created manually — things like networking and Identity and Access Management are common examples of this. They need to be up and running before much else gets done in a shiny new cloud environment.
And so, usually, as organizations move more and more of their infrastructure to IaC, someone asks how they can manage those resources that weren’t defined as Terraform using Terraform. And that’s where the `terraform import` command comes in.
`terraform import` lets you target a resource that already exists, and map it to a resource you’ve defined in code.
Why shouldn’t you use `terraform import`?
The reason to avoid using `terraform import` is very pragmatic: it’s tricky to do correctly, especially for more complicated resources.
Terraform is designed to create resources and manage resources it creates. The import functionality works, but during the process, it’s very easy for settings to be changed.
Given our use case is trying to import infrastructure that is fairly fundamental — networking and IAM — this creates very high risk for far-reaching disruptions to the environment. If you break your SSO integration during the import, that will affect all users who access the environment using that identity provider. Similarly, if networking settings are changed, that can cause entire VPCs to lose connectivity.
Since most custodians of these sorts of environments won’t be willing to accept that kind of risk, its often more effective to create a parallel resource from scratch using Terraform and, once it’s been configured correctly, begin a gradual migration to the Terraformed resource.
For example, rather than importing a VPC, all the associated subnets, firewall rules, ACL, and everything else, create a new VPC and child resources. Once the Terraformed VPC is up and running, you can migrate VMs over. If the VMs are also Terraformed, then that should be a matter of updating the VPC attribute and reapplying.
Of course, real life is rarely that tidy, but this is a case of choosing the less messy of two options.
How do you use `terraform import`?
If my argument doesn’t move you and you’ve decided importing existing resources is the way to go — and who knows, context is king, it very well may be that circumstances tie your hands — then best of luck.
When you run the import command, you need to provide two arguments: a Terraform expression for the resource you’ve defined in your code, and a unique identifier for the resource you want to import.
This varies depending on the type of resource you want to import, it’s usually a name or id. You can check the Terraform docs for a specific resource type. Terraform then matches the resource in the cloud to the resource you’ve defined in your code block.
However, you then need to reconcile the attributes of the resource as it is with how it is described in the code. Once you have updated the attributes in the code to match the configuration, you can run `terraform plan` to find all the attributes that don’t match that you didn’t catch.
Once the plan command reports no changes to be made, you can run `terraform apply`.
At this point, Terraform takes the wheel. Even if the apply doesn’t make changes, for core services like networking, there can be a lot of dependencies that experience service disruption. If something goes wrong, good luck.
But, if nothing breaks, then congratulations! You’ve successfully imported an existing resource into Terraform management. You can now make changes by running `terraform apply` — plus you get to tell me I was making it sound way worse than it actually was.
Learn more about Terraform
Want to learn more about advanced use cases with Terraform? Check out my new course, Advanced Terraform with GCP. If you love Terraform and are excited to build bigger, better solutions in GCP with Terraform, this course is for you.
- We cover how to level up your Terraform code using modules, outputs, locals, and more to create robust, dynamic solutions.
- Then, we look at Terraform functions to make your code more flexible, so you can write once, apply many times.
- Next, we put that to the test, automating your Terraform code in full CI/CD pipelines to support multiple environments from a single code base.
- Finally, we meet the HashiCorp family and look at some other DevOps and cloud management tools that can make sure that your Terraformed Google Cloud is the best it can be!
Ready to get get started? Sign up for a free trial today!