Quelldateien
Sie finden alle Quelldateien für diese Sicherungs- und Wiederherstellungslösung in unserem offiziellen Repository und können sie herunterladen, verändern und für nicht-kommerzielle Zwecke verwenden.
Sie finden sie hier.
Einführung in Amazonas Kognito
Mit Amazon Cognito können Sie ganz einfach Benutzeranmeldung, Anmeldung und Zugriffskontrolle zu Ihren mobilen und Webanwendungen hinzufügen. Amazon Cognito lässt sich auf Millionen von Benutzern skalieren und ist hochgradig zugänglich, da es die Anmeldung bei sozialen Identitätsanbietern wie Facebook, Apple, Google und Amazon sowie bei Unternehmensidentitätsanbietern über OpenID Connect und SAML 2.0 unterstützt.
Wenn Sie jedoch einen Amazon Cognito User Pool sichern müssen, werden Sie feststellen, dass es keine native Lösung von Amazon gibt. Glücklicherweise verfügt Amazon User Pool über eine sehr flexible API, die wir verwenden werden, um unsere Benutzer zu sichern.
Es ist von entscheidender Bedeutung, alle Benutzerprofile und verknüpften Daten zu sichern, da dies eine wichtige Rolle bei der Vermeidung von Unfällen (z. B. unbeabsichtigtem Datenverlust) spielt. Darüber hinaus sind sie auch in anderen Fällen unerlässlich, z. B. bei der Migration von Benutzerdaten in einen neuen Benutzerpool. Aus diesen Gründen möchte ich Ihnen heute meine selbst entwickelte Lösung vorstellen.
Maßgeschneiderte Backup-Wiederherstellungslösung für Amazon Cognito-Benutzer
Die Verwaltung von Daten ist eine schwierige Aufgabe, und genau dann kommen Backups zur Hilfe und verhindern, dass sie Probleme verursachen. Aber wie kann man Backups sicherstellen, wenn der Dienst, auf den Sie sich verlassen, keine Backup-Lösung anbietet? Die Antwort ist ziemlich einfach: Bauen Sie selbst eine! Und genau das werden wir in diesem Lernprogramm tun.
Diese Lösung ist maßgeschneidert, aber so konzipiert, dass sie für eine Vielzahl von Anwendungsfällen geeignet ist. In unserer Schritt-für-Schritt-Anleitung erfahren Sie, wie Sie eine Sicherungs- und Wiederherstellungslösung für Amazon Cognito-Benutzer entwickeln.
In diesem Lernprogramm wird der Kern der Implementierung und nicht die gesamte Einrichtung der Architektur behandelt. Weitere Informationen finden Sie in der AWS-Dokumentation.
Ich werde nicht zeigen, wie man AWS Lambda mit einem Trigger-Ereignis verknüpft. In unserem Fall werden wir Ereignisse manuell auslösen.
Um unser Ziel zu erreichen, werden wir Python-basierte Lambda-Funktionen verwenden. Eine zum Exportieren von Cognito-Benutzern in eine CSV-Datei, zum Hochladen und zum Speichern in einem S3-Bucket. Eine, um das zweite Cognito zu bereinigen, und eine, um die CSV-Datei abzurufen und sie in die Backup-Cognito-Instanz zu importieren:

Das Skript verwendet das Python AWS SDK mit der Bezeichnung boto3, um ListUsers API-Aufrufe durchzuführen. Mit der boto3-Bibliothek müssen Sie die Methode list_users(**args) von CognitoIdentityProvider verwenden. Weitere Methoden und Details finden Sie auf der offiziellen Dokumentationsseite.
Bereitstellen von Export-Lambda
Erstellen Sie eine Rolle. Mit dieser Rolle werden wir der Lambda-Funktion einige Berechtigungen geben:

- AmazonS3FullAccess - zum Hochladen und Speichern der CSV-Datei im S3 Bucket
- AmazonCognitoReadOnly - zum Auflisten und Lesen von Benutzerdaten
!!! Denken Sie daran, die geringstmögliche Berechtigung zu verwenden, wenn Sie in der Produktion bereitstellen wollen. Für diesen Lehrgang verwenden wir die von AWS bereitgestellten Berechtigungsrichtlinien. Sie bieten vollen Zugriff auf Ressourcen. Es ist immer eine gute Praxis, eine benutzerdefinierte Richtlinie mit den einzigen Berechtigungen zu erstellen, die der Lambda benötigt.
S3 Bucket erstellen
Vergessen Sie bei der Erstellung des Buckets nicht, den öffentlichen Zugriff zu sperren. Da unsere CSV-Dateien private Daten enthalten werden.
Lambda-Funktion erstellen
Erstellen Sie eine Lambda-Funktion von Grund auf mit Python 3.9 als Laufzeitumgebung:

Fügen Sie 3 Umgebungsvariablen hinzu:
- BACKUP_BUCKET - dies ist Ihr Ziel-Bucket
- COGNITO_ID - die ID des Quell-Cognito-Benutzerpools
- REGION - Region Cognito

Von Konfiguration - Allgemeine Konfiguration.
Ändern Sie den Speicher und die Zeitüberschreitung, da die Standardwerte möglicherweise nicht ausreichen, wenn Sie eine große Anzahl von Benutzern haben.
Hängen Sie die erstellte Rolle an:

Der letzte Punkt, der geändert werden muss, ist der Lambda-Handler. Dies ist die Abbildung auf die Datei und die Hauptmethode, die ausgeführt werden soll.

Fügen Sie nun den Code ein. Speichern und bereitstellen.
from email import header
import boto3
import datetime
from datetime import datetime
import time
import argparse
import traceback
import os
class Logs:
@staticmethod
def warning(logBody):
print("[WARNING] {}".format(logBody))
@staticmethod
def critical(logBody):
print("[CRITICAL] {}".format(logBody))
@staticmethod
def info(logBody):
print("[INFO] {}".format(logBody))
class Cognito:
USERPOOLID = ""
REGION = ""
ATTRIBUTES = ""
# INIT userpool id, region and column names to be exported.
# Currently region is not used. The export lambda must be in the same region as the Cognito service
def __init__(self, userPoolId, region, attributes):
self.USERPOOLID = userPoolId
self.REGION = region
self.ATTRIBUTES = attributes
def getAttributes (self):
try:
boto = boto3.client('cognito-idp')
headers = boto.get_csv_header(
UserPoolId=self.USERPOOLID
)
self.ATTRIBUTES = headers["CSVHeader"]
return headers["CSVHeader"]
except Exception as e:
Logs.critical("There is an error listing users attributes")
Logs.critical(traceback.format_exc())
exit()
# List all cognito users with only the predefined columns in ATTRIBUTES variable
# As there is a limit of 60 users per query, a multiple queries are executed separated in so called pages.
def listUsers (self):
try:
boto = boto3.client('cognito-idp')
users = []
next_page = None
kwargs = {
'UserPoolId': self.USERPOOLID,
}
users_remain = True
while(users_remain):
if next_page:
kwargs['PaginationToken'] = next_page
response = boto.list_users(**kwargs)
users.extend(response['Users'])
next_page = response.get('PaginationToken', None)
users_remain = next_page is not None
# COOL DOWN BEFORE NEXT QUERY
time.sleep(0.15)
return users
except Exception as e:
Logs.critical("There is an error listing cognito users")
Logs.critical(traceback.format_exc())
exit()
# List all cognito groups with only the predefined columns in ATTRIBUTES variable
# As there is a limit of 60 groups per query, a multiple queries are executed separated in so called pages.
def listGroups (self):
try:
boto = boto3.client('cognito-idp')
groups = []
next_page = None
kwargs = {
'UserPoolId': self.USERPOOLID,
}
groups_remain = True
while(groups_remain):
if next_page:
kwargs['NextToken'] = next_page
response = boto.list_groups(**kwargs)
groups.extend(response['Groups'])
next_page = response.get('NextToken', None)
groups_remain = next_page is not None
# COOL DOWN BEFORE NEXT QUERY
time.sleep(0.15)
return groups
except Exception as e:
Logs.critical("There is an error listing cognito groups")
Logs.critical(traceback.format_exc())
exit()
class CSV:
FILENAME = ""
FOLDER = "/tmp/"
ATTRIBUTES = ""
CSV_LINES = []
# INIT titles and filename
def __init__(self, attributes, prefix):
self.ATTRIBUTES = attributes
self.FILENAME = "cognito_backup_" + prefix + "_" + datetime.now().strftime("%Y%m%d-%H%M") + ".csv"
self.CSV_LINES = []
# Generate CSV content. Every column in a row is split with ","
# First are added the titles and then all users are looped.
def generateUserContent (self, records):
try:
#ADD TITLES
csv_new_line = self.addTitles()
#ADD USERS
for user in records:
""" Fetch Required Attributes Provided """
csv_line = csv_new_line.copy()
for requ_attr in self.ATTRIBUTES:
csv_line[requ_attr] = ''
if requ_attr in user.keys():
csv_line[requ_attr] = str(user[requ_attr])
continue
for usr_attr in user['Attributes']:
if usr_attr['Name'] == requ_attr:
csv_line[requ_attr] = str(usr_attr['Value'])
csv_line["cognito:mfa_enabled"] = "false"
csv_line["cognito:username"] = csv_line["email"]
self.CSV_LINES.append(",".join(csv_line.values()) + 'n')
return self.CSV_LINES
except Exception as e:
Logs.critical("Error generating csv content")
Logs.critical(traceback.format_exc())
exit()
# Add titles to first row and return it as a template.
def addTitles (self):
csv_new_line = {self.ATTRIBUTES[i]: '' for i in range(len(self.ATTRIBUTES))}
self.CSV_LINES.append(",".join(csv_new_line) + 'n')
return csv_new_line
# Generate CSV content. Every column in a row is split with ","
# First are added the titles and then all groups are looped.
def generateGroupContent (self, records):
try:
#ADD TITLES
csv_new_line = self.addTitles()
#ADD GROUPS
for group in records:
csv_line = {}
for groupParam in self.ATTRIBUTES:
csv_line[str(groupParam)] = str(group[str(groupParam)])
self.CSV_LINES.append(",".join(csv_line.values()) + 'n')
return self.CSV_LINES
except Exception as e:
Logs.critical("Error generating csv content")
Logs.critical(traceback.format_exc())
exit()
# Save generated content to a file.
def saveToFile(self):
try:
csvFile = open(self.FOLDER + "/" + self.FILENAME, 'a')
csvFile.writelines(self.CSV_LINES)
csvFile.close()
except Exception as e:
Logs.critical("Error saving csv file")
Logs.critical(traceback.format_exc())
exit()
class S3:
BUCKET = ""
REGION = ""
# INIT bucket name and region. Currently region is not used.
def __init__(self, bucket, region):
self.BUCKET = bucket
self.REGION = region
# Upload fil to s3 bucket
def uploadFile(self, src, dest):
try:
boto3.resource('s3').meta.client.upload_file(src, self.BUCKET, dest)
except Exception as e:
Logs.critical("Error uploading the backup file")
Logs.critical(traceback.format_exc())
exit()
def lambda_function(event, context):
### MAIN ###
# VARIABLES
REGION = os.environ['REGION']
COGNITO_ID = os.environ['COGNITO_ID']
BACKUP_BUCKET = os.environ['BACKUP_BUCKET']
GATTRIBUTES = [
'GroupName',
'Description',
'Precedence'
]
# INIT CLASSES
cognito = Cognito(COGNITO_ID, REGION, [])
cognitoS3 = S3(BACKUP_BUCKET, REGION)
# GET USERS ITTRIBUTES AND INIT CSV CLASS
ATTRIBUTES = cognito.getAttributes()
csvUsers = CSV(ATTRIBUTES, "users")
# LIST ALL USERS
user_records = cognito.listUsers()
# SAVE USERS TO FILE
csvUsers.generateUserContent(user_records)
csvUsers.saveToFile()
# DISPLAY INFO
Logs.info("Total Exported User Records: "+str(len(csvUsers.CSV_LINES)))
# UPLOAD FILE
cognitoS3.uploadFile (csvUsers.FOLDER + "/" + csvUsers.FILENAME, csvUsers.FILENAME)
# INIT GROUPS CSV CLASS
csvGroups = CSV(GATTRIBUTES, "groups")
# LIST ALL GROUPS
group_records = cognito.listGroups()
# SAVE GROUPS TO FILE
csvGroups.generateGroupContent(group_records)
csvGroups.saveToFile()
# DISPLAY INFO
Logs.info("Total Exported Group Records: "+str(len(csvGroups.CSV_LINES)))
# UPLOAD FILE
cognitoS3.uploadFile (csvGroups.FOLDER + "/" + csvGroups.FILENAME, csvGroups.FILENAME)
Drücken Sie auf der Registerkarte "Test" einfach auf die Schaltfläche "TEST", und Sie werden die erfolgreiche Ausgabe des Laufs sehen.

Was macht also dieses Lambda?
Es gibt eine Reihe von benutzerdefinierten Klassen, die mit Cognito, S3 und CSV arbeiten. Die Hauptprozedur befindet sich jedoch innerhalb der Methode lambda_function.
- Zunächst initialisieren wir alle Klassen.
- Innerhalb von GATTRIBUTES müssen wir die Gruppenspalten definieren, die exportiert werden sollen.
- Gruppenname
- Beschreibung
- Vorrangig
Dies sind die Standardspalten, die in den meisten Fällen ausreichend sind.
- Benutzerattribute abrufen. Dies sind die Spaltennamen, die in Cognito verwendet werden. In dieser Installation haben wir 3 benutzerdefinierte Attribute.

!!! Wenn wir benutzerdefinierte Attribute verwenden, müssen wir sie innerhalb des neuen Cognito erstellen, sonst schlägt der Import fehl.
- Alle Benutzer auflisten
- Erzeugen und Speichern von Benutzern in der CSV-Datei
- Hochladen der neu erstellten Benutzerdatei in unseren Backup-Bucket
- Alle Gruppen auflisten
- Erzeugen und Speichern von Gruppen in der CSV-Datei.
- Hochladen der neu erstellten Gruppendatei in unseren Backup-Bucket
- Eine Statistik exportieren
Wenn wir den Backup-Bucket besuchen, sehen wir die neu erstellten CSV-Dateien:

Cognito Lambda reinigen
Falls unser zweiter Cognito-Pool nicht leer ist oder der Import nicht vollständig erfolgreich war, müssen wir ihn bereinigen.
Erstellen Sie wieder eine Python 3.9 Lambda-Funktion von Grund auf. Ändern Sie Speicher und Timeout und fügen Sie diese Umgebungsvariablen hinzu:
- COGNITO_ID - mit der ID des Ziel-Cognitos
- REGION - Zielgebiet Cognito Region
Erstellen Sie außerdem eine neue Rolle mit der folgenden Berechtigung und nennen Sie sie CognitoImportRole:
- IAMFullAccess
- AmazonS3FullAccess
- CloudWatchFullAccess
- AmazonCognitoPowerUser
import boto3
import datetime
from datetime import datetime
import time
import traceback
import os
class Logs:
@staticmethod
def warning(logBody):
print("[WARNING] {}".format(logBody))
@staticmethod
def critical(logBody):
print("[CRITICAL] {}".format(logBody))
@staticmethod
def info(logBody):
print("[INFO] {}".format(logBody))
class Cognito:
USERPOOLID = ""
REGION = ""
ATTRIBUTES = ""
# INIT userpool id, region and column names to be exported.
# Currently region is not used. The export lambda must be in the same region as the Cognito service
def __init__(self, userPoolId, region, attributes):
self.USERPOOLID = userPoolId
self.REGION = region
self.ATTRIBUTES = attributes
def getAttributes (self):
try:
boto = boto3.client('cognito-idp')
headers = boto.get_csv_header(
UserPoolId=self.USERPOOLID
)
self.ATTRIBUTES = headers["CSVHeader"]
return headers["CSVHeader"]
except Exception as e:
Logs.critical("There is an error listing users attributes")
Logs.critical(traceback.format_exc())
exit()
# List all cognito users with only the predefined columns in ATTRIBUTES variable
# As there is a limit of 60 users per query, a multiple queries are executed separated in so called pages.
def listUsers (self):
try:
boto = boto3.client('cognito-idp')
users = []
next_page = None
kwargs = {
'UserPoolId': self.USERPOOLID,
}
users_remain = True
while(users_remain):
if next_page:
kwargs['PaginationToken'] = next_page
response = boto.list_users(**kwargs)
users.extend(response['Users'])
next_page = response.get('PaginationToken', None)
users_remain = next_page is not None
# COOL DOWN BEFORE NEXT QUERY
time.sleep(0.15)
return users
except Exception as e:
Logs.critical("There is an error listing cognito users")
Logs.critical(traceback.format_exc())
exit()
# List all cognito groups with only the predefined columns in ATTRIBUTES variable
# As there is a limit of 60 groups per query, a multiple queries are executed separated in so called pages.
def listGroups (self):
try:
boto = boto3.client('cognito-idp')
groups = []
next_page = None
kwargs = {
'UserPoolId': self.USERPOOLID,
}
groups_remain = True
while(groups_remain):
if next_page:
kwargs['NextToken'] = next_page
response = boto.list_groups(**kwargs)
groups.extend(response['Groups'])
next_page = response.get('NextToken', None)
groups_remain = next_page is not None
# COOL DOWN BEFORE NEXT QUERY
time.sleep(0.15)
return groups
except Exception as e:
Logs.critical("There is an error listing cognito groups")
Logs.critical(traceback.format_exc())
exit()
def deleteGroups (self, groups):
try:
boto = boto3.client('cognito-idp')
for group in groups:
response = boto.delete_group(
GroupName=group["GroupName"],
UserPoolId=self.USERPOOLID
)
except Exception as e:
Logs.critical("There is an error listing cognito groups")
Logs.critical(traceback.format_exc())
exit()
def deleteUsers (self, users):
try:
boto = boto3.client('cognito-idp')
for user in users:
response = boto.admin_delete_user(
UserPoolId=self.USERPOOLID,
Username=user["Username"]
)
except Exception as e:
Logs.critical("There is an error listing cognito groups")
Logs.critical(traceback.format_exc())
exit()
def lambda_function(event, context):
### MAIN ###
# VARIABLES
REGION = os.environ['REGION']
COGNITO_ID = os.environ['COGNITO_ID']
# INIT CLASSES
cognito = Cognito(COGNITO_ID, REGION, [])
# LIST ALL USERS
user_records = cognito.listUsers()
cognito.deleteUsers(user_records)
# LIST ALL GROUPS
group_records = cognito.listGroups()
cognito.deleteGroups(group_records)
Was macht also dieses Lambda? Der Vorgang ist ziemlich einfach. Es listet alle Benutzer und Gruppen auf und löscht sie.
Cognito-Benutzerpool wiederherstellen
Die folgenden Schritte sind nur dann wichtig, wenn wir die auf S3 gespeicherten Benutzerdaten wiederherstellen müssen - zum Beispiel, wenn ein Benutzer versehentlich gelöscht wurde oder wenn Daten in einen anderen Cognito User Pool migriert werden müssen. Dazu haben wir einen zweiten AWS Lambda erstellt, der manuell über die AWS-Konsole ausgelöst werden muss, wenn man die entsprechenden Daten wiederherstellen möchte. Das kann ein neuer Benutzerpool oder ein alter sein. Bei dieser generischen Lösung werden alle im Bucket gespeicherten S3-Benutzer berücksichtigt, aber Cognito importiert nur die Benutzer, die nicht im UserPool vorhanden sind, und schlägt bei den vorhandenen Benutzern fehl.
Die Wiederherstellungslösung wird im Folgenden vorgestellt.
Erstellen Sie wieder eine Python 3.9 Lambda-Funktion von Grund auf. Ändern Sie Speicher und Timeout, fügen Sie die CognitoImport-Rolle hinzu und fügen Sie diese Umgebungsvariablen hinzu:
- BACKUP_BUCKET - Sicherungseimer
- BACKUP_FILE_GROUPS - vollständiger Dateiname cognito_backup_groups_XXXXXXXX-XXXX.csv
- BACKUP_FILE_USERS - vollständiger Dateiname cognito_backup_users_XXXXXXXX-XXXX.csv
- COGNITO_ID - Ziel-Cognito-ID
- REGION - Zielgebiet cognito region
Der Quellcode ist hier ein wenig anders. Da AWS die "requests"-Bibliothek nicht unterstützt, müssen wir sie bereitstellen.
- Speichern Sie den folgenden Code in index.py
- Führen Sie im selben Ordner
pip3 install requests -t .
Dadurch werden alle Pakete heruntergeladen, die zur Ausführung von "requests" benötigt werden.
import boto3
import datetime
from datetime import datetime
import time
import traceback
import csv
import requests
import os
class Logs:
@staticmethod
def warning(logBody):
print("[WARNING] {}".format(logBody))
@staticmethod
def critical(logBody):
print("[CRITICAL] {}".format(logBody))
@staticmethod
def info(logBody):
print("[INFO] {}".format(logBody))
class S3:
BUCKET = ""
REGION = ""
def __init__(self, bucket, region):
self.BUCKET = bucket
self.REGION = region
def downloadFile (self, src, dest):
try:
boto3.resource('s3').meta.client.download_file(self.BUCKET, src, dest)
except Exception as e:
Logs.critical("Error downloading file")
Logs.critical(traceback.format_exc())
exit()
class CSV:
FILENAME = ""
FOLDER = "/tmp/"
def __init__(self, filename):
self.FILENAME = filename
def readBackup(self):
row_count = 0
groups = []
import csv
with open(self.FILENAME, 'r') as file:
csv_file = csv.DictReader(file)
for row in csv_file:
groups.append(dict(row))
return groups
class Cognito:
USERPOOLID = ""
REGION = ""
ATTRIBUTES = ""
def __init__(self, userPoolId, region, attributes):
self.USERPOOLID = userPoolId
self.REGION = region
self.ATTRIBUTES = attributes
def importUsers (self):
try:
print("importUsers")
except Exception as e:
Logs.critical("Error importing users")
Logs.critical(traceback.format_exc())
exit()
def importGroups (self, groups):
try:
boto = boto3.client('cognito-idp')
for group in groups:
print(group)
if not self.checkIfGroupExists(group["GroupName"]):
kwargs = {
'UserPoolId': self.USERPOOLID
}
for attribute in self.ATTRIBUTES:
if (group[str(attribute)].isnumeric()):
kwargs[str(attribute)] = int(group[attribute])
else:
kwargs[str(attribute)] = str(group[attribute])
response = boto.create_group(**kwargs)
else:
Logs.info("Group {} already exists".format(group["GroupName"]))
except Exception as e:
Logs.critical("Error importing groups")
Logs.critical(traceback.format_exc())
exit()
def checkIfGroupExists(self, groupName):
try:
boto = boto3.client('cognito-idp')
response = boto.get_group(
GroupName=groupName,
UserPoolId=self.USERPOOLID
)
return True
except Exception as e:
return False
def importUsers(self, filename):
try:
#client = boto3.client("cognito-idp", region_name="ap-south-1")
boto = boto3.client('cognito-idp')
response = boto.get_csv_header(
UserPoolId=self.USERPOOLID
)
response = boto.create_user_import_job(
JobName='Import-Test-Job',
UserPoolId=self.USERPOOLID,
CloudWatchLogsRoleArn='arn:aws:iam::615124646879:role/CognitoImportRole'
)
#print(response)
#UPLOAD CSV File
content_deposition = 'attachment;filename='+filename;
presigned_url = response['UserImportJob']['PreSignedUrl']
print(presigned_url)
headers_dict = {
'x-amz-server-side-encryption': 'aws:kms',
'Content-Disposition': content_deposition
}
with open(filename, 'rb') as csvFile:
file_upload_response = requests.put(
presigned_url,
data=csvFile,
headers=headers_dict
)
response2 = boto.start_user_import_job(
UserPoolId=self.USERPOOLID,
JobId=response["UserImportJob"]["JobId"]
)
print(response2)
except Exception as e:
Logs.critical("Error importing users")
Logs.critical(traceback.format_exc())
exit()
def lambda_function(event, context):
REGION = os.environ['REGION']
COGNITO_ID = os.environ['COGNITO_ID']
BACKUP_FILE_USERS = os.environ['BACKUP_FILE_USERS']
BACKUP_FILE_GROUPS = os.environ['BACKUP_FILE_GROUPS']
BACKUP_BUCKET = os.environ['BACKUP_BUCKET']
cognitS3 = S3(BACKUP_BUCKET, REGION)
# DOWNLOAD GROUPS
cognitS3.downloadFile(BACKUP_FILE_GROUPS, "/tmp/"+BACKUP_FILE_GROUPS)
# IMPORT GROUPS
csvGroups = CSV("/tmp/"+BACKUP_FILE_GROUPS)
groups = csvGroups.readBackup()
GATTRIBUTES = [
'GroupName',
'Description',
'Precedence'
]
cognito = Cognito(COGNITO_ID, REGION, GATTRIBUTES)
cognito.importGroups(groups)
# DOWNLOAD USERS
cognitS3.downloadFile(BACKUP_FILE_USERS, "/tmp/"+BACKUP_FILE_USERS)
#csvUsers = CSV("/tmp/"+BACKUP_FILE_USERS)
#users = csvUsers.readBackup()
ATTRIBUTES = [
'email',
'given_name',
'family_name'
]
cognitoUsers = Cognito(COGNITO_ID, REGION, ATTRIBUTES)
cognitoUsers.importUsers("/tmp/"+BACKUP_FILE_USERS)
# IMPORT USERS
Zippen Sie nun das gesamte Verzeichnis und verteilen Sie den Code aus der Zip-Datei.

Was macht das Lambda?
- Lädt die Gruppendatei herunter.
- Gruppen importieren
- Benutzerdatei herunterladen
- Erstellt einen Cognito-Importauftrag, fügt eine Datei an und führt ihn aus.
Da der Importauftrag asynchron ist, wird der Lambda an dieser Stelle angehalten und gilt als erfolgreich.
Wir können Importaufträge von Cognito User Pool - Benutzer und Gruppen - Benutzer importieren verfolgen

Hier sehen wir die Anzahl der erfolgreich importierten Benutzer. Aus irgendeinem Grund kann ein Benutzer nicht importiert werden.

Beobachtung der Sicherungs- und Wiederherstellungslösung mit Python3 Lambda
Leider gibt es beim Exportieren/Importieren von Benutzern aus einem Benutzerpool einige Einschränkungen. Einige sind recht einfach, andere nicht. Im Folgenden werden die Einschränkungen aufgeführt, die einen größeren Einfluss auf die Lösung haben:
- Passwort-Backups: Es gibt keine Sicherungen für Passwörter, und die Benutzer müssten sie zurücksetzen.
- Cognito-Unterattribute werden erneuert: Wenn die Software auf diese Attribute angewiesen ist, können sie in ein benutzerdefiniertes Attribut kopiert werden, oder alternativ können benutzerdefinierte Attribute anstelle von Unterattributen in der Softwarelösung verwendet werden.
- MFA - alle MFA würde in dem neu erstellten Pool deaktiviert werden und muss wieder aktiviert werden.
- Anbieter von Drittanbietern wie Facebook werden nicht funktionieren.
Das Problem ist, dass jeder Cognito-Pool einen eigenen Salzschlüssel hat. Er wird automatisch generiert und wir haben nicht die Möglichkeit, ihn zu kopieren oder zu ändern.
Wenn Sie Fragen haben, können Sie uns gerne kontaktieren.

