

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

# Criação de AWS Config regras personalizadas do Lambda
<a name="evaluate-config_develop-rules_lambda-functions"></a>

Você pode desenvolver regras personalizadas e adicioná-las AWS Config com AWS Lambda funções.

Você associa cada regra personalizada a uma função Lambda, que contém a lógica que avalia se seus AWS recursos estão em conformidade com a regra. Você associa essa função com a sua regra, e a regra chama a função em resposta a alterações de configuração ou periodicamente. Em seguida, a função avalia se seus recursos estão em conformidade com sua regra e envia os resultados da avaliação para AWS Config. 

## AWS Kit de desenvolvimento de regras (RDK)
<a name="rdk"></a>

O AWS Rule Development Kit (RDK) foi projetado para oferecer suporte a um fluxo de trabalho de “conformidade como código” que seja intuitivo e produtivo. Ele elimina grande parte do trabalho pesado indiferenciado associado à implantação de AWS Config regras apoiadas por funções personalizadas do Lambda e fornece um processo iterativo simplificado. develop-deploy-monitor

Para obter step-by-step instruções, consulte a [documentação do AWS Rule Development Kit (RDK)](https://aws-config-rdk.readthedocs.io/en/master).

## Exemplo de AWS Lambda funções para AWS Config regras (Node.js)
<a name="evaluate-config_develop-rules_nodejs-sample"></a>

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](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html) no *Guia do AWS Lambda desenvolvedor*.

------
#### [ Example Function for Evaluations Triggered by Configuration Changes ]

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:

1. A função é executada quando AWS Lambda passa o `event` objeto para a `handler` função. Neste exemplo, a função aceita o `callback` parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa um `context` 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.

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

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

1. O manipulador chama a `evaluateChangeNotificationCompliance` função e passa os `ruleParameters` objetos `configurationItem` 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âmetro `desiredInstanceType`. 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`.

1. O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto. `putEvaluationsRequest` Este objeto inclui o parâmetro `Evaluations`, que identifica o resultado de compatibilidade, o tipo de recurso e o ID do recurso que foi avaliado. O `putEvaluationsRequest` objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config. 

1. O manipulador envia os resultados da avaliação AWS Config passando o objeto para o `putEvaluations` método do `config` cliente.

------
#### [ Example Function for Periodic Evaluations ]

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 como`ScheduledNotification`.

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:

1. A função é executada quando AWS Lambda passa o `event` objeto para a `handler` função. Neste exemplo, a função aceita o `callback` parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa um `context` 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.

1. Para contar os recursos do tipo especificado, o handler chama a função `countResourceTypes` e passa o parâmetro `applicableResourceType` que recebeu do evento. A função `countResourceTypes` chama o método `listDiscoveredResources` do cliente `config`, 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.

1. O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto. `putEvaluationsRequest` Esse objeto inclui o `Evaluations` parâmetro, que identifica o resultado da conformidade e o Conta da AWS que foi publicado no evento. Você pode usar o parâmetro `Evaluations` para aplicar o resultado a qualquer tipo de recurso que tenha suporte no AWS Config. O `putEvaluationsRequest` objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config.

1. Dentro do objeto `putEvaluationsRequest`, o handler chama a função `evaluateCompliance`. Esta função testa se o número de recursos aplicáveis excede o máximo atribuído ao parâmetro `maxCount`, que foi fornecido pelo evento. Se o número de recursos excede o máximo, a função retorna `NON_COMPLIANT`. Se o número de recursos não excede o máximo, a função retorna `COMPLIANT`.

1. O manipulador envia os resultados da avaliação AWS Config passando o objeto para o `putEvaluations` método do `config` cliente.

------

## Exemplos de AWS Lambda funções para AWS Config regras (Python)
<a name="evaluate-config_develop-rules_python-sample"></a>

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](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html) no *Guia do AWS Lambda desenvolvedor*.

------
#### [ Example Function for Evaluations Triggered by Configuration Changes ]

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.

```
import botocore 
import boto3
import json
import datetime

# Set to True to get the lambda to assume the Role attached on the Config Service (useful for cross-account).
ASSUME_ROLE_MODE = False

# This gets the client after assuming the Config service role
# either in the same AWS account or cross-account.
def get_client(service, event):
    """Return the service boto client. It should be used instead of directly calling the client.
    Keyword arguments:
    service -- the service name used for calling the boto.client()
    event -- the event variable given in the lambda handler
    """
    if not ASSUME_ROLE_MODE:
        return boto3.client(service)
    credentials = get_assume_role_credentials(event["executionRoleArn"])
    return boto3.client(service, aws_access_key_id=credentials['AccessKeyId'],
                        aws_secret_access_key=credentials['SecretAccessKey'],
                        aws_session_token=credentials['SessionToken']
                       )

# Helper function used to validate input
def check_defined(reference, reference_name):
    if not reference:
        raise Exception('Error: ', reference_name, 'is not defined')
    return reference

# Check whether the message is OversizedConfigurationItemChangeNotification or not
def is_oversized_changed_notification(message_type):
    check_defined(message_type, 'messageType')
    return message_type == 'OversizedConfigurationItemChangeNotification'

# Get configurationItem using getResourceConfigHistory API
# in case of OversizedConfigurationItemChangeNotification
def get_configuration(resource_type, resource_id, configuration_capture_time):
    result = AWS_CONFIG_CLIENT.get_resource_config_history(
        resourceType=resource_type,
        resourceId=resource_id,
        laterTime=configuration_capture_time,
        limit=1)
    configurationItem = result['configurationItems'][0]
    return convert_api_configuration(configurationItem)

# Convert from the API model to the original invocation model
def convert_api_configuration(configurationItem):
    for k, v in configurationItem.items():
        if isinstance(v, datetime.datetime):
            configurationItem[k] = str(v)
    configurationItem['awsAccountId'] = configurationItem['accountId']
    configurationItem['ARN'] = configurationItem['arn']
    configurationItem['configurationStateMd5Hash'] = configurationItem['configurationItemMD5Hash']
    configurationItem['configurationItemVersion'] = configurationItem['version']
    configurationItem['configuration'] = json.loads(configurationItem['configuration'])
    if 'relationships' in configurationItem:
        for i in range(len(configurationItem['relationships'])):
            configurationItem['relationships'][i]['name'] = configurationItem['relationships'][i]['relationshipName']
    return configurationItem

# Based on the type of message get the configuration item
# either from configurationItem in the invoking event
# or using the getResourceConfigHistory API in getConfiguration function.
def get_configuration_item(invokingEvent):
    check_defined(invokingEvent, 'invokingEvent')
    if is_oversized_changed_notification(invokingEvent['messageType']):
        configurationItemSummary = check_defined(invokingEvent['configurationItemSummary'], 'configurationItemSummary')
        return get_configuration(configurationItemSummary['resourceType'], configurationItemSummary['resourceId'], configurationItemSummary['configurationItemCaptureTime'])
    return check_defined(invokingEvent['configurationItem'], 'configurationItem')

# Check whether the resource has been deleted. If it has, then the evaluation is unnecessary.
def is_applicable(configurationItem, event):
    try:
        check_defined(configurationItem, 'configurationItem')
        check_defined(event, 'event')
    except:
        return True
    status = configurationItem['configurationItemStatus']
    eventLeftScope = event['eventLeftScope']
    if status == 'ResourceDeleted':
        print("Resource Deleted, setting Compliance Status to NOT_APPLICABLE.")
    return (status == 'OK' or status == 'ResourceDiscovered') and not eventLeftScope

def get_assume_role_credentials(role_arn):
    sts_client = boto3.client('sts')
    try:
        assume_role_response = sts_client.assume_role(RoleArn=role_arn, RoleSessionName="configLambdaExecution")
        return assume_role_response['Credentials']
    except botocore.exceptions.ClientError as ex:
        # Scrub error message for any internal account info leaks
        if 'AccessDenied' in ex.response['Error']['Code']:
            ex.response['Error']['Message'] = "AWS Config does not have permission to assume the IAM role."
        else:
            ex.response['Error']['Message'] = "InternalError"
            ex.response['Error']['Code'] = "InternalError"
        raise ex

def evaluate_change_notification_compliance(configuration_item, rule_parameters):
    check_defined(configuration_item, 'configuration_item')
    check_defined(configuration_item['configuration'], 'configuration_item[\'configuration\']')
    if rule_parameters:
        check_defined(rule_parameters, 'rule_parameters')

    if (configuration_item['resourceType'] != 'AWS::EC2::Instance'):
        return 'NOT_APPLICABLE'

    elif rule_parameters.get('desiredInstanceType'):
        if (configuration_item['configuration']['instanceType'] in rule_parameters['desiredInstanceType']):
            return 'COMPLIANT'
    return 'NON_COMPLIANT'

def lambda_handler(event, context):

    global AWS_CONFIG_CLIENT

    check_defined(event, 'event')
    invoking_event = json.loads(event['invokingEvent'])
    rule_parameters = {}
    if 'ruleParameters' in event:
        rule_parameters = json.loads(event['ruleParameters'])

    compliance_value = 'NOT_APPLICABLE'

    AWS_CONFIG_CLIENT = get_client('config', event)
    configuration_item = get_configuration_item(invoking_event)
    if is_applicable(configuration_item, event):
        compliance_value = evaluate_change_notification_compliance(
                configuration_item, rule_parameters)

    response = AWS_CONFIG_CLIENT.put_evaluations(
       Evaluations=[
           {
               'ComplianceResourceType': invoking_event['configurationItem']['resourceType'],
               'ComplianceResourceId': invoking_event['configurationItem']['resourceId'],
               'ComplianceType': compliance_value,
               'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime']
           },
       ],
       ResultToken=event['resultToken'])
```

**Operações de função**

A função executa as seguintes operações em tempo de execução:

1. A função é executada quando AWS Lambda passa o `event` objeto para a `handler` função. Neste exemplo, a função aceita o `callback` parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa um `context` 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.

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

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

1. O manipulador chama a `evaluateChangeNotificationCompliance` função e passa os `ruleParameters` objetos `configurationItem` 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âmetro `desiredInstanceType`. 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`.

1. O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto. `putEvaluationsRequest` Este objeto inclui o parâmetro `Evaluations`, que identifica o resultado de compatibilidade, o tipo de recurso e o ID do recurso que foi avaliado. O `putEvaluationsRequest` objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config. 

1. O manipulador envia os resultados da avaliação AWS Config passando o objeto para o `putEvaluations` método do `config` cliente.

------
#### [ Example Function for Periodic Evaluations ]

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 como`ScheduledNotification`.

```
import botocore 
import boto3
import json
import datetime

# Set to True to get the lambda to assume the Role attached on the Config Service (useful for cross-account).
ASSUME_ROLE_MODE = False
DEFAULT_RESOURCE_TYPE = 'AWS::::Account'

# This gets the client after assuming the Config service role
# either in the same AWS account or cross-account.
def get_client(service, event):
    """Return the service boto client. It should be used instead of directly calling the client.
    Keyword arguments:
    service -- the service name used for calling the boto.client()
    event -- the event variable given in the lambda handler
    """
    if not ASSUME_ROLE_MODE:
        return boto3.client(service)
    credentials = get_assume_role_credentials(event["executionRoleArn"])
    return boto3.client(service, aws_access_key_id=credentials['AccessKeyId'],
                        aws_secret_access_key=credentials['SecretAccessKey'],
                        aws_session_token=credentials['SessionToken']
                       )

def get_assume_role_credentials(role_arn):
    sts_client = boto3.client('sts')
    try:
        assume_role_response = sts_client.assume_role(RoleArn=role_arn, RoleSessionName="configLambdaExecution")
        return assume_role_response['Credentials']
    except botocore.exceptions.ClientError as ex:
        # Scrub error message for any internal account info leaks
        if 'AccessDenied' in ex.response['Error']['Code']:
            ex.response['Error']['Message'] = "AWS Config does not have permission to assume the IAM role."
        else:
            ex.response['Error']['Message'] = "InternalError"
            ex.response['Error']['Code'] = "InternalError"
        raise ex

# Check whether the message is a ScheduledNotification or not.
def is_scheduled_notification(message_type):
    return message_type == 'ScheduledNotification'

def count_resource_types(applicable_resource_type, next_token, count):
    resource_identifier = AWS_CONFIG_CLIENT.list_discovered_resources(resourceType=applicable_resource_type, nextToken=next_token)
    updated = count + len(resource_identifier['resourceIdentifiers']);
    return updated

# Evaluates the configuration items in the snapshot and returns the compliance value to the handler.
def evaluate_compliance(max_count, actual_count):
    return 'NON_COMPLIANT' if int(actual_count) > int(max_count) else 'COMPLIANT'

def evaluate_parameters(rule_parameters):
    if 'applicableResourceType' not in rule_parameters:
        raise ValueError('The parameter with "applicableResourceType" as key must be defined.')
    if not rule_parameters['applicableResourceType']:
        raise ValueError('The parameter "applicableResourceType" must have a defined value.')
    return rule_parameters

# This generate an evaluation for config
def build_evaluation(resource_id, compliance_type, event, resource_type=DEFAULT_RESOURCE_TYPE, annotation=None):
    """Form an evaluation as a dictionary. Usually suited to report on scheduled rules.
    Keyword arguments:
    resource_id -- the unique id of the resource to report
    compliance_type -- either COMPLIANT, NON_COMPLIANT or NOT_APPLICABLE
    event -- the event variable given in the lambda handler
    resource_type -- the CloudFormation resource type (or AWS::::Account) to report on the rule (default DEFAULT_RESOURCE_TYPE)
    annotation -- an annotation to be added to the evaluation (default None)
    """
    eval_cc = {}
    if annotation:
        eval_cc['Annotation'] = annotation
    eval_cc['ComplianceResourceType'] = resource_type
    eval_cc['ComplianceResourceId'] = resource_id
    eval_cc['ComplianceType'] = compliance_type
    eval_cc['OrderingTimestamp'] = str(json.loads(event['invokingEvent'])['notificationCreationTime'])
    return eval_cc

def lambda_handler(event, context):

    global AWS_CONFIG_CLIENT

    evaluations = []
    rule_parameters = {}
    resource_count = 0
    max_count = 0

    invoking_event = json.loads(event['invokingEvent'])
    if 'ruleParameters' in event:
        rule_parameters = json.loads(event['ruleParameters'])
        valid_rule_parameters = evaluate_parameters(rule_parameters)

    compliance_value = 'NOT_APPLICABLE'

    AWS_CONFIG_CLIENT = get_client('config', event)
    if is_scheduled_notification(invoking_event['messageType']):
        result_resource_count = count_resource_types(valid_rule_parameters['applicableResourceType'], '', resource_count)

    if valid_rule_parameters.get('maxCount'):
        max_count = valid_rule_parameters['maxCount']

    compliance_value = evaluate_compliance(max_count, result_resource_count)
    evaluations.append(build_evaluation(event['accountId'], compliance_value, event, resource_type=DEFAULT_RESOURCE_TYPE))
    response = AWS_CONFIG_CLIENT.put_evaluations(Evaluations=evaluations, ResultToken=event['resultToken'])
```

**Operações de função**

A função executa as seguintes operações em tempo de execução:

1. A função é executada quando AWS Lambda passa o `event` objeto para a `handler` função. Neste exemplo, a função aceita o `callback` parâmetro opcional, que ela usa para retornar informações ao chamador. AWS Lambda também passa um `context` 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.

1. Para contar os recursos do tipo especificado, o handler chama a função `countResourceTypes` e passa o parâmetro `applicableResourceType` que recebeu do evento. A função `countResourceTypes` chama o método `listDiscoveredResources` do cliente `config`, 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.

1. O manipulador se prepara para enviar os resultados da avaliação AWS Config inicializando o objeto. `putEvaluationsRequest` Esse objeto inclui o `Evaluations` parâmetro, que identifica o resultado da conformidade e o Conta da AWS que foi publicado no evento. Você pode usar o parâmetro `Evaluations` para aplicar o resultado a qualquer tipo de recurso que tenha suporte no AWS Config. O `putEvaluationsRequest` objeto também inclui o token de resultado do evento, que identifica a regra e o evento para AWS Config.

1. Dentro do objeto `putEvaluationsRequest`, o handler chama a função `evaluateCompliance`. Esta função testa se o número de recursos aplicáveis excede o máximo atribuído ao parâmetro `maxCount`, que foi fornecido pelo evento. Se o número de recursos excede o máximo, a função retorna `NON_COMPLIANT`. Se o número de recursos não excede o máximo, a função retorna `COMPLIANT`.

1. O manipulador envia os resultados da avaliação AWS Config passando o objeto para o `putEvaluations` método do `config` cliente.

------

## Exemplos de eventos para AWS Config regras
<a name="evaluate-config_develop-rules_example-events"></a>

Quando o acionador de uma regra ocorre, AWS Config invoca a AWS Lambda função da regra publicando um evento. Em seguida, AWS Lambda executa a função passando o evento para o manipulador da função.

------
#### [ Example Event for Evaluations Triggered by Configuration Changes ]

AWS Config publica um evento quando detecta uma alteração na configuração de um recurso que está dentro do escopo de uma regra. O evento de exemplo a seguir mostra que a regra foi acionada por uma alteração de configuração para uma instância EC2.

```
{ 
    "invokingEvent": "{\"configurationItem\":{\"configurationItemCaptureTime\":\"2016-02-17T01:36:34.043Z\",\"awsAccountId\":\"123456789012\",\"configurationItemStatus\":\"OK\",\"resourceId\":\"i-00000000\",\"ARN\":\"arn:aws:ec2:us-east-2:123456789012:instance/i-00000000\",\"awsRegion\":\"us-east-2\",\"availabilityZone\":\"us-east-2a\",\"resourceType\":\"AWS::EC2::Instance\",\"tags\":{\"Foo\":\"Bar\"},\"relationships\":[{\"resourceId\":\"eipalloc-00000000\",\"resourceType\":\"AWS::EC2::EIP\",\"name\":\"Is attached to ElasticIp\"}],\"configuration\":{\"foo\":\"bar\"}},\"messageType\":\"ConfigurationItemChangeNotification\"}",
    "ruleParameters": "{\"myParameterKey\":\"myParameterValue\"}",
    "resultToken": "myResultToken",
    "eventLeftScope": false,
    "executionRoleArn": "arn:aws:iam::123456789012:role/config-role",
    "configRuleArn": "arn:aws:config:us-east-2:123456789012:config-rule/config-rule-0123456",
    "configRuleName": "change-triggered-config-rule",
    "configRuleId": "config-rule-0123456",
    "accountId": "123456789012",
    "version": "1.0"
}
```

------
#### [ Example Event for Evaluations Triggered by Oversized Configuration Changes ]

Algumas alterações de recursos geram itens de configuração superdimensionados. O evento de exemplo a seguir mostra que a regra foi acionada por uma alteração de configuração superdimensionada para uma instância EC2.

```
{
        "invokingEvent": "{\"configurationItemSummary\": {\"changeType\": \"UPDATE\",\"configurationItemVersion\": \"1.2\",\"configurationItemCaptureTime\":\"2016-10-06T16:46:16.261Z\",\"configurationStateId\": 0,\"awsAccountId\":\"123456789012\",\"configurationItemStatus\": \"OK\",\"resourceType\": \"AWS::EC2::Instance\",\"resourceId\":\"i-00000000\",\"resourceName\":null,\"ARN\":\"arn:aws:ec2:us-west-2:123456789012:instance/i-00000000\",\"awsRegion\": \"us-west-2\",\"availabilityZone\":\"us-west-2a\",\"configurationStateMd5Hash\":\"8f1ee69b287895a0f8bc5753eca68e96\",\"resourceCreationTime\":\"2016-10-06T16:46:10.489Z\"},\"messageType\":\"OversizedConfigurationItemChangeNotification\"}",
        "ruleParameters": "{\"myParameterKey\":\"myParameterValue\"}",
        "resultToken": "myResultToken",
        "eventLeftScope": false,
        "executionRoleArn": "arn:aws:iam::123456789012:role/config-role",
        "configRuleArn": "arn:aws:config:us-east-2:123456789012:config-rule/config-rule-ec2-managed-instance-inventory",
        "configRuleName": "change-triggered-config-rule",
        "configRuleId": "config-rule-0123456",
        "accountId": "123456789012",
        "version": "1.0"
    }
```

------
#### [ Example Event for Evaluations Triggered by Periodic Frequency ]

AWS Config publica um evento quando avalia seus recursos na frequência especificada por você (como a cada 24 horas). O evento de exemplo a seguir mostra que a regra foi acionada por uma frequência periódica. 

```
{
    "invokingEvent": "{\"awsAccountId\":\"123456789012\",\"notificationCreationTime\":\"2016-07-13T21:50:00.373Z\",\"messageType\":\"ScheduledNotification\",\"recordVersion\":\"1.0\"}",
    "ruleParameters": "{\"myParameterKey\":\"myParameterValue\"}",
    "resultToken": "myResultToken",
    "eventLeftScope": false,
    "executionRoleArn": "arn:aws:iam::123456789012:role/config-role",
    "configRuleArn": "arn:aws:config:us-east-2:123456789012:config-rule/config-rule-0123456",
    "configRuleName": "periodic-config-rule",
    "configRuleId": "config-rule-6543210",
    "accountId": "123456789012",
    "version": "1.0"
}
```

------

### Atributos do evento
<a name="w2aac20c19c20c13b1b7"></a>

O objeto JSON de um AWS Config evento contém os seguintes atributos:

`invokingEvent`  
O evento que aciona a avaliação de uma regra. Se o evento é publicado em resposta a uma alteração de configuração de recursos, o valor para esse atributo é uma string que contém um arquivo JSON `configurationItem` ou um `configurationItemSummary` (para itens de configuração superdimensionados). O item de configuração representa o estado do recurso no momento em que AWS Config detectou a alteração. Para obter um exemplo de um item de configuração, consulte a saída produzida pelo `get-resource-config-history` AWS CLI comando em[Visualizar o histórico de configuração](view-manage-resource-console.md#get-config-history-cli).  
Se o evento é publicado para uma avaliação periódica, o valor é uma string que contém um objeto JSON. O objeto inclui informações sobre a avaliação que foi acionada.  
Para cada tipo de evento, uma função deve analisar a string com um analisador JSON para ser capaz de avaliar seu conteúdo, como mostrado no seguinte exemplo de Node.js:  

```
var invokingEvent = JSON.parse(event.invokingEvent);
```

`ruleParameters`  
Os pares de chave/valor que a função processa como parte de sua avaliação lógica. Você define parâmetros ao usar o AWS Config console para criar uma regra personalizada do Lambda. Você também pode definir parâmetros com o `InputParameters` atributo na solicitação `PutConfigRule` AWS Config da API ou no `put-config-rule` AWS CLI comando.  
O código JSON para os parâmetros está contido em uma string, de modo que uma função deve analisar a string com um analisador JSON para ser capaz de avaliar seu conteúdo, como mostrado no seguinte exemplo de Node.js:  

```
var ruleParameters = JSON.parse(event.ruleParameters);
```

`resultToken`  
Um token para o qual a função deve passar AWS Config com a `PutEvaluations` chamada.

`eventLeftScope`  
Um valor booleano que indica se o AWS recurso a ser avaliado foi removido do escopo da regra. Se o valor for `true`, a função indica que a avaliação pode ser ignorada especificando-se `NOT_APPLICABLE` como o valor para o atributo `ComplianceType` na chamada `PutEvaluations`.

`executionRoleArn`  
O ARN da função do IAM atribuída a. AWS Config

`configRuleArn`  
O ARN AWS Config atribuído à regra.

`configRuleName`  
O nome que você atribuiu à regra que causou AWS Config a publicação do evento e a invocação da função.

`configRuleId`  
O ID AWS Config atribuído à regra.

`accountId`  
O ID do Conta da AWS proprietário da regra.

`version`  
Um número de versão atribuído por AWS. A versão será incrementada se AWS adicionar atributos aos AWS Config eventos. Se uma função requer um atributo que está somente em eventos que correspondem ou excedem uma versão específica, essa função pode verificar o valor desse atributo.  
A versão atual para AWS Config eventos é 1.0.