How to replace aws_elasticsearch_domain with aws_opensearch_domain

I am trying to switch a resource from aws_elasticsearch_domain to aws_opensearch_domain. Currently I am using aws_elasticsearch_domain/OpenSearch like this:

resource "aws_elasticsearch_domain" "my-search-service" {
  domain_name           = "my-search-${var.environment}"
  elasticsearch_version = "OpenSearch_1.1"
...
cluster_config {
    instance_type            = "m5.large.elasticsearch"
...

I renamed the resource from aws_elasticsearch_domain to aws_openearch_domain - the name of this resource stayed the same. Then I followed the guide " Elasticsearch vs. OpenSearch" and I did:

  • renamed elasticsearch_version to engine_version
  • renamed instancy_typ suffix from elasticsearch to search
  • didn’t have to change the roles
  • I didn’t change the version, it stayed OpenSearch_1.1

The new version:

resource "aws_opensearch_domain" "my-search-service" {
  domain_name    = "my-search-${var.environment}"
  engine_version = "OpenSearch_1.1"
....
cluster_config {
    instance_type            = "m5.large.search"
...

So the Terraform plan for such a change is it will:

Plan: 1 to add, 1 to change, 1 to destroy.
aws_elasticsearch_domain.my-search-service will be destroyed
aws_opensearch_domain.my-search-service will be created

So it didn’t detect that this is a replacement. Is it possible to switch in a non-destructive way? I would like to replace the cluster and its data, not create a new one from scratch

Hi @BartlomiejSkwira,

From Terraform’s perspective each resource type is distinct from one another because each one has its own schema and so Terraform would need a provider’s help to safely convert data from one schema to another. The provider protocol doesn’t currently have any way to do that, so unfortunately a more manual approach is needed in situations like this.

The most straightforward approach here, I think, would be to use terraform import to import the existing object into the new resource address, and then use terraform state rm to unbind it from its old address so that Terraform won’t think it needs to be destroyed due to that address no longer being present.

1 Like

Makes sense, thanks @apparentlymart