When using tfvars terraform want to replace the resource, instead of creating a new resource

Hi All,

hope you can help out with my question.
i want to create new resources using the tfvars method. However instead of creating new resources, terraform wants to replace resources… i’m unsure what i’m doing incorrect…
this is my code:

resource "aws_security_group" "allow_tls" {
  name        = "allow_tls ${var.env}"
  description = "Allow TLS inbound traffic"
  vpc_id      = data.aws_vpc.main.id

  ingress {
    description      = "TLS from VPC"
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = var.ips

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = [""]
    ipv6_cidr_blocks = ["::/0"]

  tags = {
    Name = "allow_tls-${var.env}"

the variable file is:

variable "env" {}

and my tfvars files look like:

env = "int"

my test.tfvars file:

env = "test"

i was expecting that when i run 2 plans with the tfvars files i would end up with 2 resources, however i end up with 1 resource that terraform want’s to replace…
i’m using Tf version 1.3.1

to give some context: i’m creating multiple resources in my terraform code, also based on tfvars. i’m also destroying these resources. to make sure i only destroy resource that are part of an environment i want to create various security groups

any help would be greatly appreciated!

As far as Terraform is concerned, first you told it to create a resource, and then you told it to change that existing resource from having one name to another. In the case of this resource type, I guess that change needs a destroy and recreate.

Having multiple pre-prepared tfvars files is not the same as having entirely separate environments that Terraform manages independently.

There are various ways to achieve that, but the simplest might be to make a complete copy of your code in a different directory, per environment.

to my understanding:

  • using tfvars can be used to differentiate between environments and its resources that terraform creates, in the examples hashicorp provides, ec2 instances are also created with different instance types, using tfvars files.
  • the variable “env” creates a new name based on the input of the tfvars file, but it seems terraform sees the resources as allready existing…

simply copying the code to a different directory is exactly what i wanted to avoid, i wanted to be sure that my code base would be 100% the same for every environment.

Only as part of a larger configuration setup, in which Terraform runs using a separate state file per environment as well.

are you sure? if i read the documentation on the website, the use case presented for tfvars is exactly what i want to achive.

related to different state files, i presume you refer to workspaces(?)


If you want to discuss some documentation you’ve found, you’ll need to provide a link.

The term workspace is unfortunately rather overloaded within Terraform. There is the concept of workspace built in to the Terraform CLI, then there is a separate workspace concept existing in Terraform Cloud/Enterprise, and then there are other workspace-like arrangements that some people build in their custom automation around Terraform.

But yes, this general concept.

this link .

Perhaps my initial concept of the use case for tfvars files wasn’t correct.
I was hopping it would create (new) resources and destroy said resources based on the tfvars file provided with the plan/destroy and leave resource that are created / destroyed via other tfvars files alone.
This seems inline with the link provided.

All that link says, is that input variables can be specified as files. Nothing on that page says anything about that enabling multiple environments that are managed independently.

For that you need some flavour of the workspaces concept - e.g. something from Managing Workspaces - Terraform CLI | Terraform | HashiCorp Developer.

If you’d like me to try to make a more targeted suggestion, you’d have to share how you are managing storage of your Terraform state, and triggering of Terraform runs.

To be honest, that is implied in that article in my opinion. What else would the use case be for multiple tfvars files?

i store the tstate file in S3, at the moment i just run terraform via the cli, like:

terraform plan -var-file="int.tfvars" -out=terraform.tfplan

so nothing special. once the code is done i will create a pipeline for it.

You are seeing what you want to see instead of what is actually written then.

An example use case would be scaling a deployment up and down by providing separate tfvars files to define small/medium/large scaling.

According to

the S3 backend supports storing different workspace’s states at different keys in S3.

Therefore you could proceed by using the built in Terraform CLI workspace support to separate your environments.

For this to work, you’d have to ensure you always matched the correct workspace with the correct -var-file - you may well want to write your own wrapper script to help with this.

The current workspace can be selected using the terraform workspace select command described on Managing Workspaces - Terraform CLI | Terraform | HashiCorp Developer, but for automation, you may find selecting workspaces using the TF_WORKSPACE environment variable to be easier: Environment Variables | Terraform | HashiCorp Developer