Funzioni AWS Lambda di esempio per le regole AWS Config (Node.js) - AWS Config

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à.

Funzioni AWS Lambda di esempio per le regole AWS Config (Node.js)

AWS Lambda esegue funzioni in risposta a eventi pubblicati da servizi AWS. La funzione per unAWS ConfigLa regola Lambda personalizzata riceve un evento pubblicato daAWS Confige la funzione usa quindi i dati che riceve dall'evento e che recupera dalAWS ConfigAPI per valutare la conformità della regola. Le operazioni in una funzione per una regola di configurazione variano a seconda che si esegua una valutazione attivata da modifiche di configurazione o attivata periodicamente.

Per informazioni sui modelli comuni all'interno dellaAWS LambdaFunzioni, vediModello di programmazionenellaAWS LambdaGuida per gli sviluppatori.

Funzione di esempio per le valutazioni attivate dalle modifiche di configurazione

AWS Config richiamerà una funzione, come nell'esempio seguente, quando rileva una modifica di configurazione per una risorsa nell'ambito di una regola personalizzata.

Se usi la console AWS Config per creare una regola che è associata a una funzione, come in questo esempio, scegli Configuration changes (Modifiche di configurazione) come tipo di trigger. Se usi l'API AWS Config o AWS CLI per creare la regola, imposta l'attributo MessageType su ConfigurationItemChangeNotification e OversizedConfigurationItemChangeNotification. Queste impostazioni permettono alla regola di essere attivate ogni volta che AWS Config genera un elemento di configurazione o un elemento di configurazione di dimensioni eccessive come risultato di una modifica delle risorse.

Questo esempio valuta le risorse e verifica che le istanze corrispondano al tipo di risorsa, AWS::EC2::Instance. La regola viene attivata quando AWS Config genera un elemento di configurazione o un notifica di un elemento di configurazione di dimensioni eccessive.

'use strict'; const aws = require('aws-sdk'); const config = new aws.ConfigService(); // Helper function used to validate input function checkDefined(reference, referenceName) { if (!reference) { throw new Error(`Error: ${referenceName} is not defined`); } return reference; } // Check whether the message type is OversizedConfigurationItemChangeNotification, function isOverSizedChangeNotification(messageType) { checkDefined(messageType, 'messageType'); return messageType === 'OversizedConfigurationItemChangeNotification'; } // Get the configurationItem for the resource using the getResourceConfigHistory API. function getConfiguration(resourceType, resourceId, configurationCaptureTime, callback) { config.getResourceConfigHistory({ resourceType, resourceId, laterTime: new Date(configurationCaptureTime), limit: 1 }, (err, data) => { if (err) { callback(err, null); } const configurationItem = data.configurationItems[0]; callback(null, configurationItem); }); } // Convert the oversized configuration item from the API model to the original invocation model. function convertApiConfiguration(apiConfiguration) { apiConfiguration.awsAccountId = apiConfiguration.accountId; apiConfiguration.ARN = apiConfiguration.arn; apiConfiguration.configurationStateMd5Hash = apiConfiguration.configurationItemMD5Hash; apiConfiguration.configurationItemVersion = apiConfiguration.version; apiConfiguration.configuration = JSON.parse(apiConfiguration.configuration); if ({}.hasOwnProperty.call(apiConfiguration, 'relationships')) { for (let i = 0; i < apiConfiguration.relationships.length; i++) { apiConfiguration.relationships[i].name = apiConfiguration.relationships[i].relationshipName; } } return apiConfiguration; } // Based on the message type, get the configuration item either from the configurationItem object in the invoking event or with the getResourceConfigHistory API in the getConfiguration function. function getConfigurationItem(invokingEvent, callback) { checkDefined(invokingEvent, 'invokingEvent'); if (isOverSizedChangeNotification(invokingEvent.messageType)) { const configurationItemSummary = checkDefined(invokingEvent.configurationItemSummary, 'configurationItemSummary'); getConfiguration(configurationItemSummary.resourceType, configurationItemSummary.resourceId, configurationItemSummary.configurationItemCaptureTime, (err, apiConfigurationItem) => { if (err) { callback(err); } const configurationItem = convertApiConfiguration(apiConfigurationItem); callback(null, configurationItem); }); } else { checkDefined(invokingEvent.configurationItem, 'configurationItem'); callback(null, invokingEvent.configurationItem); } } // Check whether the resource has been deleted. If the resource was deleted, then the evaluation returns not applicable. function isApplicable(configurationItem, event) { checkDefined(configurationItem, 'configurationItem'); checkDefined(event, 'event'); const status = configurationItem.configurationItemStatus; const eventLeftScope = event.eventLeftScope; return (status === 'OK' || status === 'ResourceDiscovered') && eventLeftScope === false; } // In this example, the resource is compliant if it is an instance and its type matches the type specified as the desired type. // If the resource is not an instance, then this resource is not applicable. function evaluateChangeNotificationCompliance(configurationItem, ruleParameters) { checkDefined(configurationItem, 'configurationItem'); checkDefined(configurationItem.configuration, 'configurationItem.configuration'); checkDefined(ruleParameters, 'ruleParameters'); if (configurationItem.resourceType !== 'AWS::EC2::Instance') { return 'NOT_APPLICABLE'; } else if (ruleParameters.desiredInstanceType === configurationItem.configuration.instanceType) { return 'COMPLIANT'; } return 'NON_COMPLIANT'; } // Receives the event and context from AWS Lambda. exports.handler = (event, context, callback) => { checkDefined(event, 'event'); const invokingEvent = JSON.parse(event.invokingEvent); const ruleParameters = JSON.parse(event.ruleParameters); getConfigurationItem(invokingEvent, (err, configurationItem) => { if (err) { callback(err); } let compliance = 'NOT_APPLICABLE'; const putEvaluationsRequest = {}; if (isApplicable(configurationItem, event)) { // Invoke the compliance checking function. compliance = evaluateChangeNotificationCompliance(configurationItem, ruleParameters); } // Initializes the request that contains the evaluation results. putEvaluationsRequest.Evaluations = [ { ComplianceResourceType: configurationItem.resourceType, ComplianceResourceId: configurationItem.resourceId, ComplianceType: compliance, OrderingTimestamp: configurationItem.configurationItemCaptureTime, }, ]; putEvaluationsRequest.ResultToken = event.resultToken; // Sends the evaluation results to AWS Config. config.putEvaluations(putEvaluationsRequest, (error, data) => { if (error) { callback(error, null); } else if (data.FailedEvaluations.length > 0) { // Ends the function if evaluation results are not successfully reported to AWS Config. callback(JSON.stringify(data), null); } else { callback(null, data); } }); }); };

Operazioni della funzione

La funzione esegue le operazioni seguenti in fase di runtime:

  1. La funzione viene eseguita quandoAWS Lambdatrasferisce ileventl'oggettohandlerfunzione. In questo esempio, la funzione accetta l'opzionecallback, che viene utilizzato per restituire le informazioni all'intermediario.AWS Lambdapassa anche acontext, che contiene le informazioni e i metodi che la funzione può utilizzare durante la sua esecuzione. Si noti che nelle versioni più recenti di Lambda, il contesto non viene più utilizzato.

  2. La funzione verifica che il messageType per l'evento sia un elemento di configurazione o un elemento di configurazione di dimensioni eccessive e quindi restituisce l'elemento di configurazione.

  3. Il gestore chiama la funzione isApplicable per determinare se la risorsa sia stato eliminata.

  4. Il gestore chiama la funzione evaluateChangeNotificationCompliance e trasferisce gli oggetti configurationItem e ruleParameters AWS Config pubblicati nell'evento.

    La funzione prima valuta se la risorsa è un'istanza EC2. Se la risorsa non è un'istanza EC2, la funzione restituisce un valore di conformità di NOT_APPLICABLE.

    La funzione valuta quindi se l'attributo instanceType nell'elemento di configurazione sia pari al valore del parametro desiredInstanceType. Se i valori sono uguali, la funzione restituisce COMPLIANT. Se i valori non sono uguali, la funzione restituisce NON_COMPLIANT.

  5. Il gestore prepara l'invio dei risultati di valutazione a AWS Config inizializzando l'oggetto putEvaluationsRequest. Questo oggetto include il parametro Evaluations, che identifica il risultato di conformità, il tipo di risorsa e l'ID della risorsa che è stata valutata. L'oggetto putEvaluationsRequest include, inoltre, il risultato del token dall'evento, che identifica la regola e l'evento per AWS Config.

  6. Il gestore invia i risultati di valutazione a AWS Config trasferendo l'oggetto al metodo putEvaluations del client config.

Funzione di esempio per valutazioni periodiche

AWS Config richiamerà una funzione simile al seguente esempio per le valutazioni periodiche. Le valutazioni periodiche si verificano con la frequenza che specifichi quando definisci la regola in AWS Config.

Se usi la console AWS Config per creare una regola che è associata a una funzione, come in questo esempio, scegli Periodic (Periodico) come tipo di trigger. Se usi l'API AWS Config o AWS CLI per creare la regola, imposta l'attributo MessageType su ScheduledNotification.

Questo esempio verifica se il numero totale di una risorsa specificata supera il limite massimo impostato.

var aws = require('aws-sdk'), // Loads the AWS SDK for JavaScript. config = new aws.ConfigService(), // Constructs a service object to use the aws.ConfigService class. COMPLIANCE_STATES = { COMPLIANT : 'COMPLIANT', NON_COMPLIANT : 'NON_COMPLIANT', NOT_APPLICABLE : 'NOT_APPLICABLE' }; // Receives the event and context from AWS Lambda. exports.handler = function(event, context, callback) { // Parses the invokingEvent and ruleParameters values, which contain JSON objects passed as strings. var invokingEvent = JSON.parse(event.invokingEvent), ruleParameters = JSON.parse(event.ruleParameters), noOfResources = 0; if (isScheduledNotification(invokingEvent)) { countResourceTypes(ruleParameters.applicableResourceType, "", noOfResources, function(err, count) { if (err === null) { var putEvaluationsRequest; // Initializes the request that contains the evaluation results. putEvaluationsRequest = { Evaluations : [ { // Applies the evaluation result to the AWS account published in the event. ComplianceResourceType : 'AWS::::Account', ComplianceResourceId : event.accountId, ComplianceType : evaluateCompliance(ruleParameters.maxCount, count), OrderingTimestamp : new Date() } ], ResultToken : event.resultToken }; // Sends the evaluation results to AWS Config. config.putEvaluations(putEvaluationsRequest, function(err, data) { if (err) { callback(err, null); } else { if (data.FailedEvaluations.length > 0) { // Ends the function execution if evaluation results are not successfully reported callback(JSON.stringify(data)); } callback(null, data); } }); } else { callback(err, null); } }); } else { console.log("Invoked for a notification other than Scheduled Notification... Ignoring."); } }; // Checks whether the invoking event is ScheduledNotification. function isScheduledNotification(invokingEvent) { return (invokingEvent.messageType === 'ScheduledNotification'); } // Checks whether the compliance conditions for the rule are violated. function evaluateCompliance(maxCount, actualCount) { if (actualCount > maxCount) { return COMPLIANCE_STATES.NON_COMPLIANT; } else { return COMPLIANCE_STATES.COMPLIANT; } } // Counts the applicable resources that belong to the AWS account. function countResourceTypes(applicableResourceType, nextToken, count, callback) { config.listDiscoveredResources({resourceType : applicableResourceType, nextToken : nextToken}, function(err, data) { if (err) { callback(err, null); } else { count = count + data.resourceIdentifiers.length; if (data.nextToken !== undefined && data.nextToken != null) { countResourceTypes(applicableResourceType, data.nextToken, count, callback); } callback(null, count); } }); return count; }

Operazioni della funzione

La funzione esegue le operazioni seguenti in fase di runtime:

  1. La funzione viene eseguita quandoAWS Lambdatrasferisce ileventl'oggettohandlerfunzione. In questo esempio, la funzione accetta l'opzionecallback, che viene utilizzato per restituire le informazioni all'intermediario.AWS Lambdapassa anche acontext, che contiene le informazioni e i metodi che la funzione può utilizzare durante la sua esecuzione. Si noti che nelle versioni più recenti di Lambda, il contesto non viene più utilizzato.

  2. Per contare le risorse del tipo specificato, il gestore chiama la funzione countResourceTypes e trasferisce il parametro applicableResourceType che ha ricevuto dall'evento. La funzione countResourceTypes chiama il metodo listDiscoveredResources del client config, che restituisce un elenco di identificatori per le risorse applicabili. La funzione utilizza la lunghezza di questo elenco per determinare il numero di risorse applicabili e restituisce questo conteggio al gestore.

  3. Il gestore prepara l'invio dei risultati di valutazione a AWS Config inizializzando l'oggetto putEvaluationsRequest. Questo oggetto include ilEvaluationsparametro, che identifica il risultato della conformità e ilAccount AWSpubblicato nell'evento. Puoi utilizzare il parametro Evaluations per applicare il risultato a qualsiasi tipo di risorsa supportata da AWS Config. L'oggetto putEvaluationsRequest include, inoltre, il risultato del token dall'evento, che identifica la regola e l'evento per AWS Config.

  4. All'interno dell'oggetto putEvaluationsRequest, il gestore chiama la funzione evaluateCompliance, Questa funzione verifica se il numero di risorse applicabili supera il massimo assegnato al parametro maxCount, che è stato fornito dall'evento. Se il numero di risorse supera il limite massimo, la funzione restituisce NON_COMPLIANT. Se il numero di risorse non supera il limite massimo, la funzione restituisce COMPLIANT.

  5. Il gestore invia i risultati di valutazione a AWS Config trasferendo l'oggetto al metodo putEvaluations del client config.