Ingeniería

Migración de AWS Elasticsearch a Elasticsearch Service en Elastic Cloud

Accede a todas las características del Elastic Stack

Como arquitecto de soluciones, me suelen preguntar cómo trasladar un despliegue de Elastic de Amazon Elasticsearch Service (AWS ES) a Elasticsearch Service.  Principalmente me preguntan porque los usuarios desean beneficiarse con todas las características, los conocimientos técnicos y el soporte de Elastic, que no están disponibles en Amazon. Esta guía profesional te guiará por el proverbial proceso de realojamiento (lift-and-shift) a Elasticsearch Service de Elastic.

Para comenzar con Elasticsearch Service, se puede obtener una prueba de 14 días gratuita que permite crear un despliegue. Puedes seleccionar el proveedor Cloud, AWS o GCP y la región en la que prefieras ejecutar Elastic en el despliegue.  Los usuarios de AWS pueden agregar el servicio Elasticsearch directamente desde AWS Marketplace, integrado en la facturación de AWS.

Hay pocas capacidades que superan los elementos disponibles en la distribución de código abierto, como Canvas, APM, Machine Learning sin supervisión,índices congelados, SQL, seguridad (fuera de las políticas IAM y redes perimetrales básicas) y plantillas de despliegue, que son exclusivas de Elasticsearch Service en Elastic Cloud. Todo el tiempo se agregan más capacidades excepcionales. Para conocer más sobre lo que hacemos en relación con AWS ES, visita nuestra página de comparación de AWS Elasticsearch periódicamente.

Migración de AWS Elasticsearch a Elasticsearch Service en Elastic Cloud

Es una guía bastante técnica para migrar de AWS ES a Elasticsearch Service en Elastic Cloud y requiere algo de experiencia en programación. Los clusters de AWS ES comúnmente se provisionan en una VPC, pero también pueden incluirse en un punto de conexión público. Con el fin de que esta guía sea universal para ambas situaciones, usamos el AWS SDK de Python. Puedes usar cualquier idioma que cuente con AWS SDK (por ejemplo, Java, Ruby, Go, etc.), pero nosotros ofrecemos únicamente ejemplos en Python a continuación.

Esta guía cuenta con dos partes:

Nota: Si ya tomaste manualmente la snapshot del cluster de AWS ES para S3, puedes omitir la parte dos.

Antes de comenzar, es importante comprender algunos de los pasos de seguridad de IAM que se presentan a continuación. Primero, para tomar la snapshot de un cluster de AWS ES en S3, el clúster necesita permiso para escribir un depósito S3 privado. Esto requiere una política y rol de IAM con los permisos necesarios. Además, necesitaremos asignar una política de IAM a un usuario de IAM (si es necesario, se crea una). Nuestro script usa tu usuario de IAM para comunicarse con tu cluster de AWS ES, así como tu despliegue administrado por Elastic para leer la snapshot desde tu depósito S3.

Parte uno: Snapshot para S3

La primera parte de esta guía incluye la configuración del rol de IAM, así como la política y el usuario, para tomar snapshots del cluster de AWS ES para S3. La documentación de AWS para este proceso se encuentra aquí: Trabajo con snapshots del índice de Elasticsearch Service de Amazon. Puede usarse como referencia si se presentan obstáculos.

Deberás anotar varias variables que usarás en el proceso. Copia y pega la siguiente tabla en un archivo de notas, el cual puedas consultar a lo largo de esta guía. Así será más fácil rellenar los valores específicos de tu migración.

DescripciónVariableValor
ARN de dominio de AWS ES DOMAIN_ARN
URL de punto de conexión de AWS ES ES_ENDPOINT
Región de AWS ES ES_REGION
Nombre de depósito de AWS S3 S3_BUCKET_NAME
Región de AWS S3 S3_REGION_NAME
ARN de rol de AWS IAM ROLE_ARN
ID de clave de acceso de AWS IAM ACCESS_KEY
Clave de acceso secreta de AWS IAM SECRET_KEY
Repositorio de snapshots de AWS ES SNAPSHOT_REPO my-snapshot-repo
Nombre de snapshot de AWS ES SNAPSHOT_NAME my-snapshot

Puedes cambiar los valores de SNAPSHOT_REPO y SNAPSHOT_NAME o usar los ejemplos proporcionados (por ejemplo, “my-snapshot-repo” y “my-snapshot”).

Paso 1: Obtener la información de AWS ES

Necesitaremos algunos datos básicos sobre tu cluster de AWS ES para crear una snapshot para S3.

  1. En tu consola de AWS, dirígete a Elasticsearch Service.
  2. Selecciona el dominio del cluster que deseas capturar con snapshot.
  3. Copia el valor del “ARN de dominio” en el archivo de notas (DOMAIN_ARN)
  4. Copia el valor de la URL del “punto de conexión” en el archivo de notas (ES_ENDPOINT)
  5. Anota en qué región de AWS (por ejemplo, us-east-1) se encuentra tu cluster de AWS ES (ES_REGION)

Esta información se usa abajo en la creación de la política de IAM y cuando es momento de enviar comandos al cluster.

Paso 2: Crear un depósito S3 de AWS

Debemos crear un depósito S3 para almacenar tu snapshot.

Importante: El depósito S3 debe estar en la misma región que el cluster de AWS ES. Podrás restaurar a partir de allí en un despliegue administrado por Elastic en cualquier región o proveedor Cloud (AWS o GCP).

  1. En su consola de AWS, dirígete al servicio S3.
  2. Crea un depósito S3 privado.
    Nota: Si dejas los valores predeterminados, el depósito será privado y seguro.
  3. Copia el nombre del depósito en el archivo de notas (S3_BUCKET_NAME)
  4. Copia la región del depósito en el archivo de notas (S3_REGION_NAME)

Esta información se usa cuando registramos un repositorio de snapshots en Elasticsearch.

Paso 3: Crear un rol de IAM

A continuación, crearemos un rol para delegar permiso a Elasticsearch Service de Amazon para que tome una snapshot en S3.

  1. En la consola de AWS, dirígete al servicio de IAM.
  2. Selecciona “Roles”.
  3. Selecciona “Crear rol”.
  4. Selecciona “EC2” como el servicio que usará este nuevo rol (lo cambiaremos más adelante).
  5. Selecciona “Siguiente: Permisos”.
  6. Deja las políticas de rol vacías por ahora.
  7. Selecciona “Siguiente: Etiquetas”.
  8. Selecciona “Siguiente: Revisar”.
  9. Nombre del rol: TheSnapshotRole
  10. Selecciona “Crear rol”.
  11. Selecciona el rol que acabamos de crear de la lista de roles: TheSnapshotRole
  12. Selecciona “Relaciones de confianza”.
  13. Selecciona “Editar relaciones de confianza”.
  14. Copia y pega lo siguiente en la relación de confianza (reemplaza lo que haya).

    {
     "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "Service": "es.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }]
    }
    
  15. Selecciona “Actualizar política de confianza”.
  16. Selecciona “Permisos”.
  17. Selecciona “Agregar política en línea”.
  18. Selecciona la pestaña JSON.
  19. Copia y pega el siguiente JSON (reemplaza lo que haya).
  20. Reemplaza S3_BUCKET_NAME con el valor correcto (en dos lugares).

    {
      "Version": "2012-10-17",
      "Statement": [{
          "Action": [
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME"
          ]
        },
        {
          "Action": [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME/*"
          ]
        }
      ]
    }   
  21. Selecciona “Política de revisión”.
  22. Asigna un nombre a la política: TheSnapshotS3Policy
  23. Selecciona “Crear política”.
  24. Copia el valor del “ARN de rol” en el archivo de notas (ROLE_ARN)

Acabamos de crear un rol de IAM con una política en línea que puedes leer y escribir en el depósito S3.

Paso 4: Crear una política de IAM

Necesitamos crear una nueva política de IAM que tenga permiso para asumir el rol anterior a fin de registrar el repositorio de snapshots.

  1. En la consola de AWS, dirígete al servicio de IAM.
  2. Selecciona “Políticas”.
  3. Selecciona “Crear política”.
  4. Selecciona la pestaña JSON.
  5. Copia y pega el siguiente JSON (reemplaza lo que haya).
  6. Reemplaza ROLE_ARN con el valor correcto.
  7. Reemplaza DOMAIN_ARN con el valor correcto.
  8. Reemplaza S3_BUCKET_NAME con el valor correcto (en 2 lugares).

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "iam:PassRole",
          "Resource": "ROLE_ARN"
        },
        {
          "Effect": "Allow",
          "Action": "es:ESHttpPut",
          "Resource": "DOMAIN_ARN/*"
        }
      ]
    }
    
  9. Selecciona “Política de revisión”.
  10. Asigna un nombre a la política: TheSnapshotPolicy
  11. Selecciona “Crear política”.

Recién creamos una política de IAM que permite al rol de IAM comunicarse con tu dominio de AWS ES.

Paso 5: Crear un usuario de IAM

Si aún no cuentas con un usuario de IAM, necesitaremos crear uno y darle acceso a tu depósito S3 privado. Si ya cuentas con un usuario de IAM, tan solo asígnale la siguiente política de IAM.

  1. En la consola de AWS, dirígete al servicio de IAM.
  2. Selecciona “Usuarios”.
  3. Selecciona “Agregar usuario”.
  4. Nombre del usuario: TheSnapshotUser
  5. Marca la casilla “Acceso programático”.
  6. Selecciona “Siguiente: Permisos”.
  7. Selecciona la casilla “Asignar políticas existentes directamente”.
  8. Filtra las políticas escribiendo “TheSnapshot”.
  9. Selecciona la casilla de verificación junto a la política “TheSnapshotPolicy”.
  10. Selecciona “Siguiente: Etiquetas”.
  11. Selecciona “Siguiente: Revisar”.
  12. Selecciona “Crear usuario”.
  13. Copia el valor “ID de clave de acceso” en el archivo de notas (ACCESS_KEY)
  14. Selecciona “Mostrar” en “Clave de acceso secreta”.
  15. Copia el valor “Clave de acceso secreta” en el archivo de notas (SECRET_KEY)
  16. Selecciona “Cerrar”.
  17. Selecciona el usuario que acabamos de crear de la lista de usuarios: TheSnapshotUser
  18. Selecciona “Agregar política en línea”.
  19. Selecciona la pestaña JSON.
  20. Copia y pega el siguiente JSON (reemplaza lo que haya).
  21. Reemplaza S3_BUCKET_NAME con el valor correcto (en 2 lugares).

    {
      "Version": "2012-10-17",
      "Statement": [{
          "Action": [
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME"
          ]
        },
        {
          "Action": [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME/*"
          ]
        }
      ]
    }
    
  22. Selecciona “Política de revisión”.
  23. Asigna un nombre a la política: TheSnapshotUserS3Policy
  24. Selecciona “Crear política”.

Acabamos de crear un usuario de IAM que puede tomar una snapshot manual y leerla.

Paso 6: Configurar el AWS SDK de Python

Antes de ejecutar una snapshot manual, debemos registrar un repositorio de snapshots con el despliegue. Para ello, se debe enviar una solicitud firmada a tu cluster de AWS ES. Una de las maneras más fáciles de hacerlo es con el AWS SDK de Python. Puedes usar otro AWS SDK (por ejemplo, Java, Ruby, Go, etc.), pero el siguiente ejemplo usa el AWS SDK de Python.

Instalaremos el AWS SDK de Python usando el PIP de instalación (pip3). Debes tener instalado Python v3. Si no cuentas con Python v3 instalado, puedes obtenerlo con solo instalar el pip3. El administrador de paquetes de tu sistema operativo instalará Python v3 automáticamente, debido a que es una dependencia del pip3. Si encuentras obstáculos, consulta los documentos de instalación de Python.

Instalación del pip3

Para instalar el pip3 en Red Hat y derivados, usa yum:

$ sudo yum -y install python3-pip

Como alternativa, algunas distribuciones de Fedora etiquetan el paquete pip3 de forma diferente:

$ sudo yum -y install python36-pip

Puedes buscarlo si ninguno de los nombres anteriores del paquete funcionan:

$ yum search pip

En derivados de Debian, como Ubuntu, usa apt-get:

$ sudo apt-get -y install python3-pip

Instalación de AWS SDK de Python

Una vez instalado pip3, puedes instalar el AWS SDK de Python llamado boto3:

$ pip3 install --user boto3 requests_aws4auth
Recopilación de boto3
...
Successfully installed boto3-1.9.106 requests-aws4auth-0.9 ...

Nota: No se necesita acceso a raíz si especifica el marcador --user.

Necesitamos crear un directorio ~/.aws para almacenar nuestras credenciales de AWS. Ejecuta el siguiente comando para crear el directorio:

$ mkdir ~/.aws

Crea un archivo llamado credenciales con tu editor favorito. Usaremos nano para que sea más simple:

$ nano ~/.aws/credentials

Copia y pega el siguiente contenido en el archivo, pero reemplaza las 2 variables en mayúscula.

[default]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY

Usa ctrl+x para salir de nano, y sigue las indicaciones para guardar el archivo.

A continuación, escribiremos algunos scripts de Python para realizar las tareas que necesitamos.

Paso 7: Tomar snapshot en forma manual AWS ES

Ejecutemos una prueba rápida usando un script de Python para enumerar los índices en nuestro cluster de AWS ES. De este modo, nos aseguramos de que nuestras credenciales de AWS funcionen y probamos que podemos comunicarnos con el cluster.

Crea un archivo llamado indices.py con tu editor favorito. Usaremos nano para que sea más simple:

$ nano indices.py

Copia y pega el siguiente contenido, pero reemplaza las dos variables en mayúscula con tus valores:

import boto3, requests
de requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Listing Indices from AWS ES ...")
solicitud = requests.get(host + '/_cat/indices?v', auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

Usa ctrl+x para salir de nano, y sigue las indicaciones para guardar el archivo.

Ejecuta el script de Python.

$ python3 indices.py

La salida debe ser similar a lo siguiente:

Lista de índices de AWS ES ...
Código de respuesta HTTP: 200
health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   testindex yME2BphgR3Gt1ln6n03nHQ   5   1          1            0      4.4kb          4.4kb

Ahora crea un archivo llamado register.py con tu editor favorito.

$ nano register.py

Copia y pega el siguiente contenido, pero reemplaza las siete variables en mayúscula con tus valores.

import boto3, requests
de requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
s3_region_name = 'S3_REGION_NAME'
s3_bucket_name = 'S3_BUCKET_NAME'
role_arn = 'ROLE_ARN'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
headers = {"Content-Type": "application/json"}
payload = {
        "type": "s3",
        "settings": {
                "region": s3_region_name,
                "bucket": s3_bucket_name,
                "role_arn": role_arn
        }
}
print("Registering Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name
req = requests.put(url, auth=auth, json=payload, headers=headers)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

Usa ctrl+x para salir de nano, y sigue las indicaciones para guardar el archivo.

Ejecuta el script de Python.

$ python3 register.py

La salida debe ser similar a lo siguiente:

Registro de snapshot con AWS ES ...
Código de respuesta HTTP: 200
{"acknowledged":true}

A continuación, crea un archivo llamado register.py con tu editor favorito.

$ nano snapshot.py

Copia y pega el siguiente contenido, pero reemplaza las cuatro variables en mayúscula con tus valores:

import boto3, requests
de requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Starting Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name + '/' + snapshot_name
req = requests.put(url, auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

Usa ctrl+x para salir de nano, y sigue las indicaciones para guardar el archivo.

Ejecuta el script de Python.

$ python3 snapshot.py

La salida debe ser similar a lo siguiente:

Comenzar snapshot con AWS ES ...
Código de respuesta HTTP: 200
{"accepted":true}

Nota: El tiempo necesario para tomar una snapshot aumenta según el tamaño del dominio de AWS ES. Según la documentación de AWS, las operaciones de snapshot de ejecución larga algunas veces muestran el mensaje “504 GATEWAY_TIMEOUT”. Sus documentos indican que puedes ignorar este error y solo esperar a que la snapshot finalice satisfactoriamente.

Por último, veamos el estado de nuestra snapshot. Crea un archivo llamado status.py.

$ nano status.py

Copia y pega el siguiente contenido, pero reemplaza las cuatro variables en mayúscula con tus valores:

import boto3, requests
de requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Getting Status of Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name + '/' + snapshot_name + '?pretty'
req = requests.get(url, auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

Usa ctrl+x para salir de nano, y sigue las indicaciones para guardar el archivo.

Ejecuta el script de Python.

$ python3 status.py

La salida debe ser similar a lo siguiente:

Obtención del estado de snapshot con AWS ES ...
Código de respuesta HTTP: 200
{
  "snapshots" : [ {
    "snapshot" : "my-snapshot",
    "uuid" : "ClYKt5g8QFO6r3kTCEzjqw",
    "version_id" : 6040299,
    "version" : "6.4.2",
    "indices" : [ "testindex" ],
    "include_global_state" : true,
    "state" : "SUCCESS",
    "start_time" : "2019-03-03T14:46:04.094Z",
    "start_time_in_millis" : 1551624364094,
    "end_time" : "2019-03-03T14:46:04.847Z",
    "end_time_in_millis" : 1551624364847,
    "duration_in_millis" : 753,
    "failures" : [ ],
    "shards" : {
      "total" : 5,
      "failed" : 0,
      "successful" : 5
    }
  } ]
}

Si ves "state":"SUCCESS", entonces se tomó satisfactoriamente la snapshot en S3 y estás listo para la parte dos.

Parte dos: Restauración desde S3

La segunda parte de esta guía supone la restauración de un despliegue administrado por Elastic desde una snapshot manual en S3.

Puedes provisionar un despliegue administrado por Elastic en AWS o GCP para esta parte de la guía.

Paso 1: Tamaño del despliegue

El despliegue que se creó en Elasticsearch Service en Elastic Cloud debe tener la misma cantidad de recursos que el cluster de AWS ES. Usa los controles deslizantes y aumenta el número de nodos de datos para reflejar el tamaño del cluster que tienes en AWS ES. Guarda los cambios antes de continuar.

Paso 2: Agregar un repositorio personalizado

En el despliegue administrado por Elastic (no el cluster de AWS ES), abra Kibana y dirígete a “Herramientas de desarrollo”.

Copia y pega el siguiente API en Herramientas de desarrollo, pero reemplaza las cinco variables:

PUT /_snapshot/SNAPSHOT_REPO
{
  "type": "s3",
  "settings": {
    "bucket": "S3_BUCKET_NAME",
    "region": "S3_REGION_NAME",
    "access_key": "ACCESS_KEY",
    "secret_key": "SECRET_KEY",
    "compress": true
  }
}

Ejecuta la solicitud.

Debes recibir la siguiente respuesta:

{
  "acknowledged": "true"
}

Ya casi terminas.

Paso 3: Restauración desde S3

Por último, es momento de restaurar el repositorio de snapshots que acabamos de registrar.

Copia y pega el siguiente API en Herramientas de desarrollo, pero reemplaza las dos variables:

POST /_snapshot/SNAPSHOT_REPO/SNAPSHOT_NAME/_restore

Debes recibir la siguiente respuesta:

{
  "accepted": "true"
}

Puedes verificar el progreso de la restauración con lo siguiente:

GET /_snapshot/SNAPSHOT_REPO/SNAPSHOT_NAME/_status

Si ves "state":"SUCCESS", la restauración finalizó satisfactoriamente:

{
  "snapshots": [
    {
      "snapshot": "my-snapshot",
      "repository": "my-snapshot-repo",
      "state": "SUCCESS",
      ...
    }
  ]
}

Felicitaciones por finalizar el proceso de realojamiento (lift-and-shift) de AWS ES a Elasticsearch Service.

Resumen

Ahora que te encuentras en Elasticsearch Service en Elastic Cloud, no solo puedes beneficiarse con las características que no están disponibles en AWS ES, sino que también tendrás la tranquilidad de que el despliegue será mantenido por los expertos que crearon el Elastic Stack. Si encuentras algún problema en el camino, los expertos del equipo de soporte de Elastic podrán ayudarte.  Si todavía no estás en Elasticsearch Service en Elastic Cloud, realiza una prueba gratuita de 14 días, y si tienes alguna pregunta, no dudes en contactarnos.