Come to see again at part 5. All 4 parts is about creating a new resource and developing in tf scripts.

The next question is, what to do if we want to develop the tf scripts on the existing resources?


Import an existing resource

It might be a case that we have manually created some resources before/without maintaining in our Terraform stacks. Don't worry, we can enlist them into. This is called Terraform import.

Terraform import can only importing resources' states into our state file, so we have to update the tf scripts ourselves which is not quite a big deal.

Let's say, we created two buckets manually like this.

There are 2 choices to import a resource into Terraform depends on how we currently design and manage the scripts.

resource in main scripts

If we go easy by writting resources in a single main folder, now we can do the following steps.

  1. Prepare an empty resource
  2. Import the state by referring the resource
  3. Show the state and update in tf scripts
  4. Verify tf scripts

1. Prepare an empty resource

2. import the state to the resource

Run the command.

terraform import -var-file="<var-file>" \
    '<resource_type>.<resource_name>' <resource_address>

var-file is for when we are using variables in the scripts, or Terraform will ask for the values.

Resource type and name are what we define in the tf script.

Resource address can be generated in the format given in Terraform registry. For this case, GCS bucket's address format is here which is <project_name>/<bucket_name> or just bucket_name.

3. Show state and update scripts

Once the import is done successfully. We can list and see its configurations.

terraform state list
terraform state show <state_name>

Then copy the config into the resource block.

4. Verify scripts

Then we can plan to see any missing between state and scripts.

Oops! we got errors. There we can see unconfigurable attributes for self_link and url and id is invalid key. These are attributes we don't need in the resource block so we delete them out.

Try plan again and yes we did it. It says no change now.

resource in modules

1. Prepare an empty resource

We can prepare a module resource like this.

and include it into the main script as follow.

2. import the state to the resource

When it comes to modules, we just change a bit on the command here.

terraform import -var-file="<var-file>" \
    'module.<module_name>.<resource_type>.<resource_name>' <resource_address>

In this case:

  • module_name is "bucket" as defined in the main script
  • resource_type is "google_cloud_storage_bucket" as defined in the module
  • resource_name is "bucket_in_module" as it is in the module as well

And it should show that the module's resource has been imported successfully, like this.

When list the state, we can see the module's state there.

3. Show state and update scripts

Then show the module's state.

terraform state list
terraform state show <state_name>

and copy into the resource block in the module.

4. Verify scripts

Finally try plan to see "no change" and that's mean we're done now.


Update state

Say we have manually updated some configs on the existing resources we have in Terraform state. For example, I changed my bucket class from "STANDARD" to "NEARLINE".

Only the bucket "bluebirz-manual-create-bucket-for_main" has been changed for the bucket class.

Fortunately, we have the state of this resource. Life is easier as we just update the state of this bucket using the command.

terraform apply -var-file="<var-file>" -refresh-only -auto-approve

Terraform will fetch and update the latest configurations to be matched between the state file and the cloud provider.

We can see what's been changed in the output of the command. And we have to update our scripts as well for those changed configs.