Terraform 101: Command Line Interface
This post is part of my Terraform 101 series, exploring how MacAdmins can use Infrastructure as Code to manage Apple environments.
Previously: Resources and Data Sources
In the last post, we looked at resources and data sources. Now let’s see how those declarations come to life using the Terraform Command Line Interface (CLI).
The CLI is how you interact with Terraform: initializing a project, previewing changes, applying updates, and cleaning up resources. It’s also where you’ll see Terraform’s declarative nature in action by analyzing the difference between your configuration and reality, then taking the steps needed to bring them in sync.
Understanding the Terraform Workflow
Terraform’s CLI workflow revolves around three main phases:
- Write – Describe your infrastructure in
.tfconfiguration files. - Plan – See the changes Terraform will do (like a dry run).
- Apply – Make the changes described above.
You’ll use the CLI for each phase, and Terraform will guide you through what’s about to happen.
terraform init
Before you can do anything, you must initialize your project:
terraform init
This command:
- Downloads the provider plugins defined in your configuration (like
axm). - Sets up local caches and directories (e.g.
.terraform/). - Prepares your working directory for future commands.
You’ll typically only need to run init once per project. It’s also needed any time you add or upgrade providers.
If you’ve been following along with this Terraform 101 series, we already ran this command after installing terraform.
terraform plan
This is where Terraform starts showing off its declarative power.
plan looks at your configuration and your current environment, then figures out what needs to happen to reach your declared state.
terraform plan
Terraform will output a summary of the actions it intends to take. For example:
Terraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# axm_device_management_service.iru will be updated in-place
~ resource "axm device_management_service" "iru" {
~ device ids = [
- "FAKE000ABC123"
+ "FAKE222GHI789",
# (2 unchanged elements hidden)
]
id = "FAKE0000111122223333444444444444"
}
PLan: 0 to add, 1 to change, ø to destroy.
Lines starting with + represent resources to be created, - represent deletions, and ~ represent changes. Nothing actually happens during a plan. It’s a dry run.
This is your chance to double-check Terraform’s understanding before approving any changes.
terraform apply
Once you’ve reviewed the plan, it’s time to apply it.
terraform apply
Terraform will:
- Re-run the plan (to ensure nothing changed in the meantime).
- Prompt for confirmation.
- Perform the actions needed to reach the declared state.
When complete, you’ll see a summary.
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
At this point, your declared configuration matches the real environment.
Saving a Plan File
Usually, you’ll want to make sure that the configuration you reviewed with plan is exactly the same one that gets used when you apply. To do that, you can save the plan output to a file.
terraform plan -out=plan.tfplan
Later, instead of re-running the plan (which could pick up new changes), you can apply exactly what you reviewed.
terraform apply "plan.tfplan"
This workflow is especially important in automated pipelines or compliance workflows. It guarantees that the plan you approved is the one being executed.
terraform show
After applying, you can inspect the current state of your infrastructure with:
terraform show
This prints out the values Terraform knows about, including outputs and resource attributes. It’s a great way to verify that your resources exist and contain the expected data.
terraform destroy
Sometimes you need to remove everything your configuration created. That’s where destroy comes in:
terraform destroy
Terraform will generate a plan showing what it intends to remove, then prompt you for confirmation before proceeding.
This is particularly useful when testing new configurations or performing a full teardown of a development environment.
⚠️ Be careful! This command permanently deletes the resources managed by your configuration. Always double-check which environment you’re in.
Additional Helpful Commands
Here are a few more CLI commands you’ll use regularly:
terraform fmt— Formats your.tffiles to standard Terraform style.terraform validate— Checks syntax and verifies that configuration is valid.terraform output— Displays any defined output values from your configuration.terraform providers— Lists the providers used in your project.
These commands don’t modify your infrastructure but are great for keeping things clean and correct.
Bringing It All Together
Now that you’ve seen how init, plan, and apply work individually, we can envision a full continuous integration (CI) for Terraform projects.
- Write or modify your
.tffiles. - Run
terraform init(if this is the first time or you’ve added providers). - Run
terraform validateto check for issues. - Run
terraform plan -out=plan.tfplanto preview changes. - Run
terraform apply plan.tfplanto make them real. - (Optional) Run
terraform destroyto clean up.
Make sure you are running these commands from within your Terraform working directory (the one containing your .tf files). By default, the Terraform CLI looks in the current working directory for the configuration files.
Wrapping Up
With these commands, you’ve seen the complete Terraform workflow in action — from initialization through planning, applying, and even tearing down. These steps form the basis of any Terraform project, whether you’re testing locally or automating with CI/CD.
If you’ve followed along with this series, you should now feel comfortable creating, inspecting, and managing Terraform configurations. I don’t currently have another post planned in this series, but I do intend to continue writing about Terraform workflows and MacAdmin-oriented infrastructure automation in the future.
Let me know if any step felt unclear or if you’d like to see a topic expanded or introduced (modules, remote backends, CI integration, etc.). Your feedback helps shape future posts.
Lastly, if you’ve made it this far: thank you. I hope this series helped demystify Terraform and gave you the confidence to use it in your environment.
Series Index
- Terraform 101: Introduction
- Terraform 101: Getting Started
- Terraform 101: Variables and Secrets
- Terraform 101: Resources and Data Sources
- Terraform 101: Command Line Interface
Comments