Scrivere uno script canary Node.js - Amazon CloudWatch

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Scrivere uno script canary Node.js

Creare un canarino CloudWatch Synthetics da zero

Ecco un esempio minimo di script Synthetics canary. Questo script passa come esecuzione riuscita e restituisce una stringa. Per vedere come appare un canary fallito, passare let fail = false; a let fail = true;.

È necessario definire una funzione di punto di ingresso per lo script canary. Per vedere come i file vengono caricati nella posizione Amazon S3 specificata come ArtifactS3Location del canary, creare questi file nella cartella /tmp. Dopo l'esecuzione dello script, lo stato di pass/fail e le metriche della durata vengono pubblicate su e i file in /tmp vengono CloudWatch caricati su S3.

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(); };

Successivamente, espanderemo lo script per utilizzare la registrazione di Synthetics ed effettuare una chiamata utilizzando l'SDK. AWS A scopo dimostrativo, questo script creerà un client Amazon DynamoDB ed effettuerà una chiamata all'API ListTables DynamoDB. Registra la risposta alla richiesta e i registri passano o falliscono in base all'esito positivo della richiesta.

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(); };

Impacchettizzazione dei file canary Node.js

Se carichi gli script del canary utilizzando una posizione di Amazon S3, il file zip deve includere lo script in questa struttura di cartelle: nodejs/node_modules/myCanaryFilename.js file.

Se si dispone di più di un singolo file .js o si dispone di una dipendenza da cui dipende lo script, è possibile raggrupparli tutti in un unico file ZIP contenente la struttura delle cartelle nodejs/node_modules/myCanaryFilename.js file and other folders and files. Se utilizzi un tempo syn-nodejs-puppeteer-3.4 o successivo, puoi inserire i file del canary in un'altra cartella e creare una struttura della cartella simile a quella seguente: nodejs/node_modules/myFolder/myCanaryFilename.js file and other folders and files.

Nome del gestore

Assicurati di impostare il punto di ingresso dello script del tuo canary (gestore) in modo che myCanaryFilename.functionName corrisponda al nome del file del punto di ingresso dello script. Se utilizzi un runtime precedente a syn-nodejs-puppeteer-3.4, functionName deve corrispondere a handler. Se utilizzi un tempo syn-nodejs-puppeteer-3.4 o successivo, puoi scegliere qualsiasi nome di funzione come gestore. Se utilizzi un tempo syn-nodejs-puppeteer-3.4 o successivo, puoi anche memorizzare il canary in una cartella separata, ad esempio nodejs/node_modules/myFolder/my_canary_filename. Se lo archivi in una cartella separata, definisci il percorso nel punto di ingresso dello script, ad esempio myFolder/my_canary_filename.functionName.

Modifica di uno script Puppeteer esistente da utilizzare come canary di Synthetics

Questa sezione spiega come prendere script Puppeteer e modificarli per essere eseguiti come script canary Synthetics. Per ulteriori informazioni su Puppeteer, consulta Puppeteer API v1.14.0.

Inizieremo con questo esempio di script Puppeteer:

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(); })();

Le fasi di conversione sono le seguenti:

  • Creare ed esportare una funzione handler. Il gestore è la funzione del punto di ingresso per lo script. Se utilizzi un runtime precedente a syn-nodejs-puppeteer-3.4, la funzione del gestore deve essere denominata handler. Se utilizzi un tempo syn-nodejs-puppeteer-3.4 o successivo, la funzione può avere un nome qualsiasi, purché corrisponda a quello utilizzato nello script. Inoltre, se utilizzi un tempo syn-nodejs-puppeteer-3.4 o successivo, puoi archiviare gli script in qualsiasi cartella e definire quest'ultima nel nome del gestore.

    const basicPuppeteerExample = async function () {}; exports.handler = async () => { return await basicPuppeteerExample(); };
  • Usa la dipendenza Synthetics.

    var synthetics = require('Synthetics');
  • Utilizzare la funzione Synthetics.getPage per ottenere un oggetto Page Puppeteer.

    const page = await synthetics.getPage();

    L'oggetto pagina restituito dalla funzione Synthetics.getPage ha gli eventi page.on request, response e requestfailed strumentati per la registrazione. Synthetics imposta anche la generazione di file HAR per le richieste e le risposte nella pagina e aggiunge l'ARN canary alle intestazioni user-agent delle richieste in uscita nella pagina.

Lo script è ora pronto per essere eseguito come Canary di Synthetics. Ecco lo script aggiornato:

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(); };

Variabili di ambiente

Quando crei canary puoi utilizzare le variabili di ambiente. Ciò consente di scrivere un singolo script canary e quindi utilizzare tale script con valori diversi per creare rapidamente più canary che hanno un'attività simile.

Ad esempio, supponiamo che l'organizzazione disponga di endpoint quali prod, dev e pre-release per le diverse fasi dello sviluppo del software ed è necessario creare canary per testare ciascuno di questi endpoint. È possibile scrivere un singolo script canary che testi il software e quindi specificare valori diversi per la variabile di ambiente dell'endpoint quando crei ciascuno dei tre canary. Quindi, quando crei un canary, si specificano lo script e i valori da utilizzare per le variabili di ambiente.

I nomi delle variabili di ambiente possono contenere lettere, numeri e il carattere di sottolineatura. Devono iniziare con una lettera e avere almeno due caratteri. La dimensione totale delle variabili di ambiente non può superare i 4 KB. Non è possibile specificare alcuna variabile di ambiente riservato Lambda come nomi per le variabili di ambiente. Per ulteriori informazioni sulle variabili di ambiente riservate, consulta Variabili di ambiente di runtime.

Importante

Le chiavi e i valori delle variabili d'ambiente non sono crittografati. Non archiviare informazioni sensibili al loro interno.

Lo script di esempio seguente utilizza due variabili di ambiente. Questo script è per un canary che controlla se una pagina Web è disponibile. Utilizza variabili di ambiente per parametrizzare sia l'URL che controlla sia il livello di registro Synthetics CloudWatch che utilizza.

La seguente funzione imposta LogLevel al valore della variabile di ambiente LOG_LEVEL.

synthetics.setLogLevel(process.env.LOG_LEVEL);

Questa funzione imposta URL al valore della variabile di ambiente URL.

const URL = process.env.URL;

Questo è lo script completo. Quando crei un canary utilizzando questo script, si specificano i valori per le variabili di ambiente LOG_LEVEL e URL.

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(); };

Passare le variabili di ambiente allo script

Per passare le variabili di ambiente allo script quando crei un canary nella console, specifica le chiavi e i valori delle variabili di ambiente nella finestra Environment variables (Variabili di ambiente) della console. Per ulteriori informazioni, consulta Creazione di un Canary.

Per passare le variabili di ambiente tramite l'API oppure AWS CLI, usa il EnvironmentVariables parametro nella sezione. RunConfig Di seguito è riportato un AWS CLI comando di esempio che crea un canarino che utilizza due variabili di ambiente con le chiavi Environment eRegion.

aws synthetics create-canary --cli-input-json '{ "Name":"nameofCanary", "ExecutionRoleArn":"roleArn", "ArtifactS3Location":"s3://cw-syn-results-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" }'

Integrazione del tuo canarino con altri servizi AWS

Tutti i canarini possono utilizzare la AWS libreria SDK. Puoi usare questa libreria quando scrivi il tuo canarino per integrare il canarino con altri servizi. AWS

Per fare ciò, è necessario aggiungere il seguente codice al tuo canary. Per questi esempi, AWS Secrets Manager viene utilizzato come servizio con cui il canarino si sta integrando.

  • Importa l'SDK. AWS

    const AWS = require('aws-sdk');
  • Crea un client per il AWS servizio con cui ti stai integrando.

    const secretsManager = new AWS.SecretsManager();
  • Utilizzare il client per effettuare chiamate API a tale servizio.

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

Il seguente frammento di codice di script canary mostra un esempio di integrazione con Secrets Manager in modo più dettagliato.

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(); };

Forzare il canary a utilizzare un indirizzo IP statico

Puoi configurare un canary in modo che utilizzi un indirizzo IP statico.

Per forzare un canary a utilizzare un indirizzo IP statico
  1. Crea un nuovo VPC. Per ulteriori informazioni, vedi Utilizzo del DNS con VPC.

  2. Crea un nuovo gateway Internet. Per ulteriori informazioni, consulta la pagina relativa all'Aggiunta di un gateway Internet al VPC.

  3. Crea una sottorete pubblica all'interno del tuo nuovo VPC.

  4. Aggiungi una nuova tabella di routing al VPC.

  5. Aggiungi un routing nella nuova tabella di routing, che va da 0.0.0.0/0 al gateway Internet.

  6. Associa la nuova tabella di routing alla sottorete pubblica.

  7. Crea un indirizzo IP elastico. Per ulteriori informazioni, consulta Indirizzi IP elastici.

  8. Crea un nuovo gateway NAT e assegnalo alla sottorete pubblica e all'indirizzo IP elastico.

  9. Per creare una sottorete privata all'interno del VPC.

  10. Aggiungere un routing alla tabella di tabella di routing predefinita del VPC, che va da 0.0.0.0/0 al gateway NAT

  11. Crea il tuo canary.