Take into account the tfvars file provided. Presently, during the execution of “terraform test,” all resources undergo provisioning and deprovisioning for testing. However, if the intention is to exclusively test the “New_Resource” while maintaining the “Existing_Resource” untouched, or to skip the provisioning and deprovisioning steps for the existing resource, is there a method within Terraform tests to accomplish this?
variable resource_group_variables = {
“resource_group_1” = {
resource_group_name = “Existing_Resource”
resource_group_location = “eastus2”
resource_group_managed_by = “blabla” #(optional) The ID of the resource or application that manages this Resource Group.
resource_group_tags = {
Created_By = “testuser”,
Department = “IT”
}
},
“resource_group_2” = {
resource_group_name = “New_Resource” #(Required) Name of the Resouce Group with which it should be created.
resource_group_location = “westus”
resource_group_managed_by = “blabla”
resource_group_tags = {
Created_By = “testuser”,
Department = “IT”
}
}
}
Hi @anoop.pc, hopefully I’m understanding your question. You can specify the -target
argument within Terraform Test run blocks as a way to selectively test specific resources:
run "test" {
plan_options {
target = [
resource_type.resource_name,
resource_type.other_name[0],
]
}
}
The above code snippet would only update the targeted resources, and any resources needed by the targeted resources in the dependency graph.
Thanks for a your response.
I’m seeking a solution that allows me to utilize “terraform test” for existing resources that have already been provisioned. Whenever there’s a modification to any attributes or dependencies of a provisioned resource, the “terraform test” command, which operates in memory, always attempts to provision new resources and raises errors, stating that the “resource already exists.”
Hi @anoop.pc, what you’re describing isn’t possible with the terraform test
command. The test command should be executed in a separate environment from your live infrastructure. This ensures that running the test command won’t modify or break anything you have running in production.
Note that running a normal terraform plan
or terraform apply
command would achieve what you are describing - in which the new infrastructure is provisioned as described in your configuration.
In addition, you can use Custom Conditions within your regular Terraform configuration. These operate in the same way as assertions within test files, and would allow you to run a terraform plan
command and validate the new infrastructure that will be created, in much the same way the terraform test
command would, without starting from an empty state file.
Official Terraform 1.8.5 Repo via JARaaS Hybrid RAG - Documentation - code current 6/17/2024
Note: Sources at the end of the response
To achieve selective Terraform testing where only the new resources are tested, while existing resources remain untouched, you can employ the use of targeting with the -target
option in the terraform plan
and terraform apply
commands.
Here’s how you can approach this:
-
Identify the Resource Addresses: Determine the resource addresses for both the “New_Resource” and the “Existing_Resource”. For example:
resource_group_1
has the addressazurerm_resource_group.resource_group_1
resource_group_2
has the addressazurerm_resource_group.resource_group_2
-
Use Target Option in Terraform Plan: Use the
-target
option to specify the resource you want to include in the plan. For instance, to include onlyresource_group_2
(New_Resource), execute:terraform plan -target=azurerm_resource_group.resource_group_2
-
Apply Target Option in Terraform Apply: Similarly, apply the target option to exclusively apply changes to the new resource:
terraform apply -target=azurerm_resource_group.resource_group_2
For selective testing within Terraform, you can also integrate Terraform’s null_resource
and triggers
to simulate testing without impacting real resource provisioning. Here’s a brief section of how you can implement null_resource
:
resource "azurerm_resource_group" "existing" {
name = var.resource_group_variables["resource_group_1"].resource_group_name
location = var.resource_group_variables["resource_group_1"].resource_group_location
tags = var.resource_group_variables["resource_group_1"].resource_group_tags
}
resource "azurerm_resource_group" "new" {
name = var.resource_group_variables["resource_group_2"].resource_group_name
location = var.resource_group_variables["resource_group_2"].resource_group_location
tags = var.resource_group_variables["resource_group_2"].resource_group_tags
}
resource "null_resource" "test" {
triggers = {
new_resource_name = azurerm_resource_group.new.name
}
provisioner "local-exec" {
command = "echo Testing new resource: ${self.triggers.new_resource_name}"
}
}
By using the above approach, you can ensure only the new
resource group undergoes testing, while the existing
resource group remains unchanged.
Sources:
- Main Terraform Specification: main.tf (internal document)
- Shared Variable Definitions: variables.tf (internal document)