Migrating an Elasticsearch service
This guide covers one way of migrating an elasticsearch domain to another. The steps listed here are specific to migrating an elasticsearch domain to enable encryption of data at rest.
Step 1 - Configure s3 snapshot repository for backup and restore
Adding an s3 snapshot repository to the elasticsearch is a 2-step process.
-
Create an s3 bucket
Use the below code block and update the values appropriately for your namespace. Raise a PR against the environments repository.
module "es_snapshots_s3_bucket" {
source = "github.com/ministryofjustice/cloud-platform-terraform-s3-bucket?ref=4.5"
team_name = var.team_name
acl = "private"
versioning = false
business-unit = var.business-unit
application = var.application
is-production = var.is-production
environment-name = var.environment-name
infrastructure-support = var.infrastructure-support
namespace = var.namespace
providers = {
aws = aws.london
}
}
resource "kubernetes_secret" "es_snapshots" {
metadata {
name = "es-snapshot-bucket"
namespace = var.namespace
}
data = {
bucket_arn = module.es_snapshots_s3_bucket.bucket_arn
bucket_name = module.es_snapshots_s3_bucket.bucket_name
}
}
- Add s3 bucket arn to the source elasticsearch module as below:
module "source_es" {
source = "github.com/ministryofjustice/cloud-platform-terraform-elasticsearch?ref=3.8.0"
cluster_name = var.cluster_name
cluster_state_bucket = var.cluster_state_bucket
application = var.application
business-unit = var.business-unit
environment-name = var.environment-name
infrastructure-support = var.infrastructure-support
is-production = var.is-production
team_name = var.team_name
elasticsearch-domain = "source-example-es"
namespace = var.namespace
elasticsearch_version = "7.9"
aws-es-proxy-replica-count = 2
instance_type = "t2.medium.elasticsearch"
s3_manual_snapshot_repository = module.es_snapshots_s3_bucket.bucket_arn
}
module "ns_annotation" {
source = "github.com/ministryofjustice/cloud-platform-terraform-ns-annotation?ref=0.0.2"
ns_annotation_roles = [module.source_es.aws_iam_role_name]
namespace = var.namespace
}
This output es_snapshot_role will have permissions to enable the creation of a manual snapshot repo in s3 bucket
resource "kubernetes_secret" "es_snapshots_role" {
metadata {
name = "es-snapshot-role"
namespace = var.namespace
}
data = {
snapshot_role_arn = module.example_es.snapshot_role_arn
}
}
Step 2 - Spin up a new ES domain with “encrypt at rest” enabled.
- Register the same snapshot repository on the source domain and the new domain
- Add the
aws_iam_role_nameof source ES domain and new encrypted ES domain to thens_annotationmodule. - Provide a different name to
aws-es-proxy-serviceso it does not overwrite the existing source proxy.
module "encrypted_es" {
source = "github.com/ministryofjustice/cloud-platform-terraform-elasticsearch?ref=3.8.0"
cluster_name = var.cluster_name
cluster_state_bucket = var.cluster_state_bucket
application = var.application
business-unit = var.business-unit
environment-name = var.environment-name
infrastructure-support = var.infrastructure-support
is-production = var.is-production
team_name = var.team_name
elasticsearch-domain = "encrypted-example-es"
encryption_at_rest = true
node_to_node_encryption_enabled = true
namespace = var.namespace
elasticsearch_version = "7.9"
aws-es-proxy-service = "aws-es-proxy-service-encrypted"
aws-es-proxy-replica-count = 2
instance_type = "t3.medium.elasticsearch"
s3_manual_snapshot_repository = module.es_snapshots_s3_bucket.bucket_arn
}
module "ns_annotation" {
source = "github.com/ministryofjustice/cloud-platform-terraform-ns-annotation?ref=0.0.2"
ns_annotation_roles = [module.source_es.aws_iam_role_name, module.encrypted_es.aws_iam_role_name]
namespace = var.namespace
}
Step 3: Stop all apps connected to the Elasticsearch domain
Step 4: Register both Elasticsearch domains
- Port forward the source ES domain using the proxy
aws-es-proxy-service
kubectl \
-n [your namespace] \
port-forward \
svc/aws-es-proxy-service 9200:9200
-
Register the snapshot repository with new encrypted Elasticsearch domain
A sample template is given below:
PUT http://localhost:9200/_snapshot/<repo name for snapshot>
{
"type": "s3",
"settings": {
"bucket": "<s3 bucket for snapshots>",
"region": "eu-west-2",
"role_arn": "<role arn from es_snapshots_role secret>"
}
}
- Port forward the encrypted ES domain using the proxy
aws-es-proxy-service-encrypted
kubectl \
-n [your namespace] \
port-forward \
svc/aws-es-proxy-service-encrypted 9200:9200
-
Register the snapshot repository with encrypted Elasticsearch domain
A sample template is given below:
PUT http://localhost:9200/_snapshot/<repo-name-for-snapshot>
{
"type": "s3",
"settings": {
"bucket": "<s3-bucket for snapshots>",
"region": "eu-west-2",
"role_arn": "<role arn from es_snapshots_role secret>"
}
}
For more details on Elasticsearch REST APIs see ES API.
Step 5: Backup and Restore snapshots
- Port forward the source ES domain using the proxy
aws-es-proxy-service
kubectl \
-n [your namespace] \
port-forward \
svc/aws-es-proxy-service 9200:9200
- Create a snapshot
PUT http://localhost:9200/_snapshot/<repo-name-for-snapshot>/<snapshot-to-restore>
- Port forward the encrypted Elasticsearch domain
kubectl \
-n [your namespace] \
port-forward \
svc/aws-es-proxy-service-encrypted 9200:9200
- Restore snapshot
NOTE: "include_global_state":true will restore all the key data
POST http://localhost:9200/_snapshot/<repo-name-for-snapshot>/<snapshot-to-restore>/_restore
{
"include_global_state": true
}
Step 6: Connect apps to new ES
Update the application to use the new encrypted es_proxy service.
Step 7: Clean up
Cleanup the portforward pods and the unwanted elasticsearch service
For more details on backup snapshots and restore, see aws documentation
Was this page useful?