# [筆記]terraform
### Summary
- HCL(HashiCorp Configuration Language)
- 只要結尾是.tf 都可以執行
- 通常會有一個resource.tf跟var.tf 最後會有一個terraform.tfvars
- 用變數不一定要使用type,但是建議使用以下是,terraform simple variable type
- string
- number
- bool
- complex type
- list
ex: [0,1,5,2] ,always return 0,1,5,2 not 5,1,2,0
- set
set like list, but it doesnt keep the order you put it in, and can only contain unique values
ex: [5, 1, 1, 2] becomes [1, 2, 5] in a set
- map
ex: {"key" = "vaule"}
- object
object like a map, but element can have a different type
ex: {firstname = "kevin", age = "18"}
- tuple
an tuple is like a list, but element can have a different type
ex: [0, "string", false]
- complex type最常使用的是 list 跟 map ,其他的偶爾使用
### basic commands:
- terraform apply - this command will read your .tf files and apply the terraform code to the provider you have configured, terraform will output the change it will make and ask if can make the change(add, change, delete), you can respond with "yes" to apply(or ues the auto-approve argument to automatically approve the change without asking)
- terraform plan - to see what change terraform would do without apply(沒有使用就是read what change)
- terraform init - every time you add a new module, init your terraform project
- terraform validate - check syntax error or something like that
- terraform destroy - you like to remove all the infrastructure you created, on Azure doesn't always work sometime it has troubles deleting so you need the resource group manually
- terraform help - to get full list all command you can use
- terraform fmt - format the *.tf make sure that it uses the correct formatting
- terraform taint - resource will be destroyed and recreated again
- terraform import - if you have already resources created manually and you want to manage them in terraform create the terraform code in a *.tf file, then run terraform import resource_type.resource_name unique-identifier
- terraform workspace - new,list,show select and delete terrafotm workspaces
the workspace cannot be used for a "fully isolated" setup that you'd need when you want to run terrafrom for multiple environments(staging / testing / prod),在現實環境寫好的modules是可以復用了,利用多個帳號拆分不同的環境來達成
- terraform state -
- terraform refresh - if at some point you'd like to update state file to reflect the "actual" state of your infrastructure, but you don't want to run terraform apply
### debug
- to enable more logging, you need to set the TF_LOG environment variable
- MacOS/Linux like this: TF_LOG=DEBUG terraform apply
- on windows in powershell, you can use: $Env:TF_LOG="DEBUG"
- log level: TRACE, DEBUG, INFO, WARN, ERROR
### Implement and maintain state
- the default backend in terraform is the local backend, this requires no configuration
- a terraform.tfstate file will be written to your project folder
- this is where the state is stored
- every time you run terraform apply, the state will be changed, and the file will be update
- if you start working in a team, you are going to wat to use a remote backend
- work with a remote state has benefits:
[Backend Overview - Configuration Language - Terraform by HashiCorp](https://www.terraform.io/docs/language/settings/backends/index.html)
- easily work in a team, as the state is separate from the code
- A remote backend can keep sensitive information off disk
- azure blob storage support encryption at rest, authentication & authorization
- remote operations: terraform apply can run for a long time in bigger projects, backend like remote backend, support remote operations that are executed fully remote, so that the whole operation runs asynchronously(在跳板機執行東西的概念)
- state locking ensures nobody can write to the state at the same time
- you need to be aware that secrets can be stored in your state file, if you have a remote then locally it'll not have stored on disk, it'll only be kept in memory when you run terraform apply
- For example when you create a database ,the initial database password will be in the state file
- make sure your remote state backend is protected sufficiently
- For example for azure blob storage, make sure only terraform administrator have access to this, enable encryption at rest, Also make sure that for every backend TLS is used when communicating with the backend
---
###### tags: `IaC` `Devops`