Condition blocks and Terraform
You can apply precondition and postcondition blocks to your resources in Terraform if you want to assume some properties will be true/false before apply or if you want to guarantee some properties will be true/false after apply when supplying your modules to consumers.
Rules for evaluating conditions
When Terraform evaluates the conditions it will try and apply them as early as possible. However, some resource properties are only available after apply, those that say (Known after apply) in your terraform plan
The result of a precondition or postcondition must be structured in a way that it can return either true or false
The scope for conditions inside the Terraform module
preconditions and postconditions will apply to resources in-scope of the Terraform Module, not other resources in your cloud unless you specify them inside the module with a data block for instance. You can use the self object on resources to evaluate them with the postcondition block to guarantee certain configuration properties.
Declaring more than one condition or mixing them with count & for_each
If you declare more than one condition and one or more fails, Terraform returns error messages for all conditions
If you specify a resource with a count or for_each setting along with a precondition block the condition will be evaluated after the count/for_each. This is to ensure the condition has the value of each result returned from each.key and count.index
When the postcondition fails
postcondition blocks will evaluate after the apply step has ran on a resource or after the read step is done on a data block resource. If a postcondition fails it will ensure resources that are depending on this failed resource are not updated.
precondition blocks can be used elsewhere as well, for example in output blocks. If this is true Terraform will evaluate the result before its passed to the value of the output.
Be smart about your condition blocks
It is smart not to litter your modules with a lot of condition blocks. If you have one resource with many dependencies, see if you can't create one postcondition block for this resource instead of several precondition elsewhere in the configuration.
Demo
I have written the following configuration in a module:
resource "azurerm_resource_group" "this" {
name = "rg-${var.environment}-${var.location_short}-conditiondemo"
location = var.location
}
resource "azurerm_storage_account" "this" {
name = "st${var.environment}${var.location_short}demo1337"
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
account_tier = var.account_tier
account_replication_type = var.account_replication_type
lifecycle {
precondition {
condition = contains(["westeurope", "swedencentral"], var.location)
error_message = "Allowed resource locations are West Europe and Sweden Central."
}
}
}The key here is the condition = contains(["westeurope", "swedencentral"], var.location) configuration inside the precondition block.
If I call my module using an incorrect location as such:

Leads to a failure:

If you want to mess around with this you can find all the code here:
Reference

About me
