Let's try: Terraform part 5 – import & update
in this series
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.
- Prepare an empty resource
- Import the state by referring the resource
- Show the state and update in
tf
scripts - 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 scriptresource_type
is "google_cloud_storage_bucket" as defined in the moduleresource_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.