Schreiben eines kanarischen Skripts für Node.js mit der Puppeteer-Laufzeit - Amazon CloudWatch

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Schreiben eines kanarischen Skripts für Node.js mit der Puppeteer-Laufzeit

Einen CloudWatch Synthetics-Kanarienvogel von Grund auf neu erstellen

Hier ist ein Beispiel für die Minimalversion eines Canary-Skripts für Synthetics. Dieses Skript wird als erfolgreiche Ausführung übergeben und gibt eine Zeichenfolge zurück. Um zu sehen, wie ein fehlerhaftes Canary aussieht, ändern Sie let fail = false; zu let fail = true;.

Sie müssen eine Eintrittspunkt-Funktion für das Canary-Skript definieren. Um zu sehen, wie Dateien an den Amazon S3 S3-Speicherort hochgeladen werden, der als der von Canary angegeben istArtifactS3Location, erstellen Sie diese Dateien in dem /tmp Ordner. Alle Canary-Artefakte sollten in diesem Verzeichnis gespeichert werden/tmp, da es das einzige beschreibbare Verzeichnis ist. Vergewissern Sie sich, dass der Screenshot-Pfad /tmp für alle Screenshots oder andere Dateien, die mit dem Skript erstellt wurden, auf eingestellt ist. Synthetics lädt Dateien automatisch in /tmp einen S3-Bucket hoch.

/tmp/<name>

Nach der Ausführung des Skripts werden der pass/fail Status und die Dauer in einem S3-Bucket veröffentlicht CloudWatch und die darunter liegenden Dateien /tmp werden in einen S3-Bucket hochgeladen.

const basicCustomEntryPoint = async function () { // Insert your code here // Perform multi-step pass/fail check // Log decisions made and results to /tmp // Be sure to wait for all your code paths to complete // before returning control back to Synthetics. // In that way, your canary will not finish and report success // before your code has finished executing // Throw to fail, return to succeed let fail = false; if (fail) { throw "Failed basicCanary check."; } return "Successfully completed basicCanary checks."; }; exports.handler = async () => { return await basicCustomEntryPoint(); };

Als Nächstes erweitern wir das Skript, um die Synthetics-Protokollierung zu verwenden und mithilfe des AWS SDK einen Anruf zu tätigen. Zu Demonstrationszwecken erstellt dieses Skript einen Amazon-DynamoDB-Client und ruft die DynamoDB-listTables-API auf. Es protokolliert die Antwort auf die Anforderung und protokolliert entweder „pass“ (erfolgreich) oder „fail“ (nicht erfolgreich), je nachdem, ob die Anforderung erfolgreich war.

const log = require('SyntheticsLogger'); const AWS = require('aws-sdk'); // Require any dependencies that your script needs // Bundle additional files and dependencies into a .zip file with folder structure // nodejs/node_modules/additional files and folders const basicCustomEntryPoint = async function () { log.info("Starting DynamoDB:listTables canary."); let dynamodb = new AWS.DynamoDB(); var params = {}; let request = await dynamodb.listTables(params); try { let response = await request.promise(); log.info("listTables response: " + JSON.stringify(response)); } catch (err) { log.error("listTables error: " + JSON.stringify(err), err.stack); throw err; } return "Successfully completed DynamoDB:listTables canary."; }; exports.handler = async () => { return await basicCustomEntryPoint(); };

Verpacken Sie Ihre kanarischen Dateien von Node.js

Wenn Sie Ihre Canary-Skripte über einen Amazon-S3-Speicherort hochladen, sollte Ihre ZIP-Datei Ihr Skript unter diese Ordnerstruktur enthalten: nodejs/node_modules/myCanaryFilename.js file.

Wenn Sie mehr als eine einzelne .js-Datei oder eine Abhängigkeit vorliegt, von der Ihr Skript abhängt, können Sie sie alle in einer einzigen ZIP-Datei bündeln, die die Ordnerstruktur nodejs/node_modules/myCanaryFilename.js file and other folders and files enthält. Wenn Sie syn-nodejs-puppeteer-3.4 oder neuer verwenden, können Sie Ihre Canary-Dateien auch in einem anderen Ordner ablegen und Ihre Ordnerstruktur wie folgt erstellen: nodejs/node_modules/myFolder/myCanaryFilename.js file and other folders and files.

Handlername

Legen Sie den Skript-Eintrittspunkt Ihres Canary (Handler) als myCanaryFilename.functionName fest, damit er mit dem Dateinamen des Skript-Eintrittspunkts übereinstimmt. Wenn Sie eine Laufzeit vor syn-nodejs-puppeteer-3.4 verwenden, muss functionName handler sein. Wenn Sie syn-nodejs-puppeteer-3.4 oder neuer verwenden, können Sie einen beliebigen Funktionsnamen als Handler auswählen. Wenn Sie syn-nodejs-puppeteer-3.4 oder neuer verwenden, können Sie den Canary auch in einem separaten Ordner (z. B. nodejs/node_modules/myFolder/my_canary_filename) ablegen. Wenn Sie ihn in einem separaten Ordner speichern, geben Sie den entsprechenden Pfad in Ihrem Skript-Eintrittspunkt an (z. B. myFolder/my_canary_filename.functionName).

Ändern eines vorhandenen Puppeteer-Skripts zur Verwendung als Synthetics-Canary

In diesem Abschnitt wird erläutert, wie Puppeteer-Skripte so geändert werden, dass sie als Synthetics-Canary-Skripte ausgeführt werden können. Weitere Informationen zu Puppeteer finden Sie unter Puppeteer API v1.14.0.

Wir beginnen mit diesem Puppeteer-Beispielskript:

const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({path: 'example.png'}); await browser.close(); })();

Für die Konvertierung sind die folgenden Schritte durchzuführen:

  • Erstellen und exportieren Sie eine handler-Funktion. Der Handler ist die Eintrittsfunktion für das Skript. Wenn Sie eine Laufzeit vor syn-nodejs-puppeteer-3.4 verwenden, muss die Handler-Funktion den Namen handler haben. Wenn Sie syn-nodejs-puppeteer-3.4 oder neuer verwenden, kann die Funktion einen beliebigen Namen haben. Dieser Name muss jedoch mit dem Namen im Skript übereinstimmen. Wenn Sie syn-nodejs-puppeteer-3.4 oder neuer verwenden, können Sie Ihre Skripte außerdem in einem beliebigen Ordner ablegen und diesen Ordner als Teil des Handlernamens angeben.

    const basicPuppeteerExample = async function () {}; exports.handler = async () => { return await basicPuppeteerExample(); };
  • Verwenden Sie die Synthetics-Abhängigkeit.

    var synthetics = require('Synthetics');
  • Verwenden Sie die Synthetics.getPage-Funktion, um ein Puppeteer-Page-Objekt zu erhalten.

    const page = await synthetics.getPage();

    Das von der Funktion Synthetics.getPage zurückgegebene Seitenobjekt hat die Ereignisse page.on request, response und requestfailed für die Protokollierung instrumentiert. Synthetics richtet auch die Generierung von HAR-Dateien für Anforderungen und Antworten auf der Seite ein und fügt den Benutzeragenten-Headern der ausgehenden Anforderungen auf der Seite den Canary-ARN hinzu.

Das Skript kann nun als Synthetics-Canary ausgeführt werden. Nachfolgend finden Sie das aktualisierte Skript:

var synthetics = require('Synthetics'); // Synthetics dependency const basicPuppeteerExample = async function () { const page = await synthetics.getPage(); // Get instrumented page from Synthetics await page.goto('https://example.com'); await page.screenshot({path: '/tmp/example.png'}); // Write screenshot to /tmp folder }; exports.handler = async () => { // Exported handler function return await basicPuppeteerExample(); };

Umgebungsvariablen

Sie können Umgebungsvariablen beim Erstellen von Canaries verwenden. Auf diese Weise können Sie ein einzelnes Canaryskript schreiben und dann dieses Skript mit unterschiedlichen Werten verwenden, um schnell mehrere Canarys zu erstellen, die eine ähnliche Aufgabe haben.

Angenommen, Ihre Organisation verfügt über Endpunkte wie prod, dev und pre-release für die verschiedenen Phasen Ihrer Softwareentwicklung und Sie müssen Canaries erstellen, um jeden dieser Endpunkte zu testen. Sie können ein einzelnes Canary-Skript schreiben, das Ihre Software testet, und dann andere Werte für die Endpunkt-Umgebungsvariable angeben, wenn Sie die drei Canarys erstellen. Wenn Sie dann einen Canary erstellen, geben Sie das Skript und die Werte an, die für die Umgebungsvariablen verwendet werden sollen.

Die Namen von Umgebungsvariablen können Buchstaben, Zahlen und den Unterstrich enthalten. Sie müssen mit einem Buchstaben beginnen und mindestens zwei Zeichen enthalten. Die Gesamtgröße Ihrer Umgebungsvariablen darf einen Wert von 4 KB nicht überschreiten. Sie können keine reservierten Lambda-Umgebungsvariablen als Namen Ihrer Umgebungsvariablen angeben. Weitere Informationen zu reservierten Umgebungsvariablen finden Sie unter Laufzeitumgebungsvariablen.

Wichtig

Schlüssel und Werte von Umgebungsvariablen werden im Ruhezustand mit AWS eigenen AWS KMS Schlüsseln verschlüsselt. Die Umgebungsvariablen sind jedoch auf der Clientseite nicht verschlüsselt. Speichern Sie keine sensiblen Daten darin.

Das folgende Beispielskript verwendet zwei Umgebungsvariablen. Dieses Skript ist für einen Canary bestimmt, der prüft, ob eine Webseite verfügbar ist. Es verwendet Umgebungsvariablen, um sowohl die URL, die es überprüft, als auch die verwendete CloudWatch Synthetics-Protokollebene zu parametrisieren.

Die folgende Funktion setzt LogLevel auf den Wert der Umgebungsvariablen LOG_LEVEL.

synthetics.setLogLevel(process.env.LOG_LEVEL);

Diese Funktion setzt URL auf den Wert der Umgebungsvariablen URL.

const URL = process.env.URL;

Dies ist das komplette Skript. Wenn Sie mit diesem Skript einen Canary erstellen, geben Sie Werte für die Umgebungsvariablen LOG_LEVEL und URL an.

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const pageLoadEnvironmentVariable = async function () { // Setting the log level (0-3) synthetics.setLogLevel(process.env.LOG_LEVEL); // INSERT URL here const URL = process.env.URL; let page = await synthetics.getPage(); //You can customize the wait condition here. For instance, //using 'networkidle2' may be less restrictive. const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); if (!response) { throw "Failed to load page!"; } //Wait for page to render. //Increase or decrease wait time based on endpoint being monitored. await page.waitFor(15000); await synthetics.takeScreenshot('loaded', 'loaded'); let pageTitle = await page.title(); log.info('Page title: ' + pageTitle); log.debug('Environment variable:' + process.env.URL); //If the response status code is not a 2xx success code if (response.status() < 200 || response.status() > 299) { throw "Failed to load page!"; } }; exports.handler = async () => { return await pageLoadEnvironmentVariable(); };

Übergeben von Umgebungsvariablen an Ihr Skript

Um Umgebungsvariablen an Ihr Skript zu übergeben, wenn Sie einen Canary in der Konsole erstellen, geben Sie die Schlüssel und Werte der Umgebungsvariablen im Abschnitt Umgebungsvariablen der Konsole an. Weitere Informationen finden Sie unter Erstellen eines Canarys.

Um Umgebungsvariablen über die API oder zu übergeben AWS CLI, verwenden Sie den EnvironmentVariables Parameter im Abschnitt. RunConfig Im Folgenden finden Sie einen AWS CLI Beispielbefehl, der einen Canary erstellt, der zwei Umgebungsvariablen mit den Schlüsseln Environment und verwendetRegion.

aws synthetics create-canary --cli-input-json '{ "Name":"nameofCanary", "ExecutionRoleArn":"roleArn", "ArtifactS3Location":"s3://amzn-s3-demo-bucket-123456789012-us-west-2", "Schedule":{ "Expression":"rate(0 minute)", "DurationInSeconds":604800 }, "Code":{ "S3Bucket": "canarycreation", "S3Key": "cwsyn-mycanaryheartbeat-12345678-d1bd-1234-abcd-123456789012-12345678-6a1f-47c3-b291-123456789012.zip", "Handler":"pageLoadBlueprint.handler" }, "RunConfig": { "TimeoutInSeconds":60, "EnvironmentVariables": { "Environment":"Production", "Region": "us-west-1" } }, "SuccessRetentionPeriodInDays":13, "FailureRetentionPeriodInDays":13, "RuntimeVersion":"syn-nodejs-2.0" }'

Integrieren Sie Ihren Canary mit anderen AWS Diensten

Alle Kanarienvögel können die AWS SDK-Bibliothek verwenden. Du kannst diese Bibliothek verwenden, wenn du deinen Canary schreibst, um den Canary in andere AWS Dienste zu integrieren.

Dazu müssen Sie den folgenden Code zu Ihrem Canary hinzufügen. In diesen Beispielen AWS Secrets Manager wird sie als Dienst verwendet, in den der Canary integriert wird.

  • Importieren Sie das AWS SDK.

    const AWS = require('aws-sdk');
  • Erstellen Sie einen Client für den AWS Service, in den Sie integrieren.

    const secretsManager = new AWS.SecretsManager();
  • Verwenden Sie den Client, um API-Aufrufe für diesen Service durchzuführen.

    var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise();

Das folgende Code-Snippet aus einem Canary-Skript veranschaulicht anhand eines Beispiels die Integration in Secrets Manager detaillierter.

var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const AWS = require('aws-sdk'); const secretsManager = new AWS.SecretsManager(); const getSecrets = async (secretName) => { var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise(); } const secretsExample = async function () { let URL = "<URL>"; let page = await synthetics.getPage(); log.info(`Navigating to URL: ${URL}`); const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); // Fetch secrets let secrets = await getSecrets("secretname") /** * Use secrets to login. * * Assuming secrets are stored in a JSON format like: * { * "username": "<USERNAME>", * "password": "<PASSWORD>" * } **/ let secretsObj = JSON.parse(secrets.SecretString); await synthetics.executeStep('login', async function () { await page.type(">USERNAME-INPUT-SELECTOR<", secretsObj.username); await page.type(">PASSWORD-INPUT-SELECTOR<", secretsObj.password); await Promise.all([ page.waitForNavigation({ timeout: 30000 }), await page.click(">SUBMIT-BUTTON-SELECTOR<") ]); }); // Verify login was successful await synthetics.executeStep('verify', async function () { await page.waitForXPath(">SELECTOR<", { timeout: 30000 }); }); }; exports.handler = async () => { return await secretsExample(); };

Verwenden Sie Ihren Canary dazu, eine statische IP-Adresse zu verwenden

Sie können einen Canary so einrichten, dass er eine statische IP-Adresse verwendet.

So erzwingen Sie einen Canary dazu, eine statische IP-Adresse zu verwenden
  1. Erstellen einer neuen VPC. Weitere Informationen finden Sie unter Using DNS with Your VPC.

  2. Erstellen eines neuen Internet-Gateways Weitere Informationen finden Sie unter Hinzufügen eines Internet-Gateways zu Ihrer VPC.

  3. Erstellen Sie ein öffentliches Subnetz in Ihrer neuen VPC.

  4. Fügen Sie der VPC eine neue Routing-Tabelle hinzu.

  5. Fügen Sie in der neuen Routing-Tabelle eine Route hinzu, die von 0.0.0.0/0 zum Internet-Gateway führt.

  6. Verknüpfen Sie die neue Routing-Tabelle dem öffentlichen Subnetz.

  7. Erstellen einer elastischen IP-Adresse Weitere Informationen finden Sie unter elastische IP-Adressen.

  8. Erstellen Sie ein neues NAT-Gateway und weisen Sie es dem öffentlichen Subnetz und der elastischen IP-Adresse zu.

  9. Erstellen Sie ein privates Subnetz innerhalb der VPC.

  10. Fügen Sie der VPC-Standard-Routing-Tabelle eine Route hinzu, die von 0.0.0.0/0 zum NAT-Gateway geht

  11. Erstellen Sie Ihr Canary.