An important point to understand about Terraform is that it can only manage configuration it created or was explicitly told about after the fact. The reason for this limitation is that Terraform expects to be authoritative for the resources it manages. It relies on two types of files to understand what resources it controls and what state they are in. Terraform determines when and how to make changes from the following:
A configuration file ↗ (ending in .tf) that defines the configuration of resources for Terraform to manage. This is what you worked with in the tutorial steps.
A local state file ↗ that maps the resource names defined in your configuration file — for example, cloudflare_load_balancer.www-lb — to the resources that exist in Cloudflare.
When Terraform makes calls to Cloudflare’s API to create new resources as explained in the tutorial, it persists those IDs to a state file. By default, Terraform uses the terraform.tfstate file in your directory, but this can also be a remote location ↗. These IDs are later looked up and refreshed when you call terraform plan and terraform apply.
If you configured Cloudflare through other means, for example, by logging in to the Cloudflare dashboard or making curl calls to api.cloudflare.com, Terraform does not yet have these resource IDs in the state file. To manage this preexisting configuration, you will need to first reproduce the configuration in your config file and then import resources individually by providing their IDs and resource names.
cf-terraforming
cf-terraforming ↗ helps existing Cloudflare customers get started with Terraform. Currently, cf-terraforming helps to generate the Terraform config state by fetching all the resources of a specified type from the account and/or zone of your choosing.
Installation
Before you start, you must install cf-terraforming.
If you use Homebrew on macOS, open a terminal and run the following commands:
To start managing existing Cloudflare resources in Terraform, for example, DNS records, you need:
The Terraform configuration of that resource (defined in a .tf file)
An accompanying Terraform state file of that resources state (defined in a .tfstate file)
Generate Terraform configuration with cf-terraforming
If you do not have a Terraform configuration file defined, you need the provider block defined as follows:
Remember to keep your credentials saved in environment variables or terraform autovars that are not checked into your source files.
Start by making a call to cf-terraforming generate to generate the Terraform configuration for the DNS records in the zone you want to manage with Terraform.
If you had not redirected the output to the importing-example.tf file, the result displayed in the standard output (your terminal window) would look like the following:
Calling terraform plan at this point will try to create these resources as if they did not exist, since they are not present in the local state file:
To fix this, you must import the real state of those resources from Cloudflare into the Terraform state file (.tfstate).
Import resources into Terraform state
cf-terraforming allows you to import local state (.tfstate file) for the same resources you imported during configuration.
When you run cf-terraforming import ..., you will obtain a list of terraform import ... commands that you must run manually afterward to import those resources into Terraform state. This is currently a manual process, but it may be automated in the future.
Run the following command:
Copy each terraform import ... command included in the output and run it. Terraform will import each resource individually into Terraform state.
For example, if the output of the first command (cf-terraforming import ...) contained the following terraform commands:
You would run each command individually in the terminal:
If you now run terraform plan, you will notice that Terraform will no longer try to re-create the cloudflare_record resources: