As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Exemplo de AWS Lambda funções para AWS Config regras (Node.js)
AWS Lambda executa funções em resposta a eventos publicados pelos AWS serviços. A função de uma regra AWS Config personalizada do Lambda recebe um evento publicado por e AWS Config, em seguida, usa os dados que recebe do evento e recupera da AWS Config API para avaliar a conformidade da regra. As operações em uma função para uma regra Config diferem conforme a avaliação seja acionada por alterações de configuração ou acionada periodicamente.
Para obter informações sobre padrões comuns nas AWS Lambda funções, consulte Modelo de programação no Guia do AWS Lambda desenvolvedor.
Sumário
Exemplo de função para avaliações acionadas por alterações de configuração
AWS Config invocará uma função como o exemplo a seguir ao detectar uma alteração na configuração de um recurso que esteja dentro do escopo de uma regra personalizada.
Se você usar o AWS Config console para criar uma regra associada a uma função como este exemplo, escolha Alterações de configuração como o tipo de acionador. Se você usar a AWS Config API ou AWS CLI criar a regra, defina o MessageType
atributo ConfigurationItemChangeNotification
como OversizedConfigurationItemChangeNotification
e. Essas configurações permitem que sua regra seja acionada sempre que AWS Config gerar um item de configuração ou um item de configuração superdimensionado como resultado de uma alteração de recurso.
Este exemplo avalia seus recursos e verifica se as instâncias correspondem ao tipo de recurso AWS::EC2::Instance
. A regra é acionada quando o AWS Config
gera um item de configuração ou uma notificação de item de configuração superdimensionado.
'use strict'; import { ConfigServiceClient, GetResourceConfigHistoryCommand, PutEvaluationsCommand } from "@aws-sdk/client-config-service"; const configClient = new ConfigServiceClient({}); // 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. async function getConfiguration(resourceType, resourceId, configurationCaptureTime, callback) { const input = { resourceType, resourceId, laterTime: new Date(configurationCaptureTime), limit: 1 }; const command = new GetResourceConfigHistoryCommand(input); await configClient.send(command).then( (data) => { callback(null, data.configurationItems[0]); }, (error) => { callback(error, null); } ); } // 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. async function getConfigurationItem(invokingEvent, callback) { checkDefined(invokingEvent, 'invokingEvent'); if (isOverSizedChangeNotification(invokingEvent.messageType)) { const configurationItemSummary = checkDefined(invokingEvent.configurationItemSummary, 'configurationItemSummary'); await 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. export const handler = async (event, context) => { checkDefined(event, 'event'); const invokingEvent = JSON.parse(event.invokingEvent); const ruleParameters = JSON.parse(event.ruleParameters); await getConfigurationItem(invokingEvent, async (err, configurationItem) => { let compliance = 'NOT_APPLICABLE'; let annotation = ''; const putEvaluationsRequest = {}; if (isApplicable(configurationItem, event)) { // Invoke the compliance checking function. compliance = evaluateChangeNotificationCompliance(configurationItem, ruleParameters); if (compliance === "NON_COMPLIANT") { annotation = "This is an annotation describing why the resource is not compliant."; } } // Initializes the request that contains the evaluation results. if (annotation) { putEvaluationsRequest.Evaluations = [ { ComplianceResourceType: configurationItem.resourceType, ComplianceResourceId: configurationItem.resourceId, ComplianceType: compliance, OrderingTimestamp: new Date(configurationItem.configurationItemCaptureTime), Annotation: annotation }, ]; } else { putEvaluationsRequest.Evaluations = [ { ComplianceResourceType: configurationItem.resourceType, ComplianceResourceId: configurationItem.resourceId, ComplianceType: compliance, OrderingTimestamp: new Date(configurationItem.configurationItemCaptureTime), }, ]; } putEvaluationsRequest.ResultToken = event.resultToken; // Sends the evaluation results to AWS Config. await configClient.send(new PutEvaluationsCommand(putEvaluationsRequest)); }); };
Operações de função
A função executa as seguintes operações em tempo de execução:
-
A função é executada quando AWS Lambda passa o
event
objeto para ahandler
função. Neste exemplo, a função aceita ocallback
parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa umcontext
objeto, que contém informações e métodos que a função pode usar enquanto é executada. Observe que nas versões mais recentes do Lambda, o contexto não é mais usado. -
A função verifica se
messageType
para o evento é um item de configuração ou um item de configuração superdimensionado, e, em seguida, retorna o item de configuração. -
O handler chama a função
isApplicable
para determinar se o recurso foi excluído.nota
Os relatórios de regras sobre recursos excluídos devem retornar o resultado da avaliação de
NOT_APPLICABLE
, a fim de evitar avaliações desnecessárias de regras. -
O manipulador chama a
evaluateChangeNotificationCompliance
função e passa osruleParameters
objetosconfigurationItem
e AWS Config publicados no evento.A função primeiro avalia se o recurso é uma instância EC2. Se o recurso não é uma instância EC2, a função retorna um valor de compatibilidade de
NOT_APPLICABLE
.Em seguida, a função avalia se o atributo
instanceType
no item de configuração é igual ao valor de parâmetrodesiredInstanceType
. Se os valores são iguais, a função retornaráCOMPLIANT
. Se os valores não são iguais, a função retornaráNON_COMPLIANT
. -
O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto.
putEvaluationsRequest
Este objeto inclui o parâmetroEvaluations
, que identifica o resultado de compatibilidade, o tipo de recurso e o ID do recurso que foi avaliado. OputEvaluationsRequest
objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config. -
O manipulador envia os resultados da avaliação AWS Config passando o objeto para o
putEvaluations
método doconfig
cliente.
Exemplo de função para avaliações periódicas
AWS Config invocará uma função como o exemplo a seguir para avaliações periódicas. As avaliações periódicas ocorrem com a frequência que você especifica ao definir a regra em AWS Config.
Se você usar o AWS Config console para criar uma regra associada a uma função como este exemplo, escolha Periódico como o tipo de acionador. Se você usar a AWS Config API ou criar AWS CLI a regra, defina o MessageType
atributo comoScheduledNotification
.
Este exemplo verifica se o número total de um recurso especificado excede o máximo especificado.
'use strict'; import { ConfigServiceClient, ListDiscoveredResourcesCommand, PutEvaluationsCommand } from "@aws-sdk/client-config-service"; const configClient = new ConfigServiceClient({}); // Receives the event and context from AWS Lambda. export const handler = async (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), numberOfResources = 0; if (isScheduledNotification(invokingEvent) && hasValidRuleParameters(ruleParameters, callback)) { await countResourceTypes(ruleParameters.applicableResourceType, "", numberOfResources, async function (err, count) { if (err === null) { var putEvaluationsRequest; const compliance = evaluateCompliance(ruleParameters.maxCount, count); var annotation = ''; if (compliance === "NON_COMPLIANT") { annotation = "Description of why the resource is not compliant."; } // Initializes the request that contains the evaluation results. if (annotation) { putEvaluationsRequest = { Evaluations: [{ // Applies the evaluation result to the AWS account published in the event. ComplianceResourceType: 'AWS::::Account', ComplianceResourceId: event.accountId, ComplianceType: compliance, OrderingTimestamp: new Date(), Annotation: annotation }], ResultToken: event.resultToken }; } else { putEvaluationsRequest = { Evaluations: [{ // Applies the evaluation result to the AWS account published in the event. ComplianceResourceType: 'AWS::::Account', ComplianceResourceId: event.accountId, ComplianceType: compliance, OrderingTimestamp: new Date() }], ResultToken: event.resultToken }; } // Sends the evaluation results to AWS Config. try { await configClient.send(new PutEvaluationsCommand(putEvaluationsRequest)); } catch (e) { callback(e, null); } } 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 the rule parameters to see if they are valid function hasValidRuleParameters(ruleParameters, callback) { // Regular express to verify that applicable resource given is a resource type const awsResourcePattern = /^AWS::(\w*)::(\w*)$/; const isApplicableResourceType = awsResourcePattern.test(ruleParameters.applicableResourceType); // Check to make sure the maxCount in the parameters is an integer const maxCountIsInt = !isNaN(ruleParameters.maxCount) && parseInt(Number(ruleParameters.maxCount)) == ruleParameters.maxCount && !isNaN(parseInt(ruleParameters.maxCount, 10)); if (!isApplicableResourceType) { callback("The applicableResourceType parameter is not a valid resource type.", null); } if (!maxCountIsInt) { callback("The maxCount parameter is not a valid integer.", null); } return isApplicableResourceType && maxCountIsInt; } // Checks whether the compliance conditions for the rule are violated. function evaluateCompliance(maxCount, actualCount) { if (actualCount > maxCount) { return "NON_COMPLIANT"; } else { return "COMPLIANT"; } } // Counts the applicable resources that belong to the AWS account. async function countResourceTypes(applicableResourceType, nextToken, count, callback) { const input = { resourceType: applicableResourceType, nextToken: nextToken }; const command = new ListDiscoveredResourcesCommand(input); try { const response = await configClient.send(command); count = count + response.resourceIdentifiers.length; if (response.nextToken !== undefined && response.nextToken != null) { countResourceTypes(applicableResourceType, response.nextToken, count, callback); } callback(null, count); } catch (e) { callback(e, null); } return count; }
Operações de função
A função executa as seguintes operações em tempo de execução:
-
A função é executada quando AWS Lambda passa o
event
objeto para ahandler
função. Neste exemplo, a função aceita ocallback
parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa umcontext
objeto, que contém informações e métodos que a função pode usar enquanto é executada. Observe que nas versões mais recentes do Lambda, o contexto não é mais usado. -
Para contar os recursos do tipo especificado, o handler chama a função
countResourceTypes
e passa o parâmetroapplicableResourceType
que recebeu do evento. A funçãocountResourceTypes
chama o métodolistDiscoveredResources
do clienteconfig
, que retorna uma lista de identificadores para os recursos aplicáveis. A função usa o comprimento da lista para determinar o número de recursos aplicáveis e retorna essa contagem para o handler. -
O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto.
putEvaluationsRequest
Esse objeto inclui oEvaluations
parâmetro, que identifica o resultado da conformidade e o Conta da AWS que foi publicado no evento. Você pode usar o parâmetroEvaluations
para aplicar o resultado a qualquer tipo de recurso que tenha suporte no AWS Config. OputEvaluationsRequest
objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config. -
Dentro do objeto
putEvaluationsRequest
, o handler chama a funçãoevaluateCompliance
. Esta função testa se o número de recursos aplicáveis excede o máximo atribuído ao parâmetromaxCount
, que foi fornecido pelo evento. Se o número de recursos excede o máximo, a função retornaNON_COMPLIANT
. Se o número de recursos não excede o máximo, a função retornaCOMPLIANT
. -
O manipulador envia os resultados da avaliação AWS Config passando o objeto para o
putEvaluations
método doconfig
cliente.