skip to Main Content

So i came across a scenario in terraform, where the requirement was check if a resource(lets say ec2) already exists in AWS and if it exits then do not create it.
Now i understand that if the ec2 "foobar" was created for the first time using terraform and then if we try to create it again, then terraform apply will say that no new changes were made to the infra. But what if resource ‘foobar` is already created manually or via any other tool, how does terraform handle the scenario in that case.

I understand that data block in terraform is used to retrieve the existing information and i tried to write something like this

data "aws_instance" "foobar"{
    filter {
        tags   = "name"
        values = ["foobar"]
  }
    most_recent = true
}

But this does not work, what would be a better way to handle this scenario

2

Answers


  1. Use Terraform’s external data source to run a script that checks if the EC2 instance exists. The script can return a value indicating whether the instance exists, and you can use this value in a count attribute to conditionally create the instance.For example

    data "external" "instance_check" {
      program = ["python", "${path.module}/check_instance.py"]
      query = {
        instance_name = "foobar"
      }
    }
    
    resource "aws_instance" "foobar" {
      count = data.external.instance_check.result["exists"] == "false" ? 1 : 0
      # ... other configuration ...
    }
    
    
    

    or ,you can use a data source to attempt to fetch the resource and a local value that determines if the resource should be created. i suppose that this method won’t stop Terraform from trying to create the resource if it’s not in the state, but it’s useful for information purposes. so i am sure that this approach will only work if the EC2 instance was tagged appropriately and the data source is able to locate it.

    data "aws_instance" "foobar" {
      filter {
        name   = "tag:Name"
        values = ["foobar"]
      }
      most_recent = true
    }
    
    locals {
      create_instance = length(data.aws_instance.foobar.ids) == 0
    }
    
    resource "aws_instance" "foobar" {
      count = local.create_instance ? 1 : 0
      # ... other configuration ...
    }
    
    
    
    Login or Signup to reply.
  2. Since Terraform is a desired-state system, the statement "create this if it doesn’t already exist" is not meaningful: it is an imperative command, rather than a desired state.

    Unfortunately, if you rephrase that into a declarative statement then you end up with a contradiction: "if the object exists then it doesn’t exist". If you were able to express that statement to Terraform then you’d end up with a configuration that can never converge, because after your initial terraform apply the object would then exist and so your configuration would declare that it should not exist, and thus Terraform would plan to destroy it.

    Instead, you must decide explicitly whether a particular Terraform configuration is either managing a particular object (a resource block) or depending on that object (a data block). There is no way to make that decision dynamically, because then it would be ambiguous whether a particular Terraform configuration is managing that object. For example, it would be unclear whether terraform destroy should destroy the object.

    If you have an existing object that was created outside of Terraform but you now want to use Terraform to manage it moving forward, then Terraform calls that concept "importing": it takes an existing object and associates it with one of the resource blocks in your configuration. If you run terraform import to create such an association, then Terraform will behave as if it had been the one to create that object originally, despite that not being true.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search