Create terraform resource (S3 Bucket Object) if already doesn't exists

Create the terraform resource based on the data source output condition.

Hi all,
I want to achieve the below requirement in Terraform.

Requirement:

I want to create object (with key_name) in s3 bucket.
Before creating the object need to check whether the object with same key already exists or not using data source.
If it is already exists, do not create object. If not do create the object in s3 bucket.

Source Code

variable "key_name" {
  default = "test.txt"
}
variable "bucket_name" {
  default = "test-bucket-654321"
}

data "aws_s3_bucket_objects" "my_objects" {
  bucket = var.bucket_name
}

locals {
  key_present = anytrue([
	for key in data.aws_s3_bucket_objects.my_objects.keys: key == var.key_name
  ])
}

resource "aws_s3_bucket_object" "examplebucket_object" {
  count = local.key_present ? 0 : 1
  
  key     = var.key_name
  bucket  = var.bucket_name
  content = "Test Value"
}

output "my_objects" {
  value = data.aws_s3_bucket_objects.my_objects.keys
}
output "key_present" {
  value = local.key_present
}

Let’s assume, key is does not exists in the bucket (For example, it is a new bucket with no objects)

  1. On applying 1st time, it creates the object in bucket.
  2. On applying 2ns time, it destroy the created object in bucket.
  3. On applying 3rd time, it creates the object in bucket.

On 1st time, data source returns empty value. so it creates the object in bucket.
On 2nd time, data source returns created object name. so the key is already exists and it destroys the object in bucket.

Likewise every odd number of times it creates the objects and every even number of times it destroys the created object.

Output:

ubuntu@test-instance:~$ terraform apply --auto-approve
aws_s3_bucket_object.examplebucket_object[0]: Creating...
aws_s3_bucket_object.examplebucket_object[0]: Creation complete after 0s [id=test.txt]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:
key_present = false
my_objects = tolist([])

ubuntu@test-instance:~$ terraform apply --auto-approve
aws_s3_bucket_object.examplebucket_object[0]: Refreshing state... [id=test.txt]
aws_s3_bucket_object.examplebucket_object[0]: Destroying... [id=test.txt]
aws_s3_bucket_object.examplebucket_object[0]: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Outputs:
key_present = true
my_objects = tolist([
  "test.txt",
])

Could anyone give me the solution for creating a terraform resource based on the data source output ?

1 Like

Did you found any solution?

Terraform is designed to support the declarative creation of resources.

As a result of its target use cases, it does not provide support for a “create if not already exists” operation.

Common options are:

  1. Explicitly specify in the Terraform configuration whether to create the resource, or use an existing resource. This would usually involve a boolean variable, that is used to vary the count of a resource, and a data source between 0 and 1, so that only one of them is processed, and then also used in a ? : expression to fetch information from whichever of the resource or data source exists.

  2. Decide that Terraform is not the right tool for your particular problem, and use something else.

1 Like