terraform init
- initialises the working directory by downloading provider plugins and source modules.terraform validate
- checks configuration file syntax.terraform fmt
– formats configuration files.terraform plan
- creates an execution plan that compares the desired state to the known state.terraform apply
- core command used to create resources according to plan.terraform destroy
- removes resources according to known state.Note: Only constant values are allowed in this block no variable references.
Provider plugins are downloaded by terraform cli and used to interact with Cloud APIs e.g. the azure provider communicates with the Microsoft Azure API. They have their own release cycles and version numbers.
This is contained within the terraform block and includes the source and version as shown below:
terraform {
required_version = ">= 1.0.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 2.0"
}
}
}
The source is prefixed with registry.terraform.io by default.
This block allows you to change the default behaviour of a provider such as:
Note: You can call a provider alias and thus feature settings in a resource block.
provider "azurerm" {
features {}
}
Note: Local names should match between the required_providers and provider block. It is recommended to use the vendor preferred name e.g. azurerm but you could use anything in theory.
It prevents you from updating a provider plugin version. It is best practice to check in the lock file into your code repository.
terraform init -upgrade
- this will upgrade the lock file if you decide to change the allowed provider versions.
Note: It only includes provider version tracking not Terraform cli nor modules.
When you navigate to the terraform registry list of providers you will notice they have 1 of 3 badges:
It contains:
resource "azurerm_resource_group" "resource_group" {
location = "uksouth"
name = "rg-01"
}
A block within a resource block e.g. Ip_configuration {}
in azurerm_network_interface
resource.
Note: Whereas, tag = {} is an argument using a map value.
Note: It first destroys and then recreates. You can change this behaviour using meta-arguments.
terraform apply
is executed a state file is created - terraform.tfstate.
terraform destroy
will remove configuration from the Cloud environment for the resource(s) that are contained within the state file.Note: It is not recommended to manually edit the state file nor store it locally.
Changes behaviour of resource blocks:
Note: Provisioners & Connections are not meta-arguments, they can invoke extra actions after resource creation or destruction e.g. install app on VM.
depends_on = [
azurerm_virtual_network.vnet1,
azurerm_subnet.subnet1
]
${Count.index}
– can be used to set a value based on the instance number:resource "azurerm_public_ip" "pip" {
count = 2
name = "pip-${count.index}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
allocation_method = "Static"
}
azurerm_public_ip.pip[0]
.For_each = {
Dev = "myapp1"
}
Each.key = dev
Each.value = myapp1
for_each = azurerm_network_interface.nic
lifecycle {
create_before_destroy = true
}
lifecycle {
prevent_destroy = true
}
lifecycle {
ignore_changes = [ tags, ]
}
This can be used to read the contents of a file e.g. obtain ssh public key within azurerm_linux_virtual_machine
resource block.
admin_ssh_key {
username = "localadmin"
public_key = file("${path.module}/ssh-keys/key.pub")
}
This can be used to read the contents of a file Base64-encoded e.g. used by the Custom_data argument within azurerm_linux_virtual_machine
resource block to reference cloud init file that can configure a VM.
custom_data = filebase64("${path.module}/scripts/cloud_init.txt")
element(list, index)
, for example:element(["blue","red","green"], 1)
red
length(["blue","red","green"])
3
resource "azurerm_resource_group" "rg" {
for_each = toset([ "uksouth", "ukwest" ])
name = "rg-${each.key}"
location = each.key
}
The following example illustrates how to reference an instance of a NIC when both resource block azurerm_windows_virtual_machine
and azurerm_network_interface
are using the count
meta-argument:
network_interface_ids = [
element(azurerm_network_interface.winvm_nic[*].id, count.index)
]