

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.

# AWS Config Benutzerdefinierte Lambda-Regeln erstellen
<a name="evaluate-config_develop-rules_lambda-functions"></a>

Sie können benutzerdefinierte Regeln entwickeln und diese AWS Config mit AWS Lambda Funktionen ergänzen.

Sie verknüpfen jede benutzerdefinierte Regel mit einer Lambda-Funktion, die die Logik enthält, die bewertet, ob Ihre AWS Ressourcen der Regel entsprechen. Sie ordnen diese Funktion Ihrer Regel zu und die Regel ruft die Funktion entweder als Reaktion auf Änderungen an der Konfiguration oder in regelmäßigen Abständen ab. Die Funktion bewertet dann, ob Ihre Ressourcen Ihrer Regel entsprechen, und sendet ihre Bewertungsergebnisse an. AWS Config

## AWS Regelentwicklungskit (RDK)
<a name="rdk"></a>

Das AWS Rule Development Kit (RDK) wurde entwickelt, um einen intuitiven und produktiven Compliance-as-Code-Workflow zu unterstützen. Es abstrahiert einen Großteil der undifferenzierten Arbeit, die mit der Bereitstellung von AWS Config Regeln verbunden ist, die durch benutzerdefinierte Lambda-Funktionen unterstützt werden, und bietet einen optimierten develop-deploy-monitor iterativen Prozess.

Eine step-by-step Anleitung finden Sie in der Dokumentation zum [AWS Rule Development Kit](https://aws-config-rdk.readthedocs.io/en/master) (RDK).

## AWS Lambda Beispielfunktionen für AWS Config Regeln (Node.js)
<a name="evaluate-config_develop-rules_nodejs-sample"></a>

AWS Lambda führt Funktionen als Reaktion auf Ereignisse aus, die von AWS Diensten veröffentlicht werden. Die Funktion für eine AWS Config benutzerdefinierte Lambda-Regel empfängt ein Ereignis, das von veröffentlicht wurde AWS Config, und die Funktion verwendet dann Daten, die sie von dem Ereignis empfängt und die sie von der AWS Config API abruft, um die Einhaltung der Regel zu bewerten. Die Operationen in einer Funktion für eine Config-Regel unterscheiden sich darin, ob eine durch Konfigurationsänderungen ausgelöste oder regelmäßige Auswertung durchgeführt wird.

Informationen zu häufig verwendeten Mustern innerhalb von AWS Lambda Funktionen finden Sie unter [Programmiermodell](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html) im *AWS Lambda Entwicklerhandbuch*.

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

AWS Config ruft eine Funktion wie das folgende Beispiel auf, wenn sie eine Konfigurationsänderung für eine Ressource erkennt, die im Geltungsbereich einer benutzerdefinierten Regel liegt.

Wenn Sie die AWS Config Konsole verwenden, um eine Regel zu erstellen, die mit einer Funktion wie diesem Beispiel verknüpft ist, wählen Sie **Configuration changes** als Triggertyp aus. Wenn Sie die AWS Config API verwenden oder AWS CLI die Regel erstellen, legen Sie das `MessageType` Attribut auf `ConfigurationItemChangeNotification` und fest`OversizedConfigurationItemChangeNotification`. Mit diesen Einstellungen kann Ihre Regel immer dann ausgelöst werden, wenn aufgrund einer Ressourcenänderung ein Konfigurationselement oder ein zu großes Konfigurationselement AWS Config generiert wird.

In diesem Beispiel werden Ihre Ressourcen ausgewertet und es wird geprüft, ob die Instances dem Ressourcentyp `AWS::EC2::Instance` entsprechen. Die Regel wird ausgelöst, wenn AWS Config eine Benachrichtigung über ein Konfigurationselement oder ein übergroßes Konfigurationselement generiert. 

```
'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));
    });
};
```

**Funktionsoperationen**

Die Funktion führt die folgenden Operationen zur Laufzeit aus:

1. Die Funktion wird ausgeführt, wenn AWS Lambda das `event` Objekt an die `handler` Funktion übergeben wird. In diesem Beispiel akzeptiert die Funktion den optionalen `callback` Parameter, mit dem sie Informationen an den Aufrufer zurückgibt. AWS Lambda übergibt außerdem ein `context` Objekt, das Informationen und Methoden enthält, die die Funktion während ihrer Ausführung verwenden kann. Beachten Sie, dass in neueren Versionen von Lambda „context“ nicht mehr verwendet wird.

1. Die Funktion prüft, ob `messageType` für das Ereignis ein Konfigurationselement oder ein übergroßes Konfigurationselement ist, und gibt anschließend das Konfigurationselement zurück. 

1. Der Handler ruft die `isApplicable`-Funktion auf, um zu ermitteln, ob die Ressource gelöscht wurde.
**Anmerkung**  
Regeln, die gelöschte Ressourcen melden, sollten das Auswertungsergebnis `NOT_APPLICABLE` zurückgeben, um unnötige Regelauswertungen zu vermeiden.

1. Der Handler ruft die `evaluateChangeNotificationCompliance` Funktion auf und übergibt die `ruleParameters` Objekte `configurationItem` und, die im Ereignis AWS Config veröffentlicht wurden.

   Die Funktion bewertet zunächst, ob es sich bei der Ressource um eine EC2 Instance handelt. Wenn die Ressource keine EC2 Instance ist, gibt die Funktion den Compliance-Wert `NOT_APPLICABLE` zurück. 

   Anschließend wertet die Funktion aus, ob das `instanceType`-Attribut im Konfigurationselement dem `desiredInstanceType`-Parameterwert gleicht. Wenn die Werte identisch sind, gibt die Funktion `COMPLIANT` zurück. Wenn die Werte nicht identisch sind, gibt die Funktion `NON_COMPLIANT` zurück.

1. Der Handler bereitet das Senden der Auswertungsergebnisse vor, AWS Config indem er das `putEvaluationsRequest` Objekt initialisiert. Dieses Objekt enthält die `Evaluations`-Parameter, die das Compliance-Ergebnis, den Ressourcentyp und die ID der ausgewerteten Ressource identifizieren. Das `putEvaluationsRequest` Objekt enthält auch das Ergebnis-Token des Ereignisses, das die Regel und das Ereignis für AWS Config identifiziert. 

1. Der Handler sendet die Auswertungsergebnisse an, AWS Config indem er das Objekt an die `putEvaluations` Methode des `config` Clients übergibt.

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

AWS Config ruft eine Funktion wie das folgende Beispiel für regelmäßige Auswertungen auf. Regelmäßige Auswertungen werden mit der von Ihnen bei der Definition der Regel in AWS Config angegebenen Häufigkeit ausgeführt.

Wenn Sie die AWS Config Konsole verwenden, um eine Regel zu erstellen, die mit einer Funktion wie diesem Beispiel verknüpft ist, wählen Sie **Periodisch** als Triggertyp. Wenn Sie die AWS Config API verwenden oder AWS CLI die Regel erstellen, setzen Sie das `MessageType` Attribut auf`ScheduledNotification`.

In diesem Beispiel wird überprüft, ob die Gesamtanzahl einer bestimmten Ressource einen bestimmten Höchstwert überschreitet.

```
'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;
}
```

**Funktionsoperationen**

Die Funktion führt die folgenden Operationen zur Laufzeit aus:

1. Die Funktion wird ausgeführt, wenn AWS Lambda das `event` Objekt an die `handler` Funktion übergeben wird. In diesem Beispiel akzeptiert die Funktion den optionalen `callback` Parameter, mit dem sie Informationen an den Aufrufer zurückgibt. AWS Lambda übergibt außerdem ein `context` Objekt, das Informationen und Methoden enthält, die die Funktion während ihrer Ausführung verwenden kann. Beachten Sie, dass in neueren Versionen von Lambda „context“ nicht mehr verwendet wird.

1. Der Handler ruft die `countResourceTypes`-Funktion auf, um die Ressourcen des angegebenen Typs zu zählen, und die Funktion übergibt den `applicableResourceType`-Parameter, den sie vom Ereignis erhalten hat. Die `countResourceTypes`-Funktion ruft die `listDiscoveredResources`-Methode des `config`-Clients auf. Dieser gibt eine Liste der Kennungen für die entsprechenden Ressourcen zurück. Die Funktion verwendet die Länge dieser Liste, um die Anzahl der anwendbaren Ressourcen zu bestimmen, und gibt diese Anzahl an den Handler zurück.

1. Der Handler bereitet das Senden der Auswertungsergebnisse vor, AWS Config indem er das `putEvaluationsRequest` Objekt initialisiert. Dieses Objekt enthält den `Evaluations` Parameter, der das Konformitätsergebnis und das Ergebnis identifiziert AWS-Konto , das bei dem Ereignis veröffentlicht wurde. Sie können das Ergebnis mithilfe des `Evaluations`-Parameters auf jeden von AWS Config unterstützten Ressourcentyp anwenden. Das `putEvaluationsRequest` Objekt enthält auch das Ergebnis-Token des Ereignisses, das die Regel und das Ereignis für identifiziert AWS Config.

1. Innerhalb des `putEvaluationsRequest`-Objekts ruft der Handler die `evaluateCompliance`-Funktion auf. Diese Funktion prüft, ob die Anzahl der anwendbaren Ressourcen das Maximum überschreitet, das dem vom Ereignis bereitgestellten `maxCount`-Parameter zugewiesene wurde. Wenn die Anzahl der Ressourcen das Maximum überschreitet, gibt die Funktion `NON_COMPLIANT` zurück. Wenn die Anzahl der Ressourcen das Maximum nicht überschreitet, gibt die Funktion `COMPLIANT` zurück.

1. Der Handler sendet die Auswertungsergebnisse an, AWS Config indem er das Objekt an die `putEvaluations` Methode des `config` Clients übergibt.

------

## AWS Lambda Beispielfunktionen für AWS Config Regeln (Python)
<a name="evaluate-config_develop-rules_python-sample"></a>

AWS Lambda führt Funktionen als Reaktion auf Ereignisse aus, die von AWS Diensten veröffentlicht werden. Die Funktion für eine AWS Config benutzerdefinierte Lambda-Regel empfängt ein Ereignis, das von veröffentlicht wurde AWS Config, und die Funktion verwendet dann Daten, die sie von dem Ereignis empfängt und die sie von der AWS Config API abruft, um die Einhaltung der Regel zu bewerten. Die Operationen in einer Funktion für eine Config-Regel unterscheiden sich darin, ob eine durch Konfigurationsänderungen ausgelöste oder regelmäßige Auswertung durchgeführt wird.

Informationen zu häufig verwendeten Mustern innerhalb von AWS Lambda Funktionen finden Sie unter [Programmiermodell](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html) im *AWS Lambda Entwicklerhandbuch*.

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

AWS Config ruft eine Funktion wie das folgende Beispiel auf, wenn sie eine Konfigurationsänderung für eine Ressource erkennt, die im Geltungsbereich einer benutzerdefinierten Regel liegt.

Wenn Sie die AWS Config Konsole verwenden, um eine Regel zu erstellen, die mit einer Funktion wie diesem Beispiel verknüpft ist, wählen Sie **Configuration changes** als Triggertyp aus. Wenn Sie die AWS Config API verwenden oder AWS CLI die Regel erstellen, legen Sie das `MessageType` Attribut auf `ConfigurationItemChangeNotification` und fest`OversizedConfigurationItemChangeNotification`. Mit diesen Einstellungen kann Ihre Regel immer dann ausgelöst werden, wenn aufgrund einer Ressourcenänderung ein Konfigurationselement oder ein zu großes Konfigurationselement AWS Config generiert wird.

```
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'])
```

**Funktionsoperationen**

Die Funktion führt die folgenden Operationen zur Laufzeit aus:

1. Die Funktion wird ausgeführt, wenn AWS Lambda das `event` Objekt an die `handler` Funktion übergeben wird. In diesem Beispiel akzeptiert die Funktion den optionalen `callback` Parameter, mit dem sie Informationen an den Aufrufer zurückgibt. AWS Lambda übergibt außerdem ein `context` Objekt, das Informationen und Methoden enthält, die die Funktion während ihrer Ausführung verwenden kann. Beachten Sie, dass in neueren Versionen von Lambda „context“ nicht mehr verwendet wird.

1. Die Funktion prüft, ob `messageType` für das Ereignis ein Konfigurationselement oder ein übergroßes Konfigurationselement ist, und gibt anschließend das Konfigurationselement zurück. 

1. Der Handler ruft die `isApplicable`-Funktion auf, um zu ermitteln, ob die Ressource gelöscht wurde.
**Anmerkung**  
Regeln, die gelöschte Ressourcen melden, sollten das Auswertungsergebnis `NOT_APPLICABLE` zurückgeben, um unnötige Regelauswertungen zu vermeiden.

1. Der Handler ruft die `evaluateChangeNotificationCompliance` Funktion auf und übergibt die `ruleParameters` Objekte `configurationItem` und, die im Ereignis AWS Config veröffentlicht wurden.

   Die Funktion bewertet zunächst, ob es sich bei der Ressource um eine EC2 Instance handelt. Wenn die Ressource keine EC2 Instance ist, gibt die Funktion den Compliance-Wert `NOT_APPLICABLE` zurück. 

   Anschließend wertet die Funktion aus, ob das `instanceType`-Attribut im Konfigurationselement dem `desiredInstanceType`-Parameterwert gleicht. Wenn die Werte identisch sind, gibt die Funktion `COMPLIANT` zurück. Wenn die Werte nicht identisch sind, gibt die Funktion `NON_COMPLIANT` zurück.

1. Der Handler bereitet das Senden der Auswertungsergebnisse vor, AWS Config indem er das `putEvaluationsRequest` Objekt initialisiert. Dieses Objekt enthält die `Evaluations`-Parameter, die das Compliance-Ergebnis, den Ressourcentyp und die ID der ausgewerteten Ressource identifizieren. Das `putEvaluationsRequest` Objekt enthält auch das Ergebnis-Token des Ereignisses, das die Regel und das Ereignis für AWS Config identifiziert. 

1. Der Handler sendet die Auswertungsergebnisse an, AWS Config indem er das Objekt an die `putEvaluations` Methode des `config` Clients übergibt.

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

AWS Config ruft eine Funktion wie das folgende Beispiel für regelmäßige Auswertungen auf. Regelmäßige Auswertungen werden mit der von Ihnen bei der Definition der Regel in AWS Config angegebenen Häufigkeit ausgeführt.

Wenn Sie die AWS Config Konsole verwenden, um eine Regel zu erstellen, die mit einer Funktion wie diesem Beispiel verknüpft ist, wählen Sie **Periodisch** als Triggertyp. Wenn Sie die AWS Config API verwenden oder AWS CLI die Regel erstellen, setzen Sie das `MessageType` Attribut auf`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'])
```

**Funktionsoperationen**

Die Funktion führt die folgenden Operationen zur Laufzeit aus:

1. Die Funktion wird ausgeführt, wenn AWS Lambda das `event` Objekt an die `handler` Funktion übergeben wird. In diesem Beispiel akzeptiert die Funktion den optionalen `callback` Parameter, mit dem sie Informationen an den Aufrufer zurückgibt. AWS Lambda übergibt außerdem ein `context` Objekt, das Informationen und Methoden enthält, die die Funktion während ihrer Ausführung verwenden kann. Beachten Sie, dass in neueren Versionen von Lambda „context“ nicht mehr verwendet wird.

1. Der Handler ruft die `countResourceTypes`-Funktion auf, um die Ressourcen des angegebenen Typs zu zählen, und die Funktion übergibt den `applicableResourceType`-Parameter, den sie vom Ereignis erhalten hat. Die `countResourceTypes`-Funktion ruft die `listDiscoveredResources`-Methode des `config`-Clients auf. Dieser gibt eine Liste der Kennungen für die entsprechenden Ressourcen zurück. Die Funktion verwendet die Länge dieser Liste, um die Anzahl der anwendbaren Ressourcen zu bestimmen, und gibt diese Anzahl an den Handler zurück.

1. Der Handler bereitet das Senden der Auswertungsergebnisse vor, AWS Config indem er das `putEvaluationsRequest` Objekt initialisiert. Dieses Objekt enthält den `Evaluations` Parameter, der das Konformitätsergebnis und das Ergebnis identifiziert AWS-Konto , das bei dem Ereignis veröffentlicht wurde. Sie können das Ergebnis mithilfe des `Evaluations`-Parameters auf jeden von AWS Config unterstützten Ressourcentyp anwenden. Das `putEvaluationsRequest` Objekt enthält auch das Ergebnis-Token des Ereignisses, das die Regel und das Ereignis für identifiziert AWS Config.

1. Innerhalb des `putEvaluationsRequest`-Objekts ruft der Handler die `evaluateCompliance`-Funktion auf. Diese Funktion prüft, ob die Anzahl der anwendbaren Ressourcen das Maximum überschreitet, das dem vom Ereignis bereitgestellten `maxCount`-Parameter zugewiesene wurde. Wenn die Anzahl der Ressourcen das Maximum überschreitet, gibt die Funktion `NON_COMPLIANT` zurück. Wenn die Anzahl der Ressourcen das Maximum nicht überschreitet, gibt die Funktion `COMPLIANT` zurück.

1. Der Handler sendet die Auswertungsergebnisse an, AWS Config indem er das Objekt an die `putEvaluations` Methode des `config` Clients übergibt.

------

## Beispielereignisse für AWS Config Regeln
<a name="evaluate-config_develop-rules_example-events"></a>

Wenn der Auslöser für eine Regel eintritt, AWS Config ruft die AWS Lambda Funktion der Regel auf, indem ein Ereignis veröffentlicht wird. AWS Lambda Führt dann die Funktion aus, indem das Ereignis an den Handler der Funktion übergeben wird.

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

AWS Config veröffentlicht ein Ereignis, wenn eine Konfigurationsänderung für eine Ressource erkannt wird, die im Geltungsbereich einer Regel liegt. Im folgenden Beispiel wird gezeigt, dass die Regel durch eine Konfigurationsänderung für eine EC2-Instance ausgelöst wurde.

```
{ 
    "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 ]

Einige Änderungen an der Ressource erzeugen übergroße Konfigurationselemente. Im folgenden Beispiel wird gezeigt, dass die Regel durch eine übergroße Konfigurationsänderung für eine EC2-Instance ausgelöst wurde.

```
{
        "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 veröffentlicht ein Ereignis, wenn Ihre Ressourcen mit einer von Ihnen festgelegten Häufigkeit bewertet werden (z. B. alle 24 Stunden). Im folgenden Beispielereignis wird gezeigt, dass die Regel von einer periodischen Häufigkeit ausgelöst wurde. 

```
{
    "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"
}
```

------

### Ereignisattribute
<a name="w2aac20c19c20c13b1b7"></a>

Das JSON-Objekt für ein AWS Config Ereignis enthält die folgenden Attribute:

`invokingEvent`  
Das Ereignis, das die Bewertung für eine Regel auslöst. Wenn das Ereignis als Antwort auf die Änderung einer Ressourcenkonfigurationsänderung veröffentlicht wird, handelt es sich bei dem Wert für dieses Attribut um eine Zeichenfolge mit einem JSON-`configurationItem` oder einer `configurationItemSummary` (für übergroße große Konfigurationselemente). Das Konfigurationselement stellt den Status der Ressource zu dem Zeitpunkt dar, in dem die Änderung AWS Config erkannt wurde. Ein Beispiel für ein Konfigurationselement finden Sie in der Ausgabe des `get-resource-config-history` AWS CLI Befehls in[Anzeigen des Konfigurationsverlaufs](view-manage-resource-console.md#get-config-history-cli).  
Wenn das Ereignis für eine regelmäßige Bewertung veröffentlicht wird, handelt es sich bei dem Wert um eine Zeichenfolge mit einem JSON-Objekt. Das Objekt enthält Informationen über die Bewertung, die ausgelöst wurde.  
Für jeden Ereignistyp, muss eine Funktion die Zeichenfolge mit einem JSON-Parser analysieren, um die Inhalte zu bewerten, wie im folgenden Node.js-Beispiel:  

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

`ruleParameters`  
Schlüssel/Wert-Paare, die die Funktion als Teil seiner Bewertungslogik verarbeitet. Sie definieren Parameter, wenn Sie die AWS Config Konsole verwenden, um eine benutzerdefinierte Lambda-Regel zu erstellen. Sie können Parameter auch mit dem `InputParameters` Attribut in der `PutConfigRule` AWS Config API-Anfrage oder im `put-config-rule` AWS CLI Befehl definieren.  
Der JSON-Code für die Parameter ist in einer Zeichenfolge enthalten, sodass eine Funktion die Zeichenfolge mit einem JSON-Parser analysieren muss, um die Inhalte wie im folgenden Node.js-Beispiel bewerten zu können:  

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

`resultToken`  
Ein Token, an das die Funktion AWS Config beim `PutEvaluations` Aufruf übergeben muss.

`eventLeftScope`  
Ein boolescher Wert, der angibt, ob die auszuwertende AWS Ressource aus dem Geltungsbereich der Regel entfernt wurde. Wenn der Wert `true` ist, gibt die Funktion an, dass die Bewertung ignoriert werden kann, indem Sie `NOT_APPLICABLE` als Wert für das `ComplianceType`-Attribut im `PutEvaluations`-Aufruf übergibt.

`executionRoleArn`  
Der ARN der IAM-Rolle, der zugewiesen AWS Config ist.

`configRuleArn`  
Der ARN, AWS Config der der Regel zugewiesen wurde.

`configRuleName`  
Der Name, den Sie der Regel zugewiesen haben, die AWS Config zur Veröffentlichung des Ereignisses und zum Aufrufen der Funktion geführt hat.

`configRuleId`  
Die ID, die AWS Config der Regel zugewiesen wurde.

`accountId`  
Die ID desjenigen AWS-Konto , dem die Regel gehört.

`version`  
Eine Versionsnummer, die von zugewiesen wurde AWS. Die Version wird erhöht, wenn AWS Config Ereignissen Attribute AWS hinzugefügt werden. Wenn eine Funktion ein Attribut erfordert, das nur in Ereignissen vorhanden ist, die gleich oder größer als eine bestimmte Version sind, überprüft diese Funktion den Wert für dieses Attribut.  
Die aktuelle Version für AWS Config Ereignisse ist 1.0.