U:: [[Infrastructure as Code]]
## Migrating my Personal Stack to Terraform
* First stumbling block implementing, deciding state backends. If I didn't know about these from the start, I would've started with just the default local and would have to do an annoying migration to a new backend once it's all setup.
* Terraform Cloud really eases all of this. It's not just a wrapper; it actually provides useful hooks so that I don't have to set up much. The free plan is generous enough for my personal stack.
* Variables are kind of annoying in Terraform, I always seem to always need to keep defining them through every module level repeatedly.
## DigitalOcean Provider
* There's an [official one](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs). At the time of writing (Aug 2022) it didn't yet have support for the serverless features launched in May 2022.
## Linode Provider
* There's also a [Linode Provider](https://registry.terraform.io/providers/linode/linode/1.29.2) that allows me to operate in a richer way that DO.
## Kubernetes Provider
* There's an [official one](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) which is pretty clear and comprehensive.
* It's straightforward but tedious to convert the k8s yaml spec to terraform format, but I find that it allows me to really review so I didn't seek a tool to make this automated.
## Tips and Tricks
* If there's a resource that takes some time to create, then use a [`time_sleep`](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) resource in order to delay it.
* Use [provisioners](https://www.terraform.io/language/resources/provisioners/syntax) for provisioning things in an imperative way, it's only useful as a last resort, but I found it super useful for resetting root passwords and adding SSH keys to Linodes when they were created. Provisioners can provision things by running on the Terraform Runner, or SSH-ing into an instance so that you can perform setup tasks.
* For my Linode Kubernetes Cluster's nodes, I first used `local-exec` to make API requests to reset the root password, then subsequently SSH-ed in via `remote-exec` to do some provisioning tasks.
* The state can be easily inspected in Terraform cloud for debugging. I used to use "outputs" in modules to do this but found the state to be much more comprehensive.
* There are times when if you use name to fetch the ID using a `data` block, the resource and its depends will keep recreating with every apply. It's always better to just put the zone ID in directly to avoid this issue.