terraform
Table of Contents
1. Basic commands
terraform init terraform plan terraform plan -destroy # dry run terraform apply terraform destroy # using tfvars terraform plan -var-file=development.tfvars # state terraform show terraform state list # format terraform fmt terraform validate # debugging terraform console
2. Other notes
- After including a new module, you need to do
terraform init statecan contain sensitive info, so it usually needs some kind of credentials for access if using aremote backend. Better to use credentials as env vars..terraformdirectory not supposed to be version controlled- Ideally the infrastructure that is used by Terraform should exist outside of the infrastructure that Terraform manages.
2.1. Terraform AWS ubuntu AMI
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
# https://cloud-images.ubuntu.com/locator/ec2/
# NOTE: I found the value for this name by manually trying to creating an
# EC2 instance from the AWS console, there seems to be no other
# proper way
values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
}
filter {
name = "root-device-type"
values = ["ebs"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
3. FAQ
3.1. Variable substitution in resource names?
- Because the resource name is used only within the module, Terraform requires it to be a literal.
- Resource names is that they are scoped only to the module where you declare them, and so there is generally no need for them to be dynamic
- See this thread
3.2. Local variable vs Input variables
- Input variables
- Are usually declared in
variables.tfusingvariableblocks- Think of these variable declarations needed to make the module work (we pass these "into" the module)
- Naming the file variables.tf is merely a convention. (It just needs to have the
variableblock setup)
- Can be accessed in the module using
var - Can be passed using various mechanism of which
*.tfvarsand-varcli option are two ways.
- Are usually declared in
3.3. Parent and Child module and Input variables
*.tfvarsafaik only works for the root module- If you want to pass input variables into a child module you do it in the
moduleblock. However, you can source them from the root module's*.tfvars
3.4. Modules vs Data sources and Outputs & Inputs(Variables)
| Name | Description |
|---|---|
| Module | Collection of tf files (our envs are modules, our things inside modules directory, basically any number of tf files inside a directory) |
| Root Module | Caller module |
| Child Module | Callee module |
| Variables (Input) | This is the way we can interact with a module and alter its behavior (You'd use variables.tf and variable blocks for this) |
| Output | These are things we explicitly decide to export out of the module, once exported, the outputs get stored in tf state |
| Data Source | Use information defined outside of Terraform in your tf config |
| State Data Source | See remote state data source , this basically allows you to use data blocks to access tf state data of from some backend |
3.5. Calling of a module
- To call a module means to "include" the contents of that module into the configuration with specific values for its
input variables. - The "calling" happens via the
moduleblock