[PYTHON] Déploiement groupé avec CFn pour prendre des instantanés manuels d'Elastic Search Service avec Lambda

Déployez le mécanisme d'acquisition d'instantanés manuel avec Cloudformation à la fois avec Amazon Elasticsearch Service (AES). Et il est configuré pour supprimer automatiquement les anciens instantanés à l'aide de Curator. Il est étonnamment difficile de prendre un instantané.

Les scripts Python sont basés sur ceux trouvés dans cette documentation AWS.

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/curator.html

Chose que tu veux faire

Faites ceci. Le script est presque le même que celui de la documentation AWS, donc je pense que c'est un niveau que vous pouvez facilement comprendre en le lisant. Il y a aussi des commentaires.

image.png

Besoin d'instantanés manuels

En juillet 2019, les instantanés automatiques ont été améliorés comme suit, et les instantanés horaires sont désormais stockés dans S3 pendant 14 jours.

https://aws.amazon.com/jp/about-aws/whats-new/2019/07/amazon-elasticsearch-service-increases-data-protection-with-automated-hourly-snapshots-at-no-extra-charge/

Cela seul est très pratique car il vous permet de revenir à la situation une heure avant la panne même lorsque des données sont perdues en raison d'une panne simultanée de plusieurs nœuds.

Cependant, les instantanés automatiques sont pris dans un compartiment S3 géré, de sorte que tout est supprimé lorsque le domaine est supprimé.

Il existe également des restrictions telles que l'impossibilité de restaurer un instantané sur un autre domaine, par exemple lorsque vous souhaitez faire une duplication d'un domaine.

Je pense qu'il y a pas mal de besoins pour utiliser les définitions de Kibana et les cartes d'index dans différents domaines. Pour cela, il est bon de prendre un instantané manuel en parallèle avec l'instantané automatique.

Bien qu'il existe une URL de référence

Il n'existe qu'un service éprouvé et des informations officielles sur ce domaine.

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/curator.html

Cependant, même si je copie ceci sur Lambda tel quel, cela ne fonctionne pas. La bibliothèque utilisée dans l'exemple de script Python doit être configurée afin de pouvoir être importée séparément par Lambda.

En outre, IAM et d'autres paramètres sont nécessaires pour effectuer des instantanés manuels. Il y a un manuel ici, mais si vous n'y êtes pas habitué, vous ne saurez pas quoi faire.

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html

Dans cet article, le but est de créer un environnement dans lequel ce programme (une version légèrement modifiée) fonctionne.

Lieu de travail

C'est la prémisse de l'opération effectuée dans cet article.

Côté terminal de travail

Au minimum, les machines Linux ou Mac avec les éléments suivants installés: (Au fait, je travaille sur wsl2)

Côté AWS

--Amazon Elasticsearch Service a été déployé avec le type d'accès VPC

Méthode d'exécution

Télécharger depuis Github

Téléchargez le référentiel suivant depuis Github.

$ git clone [email protected]:yomon8/aes-snapshot-sample.git
$ cd aes-snapshot-sample/

https://github.com/yomon8/aes-snapshot-sample

Réglage du fichier de réglage

Entrez les variables dans le fichier de configuration.

$ cp settings.sh{.sample,}
$ vim settings.sh

Il existe les éléments suivants, définissez-les en fonction de votre environnement.

#Nom de la pile Cloudformation
readonly STACK_NAME=es-snapshot-sample

#Bucket pour télécharger des packages Cloudformation
readonly STACK_S3_BUCKET=bucket-name
readonly STACK_S3_PREFIX=es-snapshot-sample

#Nom d'hôte AES (AES est créé sur l'hypothèse d'un accès VPC)
readonly AES_HOST=vpc-xxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com

#Spécifiez le sous-réseau pouvant accéder à AES
readonly LAMBDA_SUBNET_ID=subnet-xxxxxxxxxxxxxxxxxxxxxx

#Spécifiez SG qui peut accéder à AES
readonly LAMBDA_SECURITY_GROUP_ID=sg-xxxxxxxxxxxxxxxxxxx

#Nom de l'emplacement de stockage des instantanés AES
readonly SNAPSHOT_REPOSITORY_NAME=your-repo

#Préfixe avec le nom de l'instantané AES
readonly SNAPSHOT_PREFIX=your-snapshot

Déploiement de Cloudformation

Après cela, appuyez sur le script de déploiement et vous avez terminé. Le premier téléchargement du logiciel Layer prend beaucoup de temps. Cela prend moins de 10 minutes dans mon environnement.

$ ./deploy.sh
~ Omis ~

Enregistrer le référentiel de snapshots

Quand je lance deploy.sh, j'obtiens le message suivant à la fin.

1.Exécutez la commande suivante une fois au début.
aws lambda invoke --function-name aes-snapshot-sample-AESRegistSnapshotRepositoryFun-1SHIY9NWSSH8B:live /dev/null

Comme le message l'indique, lorsque vous exécutez la commande, Lambda pour l'enregistrement du référentiel sera exécuté.

$ aws lambda invoke --function-name aes-snapshot-sample-AESRegistSnapshotRepositoryFun-1SHIY9NWSSH8B:live /dev/null
{
    "StatusCode": 200,
    "ExecutedVersion": "1"
}

Vérifions si le référentiel est enregistré. Un référentiel appelé my-repo est enregistré.

GET _cat/repositories?v
id           type
cs-automated   s3
my-repo        s3

Faites une sauvegarde

À ce stade, je viens d'enregistrer le référentiel, il n'y a donc pas d'instantané. Même si vous accédez à l'API suivante, l'instantané ne doit pas être affiché.

GET _cat/snapshots/my-repo

Vous devriez voir un autre message dans deploy.sh pour prendre un instantané.

2.Pour prendre un instantané manuellement, exécutez la commande suivante.   
De plus, ce Lambda est également configuré pour planifier l'exécution.
aws lambda invoke --function-name aes-snapshot-sample-AESRotateSnapshotFunction-1GB4JKXMNZ8KQ:live /dev/null

Vous pouvez obtenir une sauvegarde en exécutant la commande affichée ici.

$ aws lambda invoke --function-name aes-snapshot-sample-AESRotateSnapshotFunction-1GB4JKXMNZ8KQ:live /dev/null
{
    "StatusCode": 200,
    "ExecutedVersion": "1"
}
GET _cat/snapshots/my-repo?v
id                            status start_epoch start_time end_epoch  end_time duration indices successful_shards failed_shards total_shards
my-snapshot-2019-11-13-12-35 SUCCESS 1573647456  12:17:36   1573647456 12:17:36    459ms       1                 1             0            1

Vous pouvez confirmer que les données de l'instantané sont également incluses dans S3.

image.png

De plus, comme la sauvegarde est configurée pour démarrer pendant un certain temps dans CloudWatch Event, elle fonctionne une fois par jour sans exécuter la commande comme décrit ci-dessus.

image.png

Vous pouvez ajuster la planification dans la partie suivante de template.yaml. À part le calendrier, je viens d'apporter quelques scripts, donc veuillez les ajuster et les utiliser.

      Events:
        Rule:
          Type: Schedule
          Properties:
            Schedule: cron(5 16 * * ? *)

Que fais tu

Vous pouvez voir ce que vous faites en regardant le contenu de deploy.sh.

elasticsearch et Curator sont téléchargés avec Docker, créés et téléchargés en tant que couche Lambda.

#!/bin/bash

#Lire le fichier de paramètres
source ./settings.sh

#Téléchargez la bibliothèque Python requise en tant que couche Lambda
docker run --rm -v $(pwd)/layer/python:/python python:3.7.5-alpine pip install -t /python requests-aws4auth elasticsearch elasticsearch-curator

#Déployer avec Cloudformation
aws cloudformation package --template-file ./template.yaml --output-template-file ./package.yaml \
    --s3-bucket ${STACK_S3_BUCKET} \
    --s3-prefix ${STACK_S3_PREFIX} 
aws cloudformation deploy --template-file ./package.yaml --capabilities CAPABILITY_IAM \
    --stack-name ${STACK_NAME} \
    --parameter-overrides \
    AESHost=${AES_HOST} \
    LambdaSubnetId=${LAMBDA_SUBNET_ID} \
    LambdaSecurityGroupId=${LAMBDA_SECURITY_GROUP_ID} \
    SnapshotRepositoryName=${SNAPSHOT_REPOSITORY_NAME} \
    SnapshotPrefix=${SNAPSHOT_PREFIX} 

#Affichage des messages
echo ""
echo "1.Exécutez la commande suivante une fois au début."
echo aws lambda invoke --function-name $(aws cloudformation describe-stacks --stack-name ${STACK_NAME} --query 'Stacks[].Outputs[?OutputKey == `RegistSnapshotFunctionName`].OutputValue' --output text):live /dev/null
echo ""
echo "2.Pour prendre un instantané manuellement, exécutez la commande suivante."
echo "De plus, ce Lambda est également configuré pour planifier l'exécution."
echo aws lambda invoke --function-name $(aws cloudformation describe-stacks --stack-name ${STACK_NAME} --query 'Stacks[].Outputs[?OutputKey == `RotateSnapshotFunctionName`].OutputValue' --output text):live /dev/null
echo ""

Restaurer l'instantané

Si vous enregistrez S3 où l'instantané est stocké en tant que référentiel de la même manière, vous pouvez facilement le restaurer en suivant la procédure liée ci-dessous.

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html#es-managedomains-snapshot-restore

référence

https://github.com/elastic/curator

[Note de conseils] Restaurer l'index non-Kibana

Souvent, vous souhaitez restaurer autre chose que Kibana. Vous pouvez restaurer des index autres que Kibana en exécutant ce qui suit. Vous ne pouvez restaurer qu'un index spécifique en modifiant le paramètre d'index.

POST _snapshot/Nom du référentiel/Nom de l'instantané/_restore
{"indices": "*,-.kibana_1"}

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html#es-managedomains-snapshot-restore

Recommended Posts

Déploiement groupé avec CFn pour prendre des instantanés manuels d'Elastic Search Service avec Lambda
Envoyer une demande d'AWS Lambda à Amazon Elasticsearch Service
Jusqu'à ce que vous obteniez un instantané du service Amazon Elasticsearch et que vous le restauriez
Exporter un instantané RDS vers S3 avec Lambda (Python)
Mémo connecté à HiveServer2 d'EMR avec python
Prenez des captures d'écran LCD avec Python-LEGO Mindstorms
Entrez les données Zaim dans Amazon Elasticsearch Service avec Logstash
Je veux lier une variable locale avec lambda
Une collection de techniques professionnelles compétitives à résoudre avec Python
Comment afficher une liste des versions installables avec pyenv