# terraform-elasticsearch

## Overview

> [!WARNING]
> Breaking changes! Starting with version 5.0.0, the Route 53 zone ID is automatically selected based on the environment.
> The `route53_zone_id` variable has been removed. See [Route 53 Records](#route-53-records) for more information.

> [!WARNING]
> Breaking changes! Starting with version 3.0.0, the module has been refactored to use a second provider for DNS record creation. This provider should be defined in the same directory as the module and should use the `networking` profile. See [Providers](#providers) for more information.

> [!WARNING]
> This terraform module 0.12 release should not be used to run against old terraformed elasticsearch instances that have node to node encryption disabled.

> [!INFO]
> By default, domains do not use node-to-node encryption, and you can't configure existing domains to use the feature. To enable the feature, you must create another domain and migrate your data. Node-to-node encryption requires Elasticsearch 6.0 or later.

## Description

Terraform module to create aws elasticsearch instances.

Note: By default encryption at rest, node to node encryption, fine-grained access control, and zone awareness are enabled when supported.

## Input variables

The module includes secure defaults, and most options will not need to be overridden. There are, however, a few values that you will almost always need to specify:

     var.env
     var.aws_es_domain_name
     var.aws_es_version
     var.aws_es_instance_type
     var.aws_es_instance_count
     var.aws_es_disk_size
     var.aws_es_disk_type
     var.zone_awareness_enabled

There are many other configurable settings that can be tuned to support a wide range of use cases. See variables.tf for specific parameters.

To spin up a domain using the newer OpenSearch engines instead of the ElasticSearch ones, enable variable `use_opensearch_engine`.

### Route 53 Records

The module manages Route 53 records for the domain by default. This can be disabled by setting the `route53_record_creation_enabled` variable to false.

The Route 53 Zone ID is automatically selected based on the environment. If `environment` is dev, the zone ID defaults to that of the `dev.theorchard.io` domain. Otherwise, the zone ID defaults to that of the `theorchard.io` domain.

If you require a different zone to the default selection, you can specify it using the `override_route53_zone_id` variable instead.

The Route 53 records are created in the AWS account specified by the `dns` provider. See [Providers](#providers) for more information.

### Providers

The module requires an explicitly defined second AWS provider which specifies where Route 53 records will be created.

If you are creating Route 53 records in the same account as the domain (e.g. in dev), you can simply alias the default provider as `dns` as follows:

```hcl
provider "aws" {
  region  = var.aws_region
}

module "elasticsearch" {
  source = "git@github.com:theorchard/terraform-elasticsearch.git//?ref=x.x.x"

  providers = {
    aws.dns = aws
  }

  // other settings
}
```

If you are creating Route 53 records in a different account to the domain (e.g. `theorchard.io`), you will need to define a second provider with the appropriate credentials:

```hcl
provider "aws" {
  region  = var.aws_region
}

provider "aws" {
  region  = var.aws_region
  alias   = "networking"
  profile = "networking"
}

module "elasticsearch" {
  source = "git@github.com:theorchard/terraform-elasticsearch.git//?ref=x.x.x"

  providers = {
    aws.dns = aws.networking
  }

  // other settings
}
```

## Outputs

Modules can also return values. This is done using output variables, which can be consumed by other pieces of terraform, and are located in outputs.tf. Examples:

```
output "aws_elasticsearch_domain_arn" {
  description = "Amazon Resource Name (ARN) of the domain"
  value       = aws_elasticsearch_domain.default.arn
}

output "aws_elasticsearch_domain_name_output" {
  description = "Name of the domain"
  value       = aws_elasticsearch_domain.default.domain_name
}
```

## Usage example

```
provider "aws" {
  region = "us-east-1"
}

provider "aws" {
  region  = var.aws_region
  alias   = "networking"
  profile = "networking"
}

variable "environment" {
  default = "qa"
}

variable "service_name" {
  default = "ows-service"
}

module "elasticsearch" {
  source = "git@github.com:theorchard/terraform-elasticsearch.git//?ref=x.x.x"

  providers = {
    aws.dns = aws.networking
  }

  env                    = var.environment              # Environment parameter (qa).
  aws_es_domain_name     = var.service_name             # Domain name, minus environment prefix (conflict-manager, ows-service).
  aws_es_instance_type   = "m5.large.elasticsearch"     # This is an example of overwriting module values. The instance type is t3 by default in the module.
  aws_es_instance_count  = 2                            # Create _n_ number of instances; 2 or more are required when zone awareness is enabled. Adjust the value as needed.
  aws_es_disk_size       = 20                           # EBS disk size.
  aws_es_disk_type       = "gp3"                        # EBS disk type.
}
```

## Elasticsearch limitations.

```
Encrypting at rest: T2, M3, and R3 instances type are not supported.
# Node-to-node Encryption: requires Elasticsearch 6.0 or later.
# By default, domains do not use node-to-node encryption, and you can't configure existing domains to use the feature. To enable the feature, you must create another domain and migrate your data. Node-to-node encryption requires Elasticsearch 6.0 or later.

KMS key WARNING:
If you delete the key that you used to encrypt a domain, the domain becomes inaccessible. The Amazon ES team can't help you recover your data. AWS KMS deletes master keys only after a waiting period of at least seven days, so the Amazon ES team might contact you if they detect that your domain is at risk.

Disabling Encryption of Data at Rest:
By default, domains don't encrypt data at rest, and you can't configure existing domains to use the feature. To enable the feature, you must create another domain and migrate your data. Encryption of data at rest requires Elasticsearch 5.1 or later.
```
