

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# AWS Config 自定义规则
<a name="evaluate-config_develop-rules"></a>

AWS Config 自定义规则是您从头开始创建的规则。有两种方法可以创建 AWS Config 自定义规则：使用 Lambda 函数（[AWS Lambda 开发者指南](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html#gettingstarted-concepts-function)）和使用 Guard（[防护 GitHub存储库](https://github.com/aws-cloudformation/cloudformation-guard)）（一种 policy-as-code语言）。

AWS Config *使用 Lambda 创建的自定义规则称为自定义 *AWS Config Lambda 规则*，使用 Guard 创建的 AWS Config 自定义规则称为AWS Config 自定义策略规则。*

在使用自定义规则之前，请参阅 [注意事项](evaluate-config.md#evaluate-config-considerations)

## AWS Config 自定义策略规则
<a name="evaluate-config_develop-rules-policy"></a>

使用 Guard 编写的规则可以从 AWS Config 控制台创建，也可以使用 AWS Config 规则创建 APIs。 AWS Config 自定义策略规则允许您创建 AWS Config 自定义规则，而无需使用 Java 或 Python 开发 Lambda 函数来管理您的自定义规则。 AWS Config 自定义策略规则由配置更改启动。有关 Guard 的更多信息，请参阅 [Guard GitHub 存储库](https://github.com/aws-cloudformation/cloudformation-guard)。

## AWS Config 自定义 Lambda 规则
<a name="evaluate-config_develop-rules-lambda"></a>

自定义 Lambda 规则为您提供了使用 Java 或 Python 为自定义规则创建 Lambda 函数的选项。 AWS Config *Lambda 函数*是您上传到的自定义代码 AWS Lambda，由事件源向其发布的事件调用该函数。如果 Lambda 函数与规则关联， AWS Config 则在规则启动时 AWS Config 调用该函数。然后，Lambda 函数评估发送的配置信息 AWS Config，并返回评估结果。有关 Lambda 函数的更多信息，请参阅《AWS Lambda 开发人员指南**》中的[函数和事件源](https://docs.aws.amazon.com/lambda/latest/dg/intro-core-components.html)。

## AWS Config 自定义规则的格式差异
<a name="evaluate-config_develop-schema"></a>

下表显示了[ConfigurationItem](https://docs.aws.amazon.com/config/latest/APIReference/API_ConfigurationItem.html)数据类型和 AWS Config 自定义规则字段的格式差异。


| ConfigurationItem | AWS Config 自定义规则 | 
| --- | --- | 
| version | configurationItemVersion | 
| accountId | awsAccountId | 
| arn | ARN | 
| configurationItemMD5Hash | configurationStateMd5Hash | 

**Topics**
+ [自定义策略规则](#evaluate-config_develop-rules-policy)
+ [自定义 Lambda 规则](#evaluate-config_develop-rules-lambda)
+ [AWS Config 自定义规则的格式差异](#evaluate-config_develop-schema)
+ [创建自定义策略规则](evaluate-config_develop-rules_cfn-guard.md)
+ [创建自定义 Lambda 规则](evaluate-config_develop-rules_lambda-functions.md)
+ [管理自定义 Lambda 规则的已删除资源](evaluate-config_develop-rules-delete.md)

# 创建 AWS Config 自定义策略规则
<a name="evaluate-config_develop-rules_cfn-guard"></a>

您可以通过 AWS 管理控制台 AWS CLI、或 AWS Config API 创建 AWS Config 自定义策略规则。

## 添加 AWS Config 自定义策略规则
<a name="config-custom-policy-rules-add"></a>

------
#### [ Using the console ]

1. 登录 AWS 管理控制台 并在家中打开[https://console.aws.amazon.com/config/主 AWS Config](https://console.aws.amazon.com/config/home)机。

1. 在 AWS 管理控制台 菜单中，确认区域选择器设置为支持 AWS Config 规则的 AWS 区域。有关支持的区域的列表，请参阅《Amazon Web Services 一般参考》**中的 [AWS Config 区域和终端节点](https://docs.aws.amazon.com/general/latest/gr/awsconfig.html)。

1. 在左侧导航窗格中，选择 **Rules**。

1. 在 **Rules** 页面，选择 **Add rule**。

1. 在**指定规则类型**页面上，选择**使用 Guard 创建自定义规则**。

1. 在**配置规则**页面上，通过完成以下步骤创建规则：

   1. 对于**规则名称**，键入一个唯一的规则名称。

   1. 对于**描述**，键入规则的描述。

   1. 对于 **Guard 运行时版本**，请为您的 AWS Config 自定义策略规则选择运行时系统。

   1. 对于**规则内容**，可以为其填充规则的 Guard 自定义策略。

   1. 对于**评估模式**，请选择在资源创建和管理过程中何 AWS Config 时评估您的资源。根据规则， AWS Config 可以在置备资源之前、资源调配之后或两者兼而有之地评估您的资源配置。

      1. 选择**开启主动评估**，以允许您在部署资源之前对资源的配置设置进行评估。

         开启主动评估后，您可以使用 [StartResourceEvaluation](https://docs.aws.amazon.com/config/latest/APIReference/API_StartResourceEvaluation.html)API 和 [GetResourceEvaluationSummary](https://docs.aws.amazon.com/config/latest/APIReference/API_GetResourceEvaluationSummary.html)API 来检查您在这些命令中指定的资源是否会被您所在地区的账户中的主动规则标记为 “不合规”。

          有关使用此命令的更多信息，请参阅[使用 AWS Config 规则评估您的资源](https://docs.aws.amazon.com/config/latest/developerguide/evaluating-your-resources.html#evaluating-your-resources-proactive)。有关支持主动评估的托管规则[列表，请参阅按评估模式列出的 AWS Config 托管规则](https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-evaluation-mode.html)列表。

      1. 选择**开启侦查评估**以评估您的现有资源的配置设置。

         对于侦探评估， AWS Config 自定义策略规则由**配置更改**启动。将预先选择以下选项。
         +  **资源** – 在创建、更改或删除与指定资源类型（或类型和标识符）匹配的资源时。
         +  **标签** – 在创建、更改或删除包含指定标签的资源时。
         +  **所有更改**-创建、更改或删除记录的资源时。 AWS Config 

         AWS Config 当它检测到与规则范围相匹配的资源发生变化时，就会运行评估。您可以使用范围来限制哪些资源启动评估。否则，当配置后的资源发生变化时，就会启动评估。

   1. 对于**参数**，如果您的规则包含参数，可以自定义所提供的键的值。参数是资源在被视为符合规则之前必须遵守的属性。

1. 在**审核和创建**页面上，查看您的所有选择，然后再将规则添加到您的。 AWS 账户

1. 查看完规则后，选择**添加规则**。

------
#### [ Using the AWS CLI ]

使用 [https://docs.aws.amazon.com/cli/latest/reference/configservice/put-config-rule.html](https://docs.aws.amazon.com/cli/latest/reference/configservice/put-config-rule.html) 命令。

`Owner` 字段应为。`CUSTOM_POLICY` AWS Config 自定义策略规则需要以下附加字段：
+ `Runtime`：您的 AWS Config 自定义策略规则的运行时系统。
+ `PolicyText`：包含 AWS Config 自定义策略规则逻辑的策略定义。
+ `EnableDebugLogDelivery`：用于为 AWS Config 自定义策略规则启用调试日志记录的布尔表达式。默认值为 `false`。

------
#### [ Using the API Reference ]

使用 [PutConfigRule](https://docs.aws.amazon.com/config/latest/APIReference/API_PutConfigRule.html) 操作。

`Owner` 字段应为。`CUSTOM_POLICY` AWS Config 自定义策略规则需要以下附加字段：
+ `Runtime`：您的 AWS Config 自定义策略规则的运行时系统。
+ `PolicyText`：包含 AWS Config 自定义策略规则逻辑的策略定义。
+ `EnableDebugLogDelivery`：用于为 AWS Config 自定义策略规则启用调试日志记录的布尔表达式。默认值为 `false`。

------

## 为 AWS Config 自定义策略规则编写规则内容
<a name="config-custom-policy-rules"></a>

使用 AWS Config 自定义策略规则，您可以使用 AWS CloudFormation Guard 的域特定语言 (DSL) 来评估资源配置。本主题提供了编写自定义策略规则的模式和最佳实践。

有关如何使用 Guard 编写规则的更多信息，请参阅 Guard 用户指南中的[编写 AWS CloudFormation 防护规则](https://docs.aws.amazon.com/cfn-guard/latest/ug/writing-rules.html)和 G [AWS CloudFormation uard 2.0 在 Guard GitHub 存储库中的操作模式](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard)。

### 基本规则结构
<a name="config-custom-policy-rules-structure"></a>

使用以下基本格式创建规则：

```
# Basic rule format
rule <rule_name> when
    resourceType == "<AWS::Service::Resource>" {
    # Evaluation clauses
}

# Example with filtering
let resources_of_type = Resources.*[ Type == 'AWS::Service::Resource' ]
rule check_resources when %resources_of_type !empty {
    %resources_of_type.configuration.property == expected_value
}
```

### 关键组件
<a name="config-custom-policy-rules-components"></a>

配置  
包含资源配置的内容。

supplementaryConfiguration  
包含资源配置的其他内容。 AWS Config 为某些资源类型返回此字段，以补充为配置字段返回的信息。

resourceType  
AWS 正在评估的资源类型。

resourceId  
资源的 ID（例如，`sg-xxxxxx`）。

accountId  
与资源关联 AWS 账户 的 12 位数字 ID。

### 常见模式
<a name="config-custom-policy-rules-patterns"></a>

------
#### [ Status checks ]

```
let allowed_status = ['ACTIVE', 'RUNNING']
rule check_resource_status when
    resourceType == "AWS::Service::Resource" {
    configuration.status IN %allowed_status
}
```

------
#### [ Required properties ]

```
rule check_required_properties when
    resourceType == "AWS::Service::Resource" {
    configuration.propertyName exists
    configuration.propertyName is_string  # or is_list, is_struct
}
```

------
#### [ Query blocks ]

```
configuration.Properties {
    property1 exists
    property2 is_string
    property3 IN [allowed_value1, allowed_value2]
}
```

------
#### [ Conditional evaluation ]

```
when configuration.feature_enabled == true {
    configuration.feature_settings exists
    configuration.feature_settings is_struct
}
```

------
#### [ Custom messages ]

```
rule check_compliance when
    resourceType == "AWS::Service::Resource" {
    configuration.property == expected_value <<Custom error message explaining the requirement>>
}}
```

------

### 高级功能
<a name="config-custom-policy-rules-advanced"></a>

------
#### [ Range checks ]

```
rule check_numeric_limits {
    # Inclusive range (lower_limit <= value <= upper_limit)
    configuration.value IN r[minimum_value, maximum_value]  

    # Exclusive range (lower_limit < value < upper_limit)
    configuration.value IN r(exclusive_min, exclusive_max)  

    # Left inclusive, right exclusive (lower_limit <= value < upper_limit)
    configuration.value IN r[minimum_value, exclusive_max)

    # Left exclusive, right inclusive (lower_limit < value <= upper_limit)
    configuration.value IN r(exclusive_min, maximum_value]
}
```

------
#### [ Combining conditions ]

```
# AND conditions (implicit through new lines)
condition_1
condition_2

# OR conditions (explicit)
condition_3 OR
condition_4
```

------
#### [ Chaining rules ]

```
rule check_prerequisites {
    configuration.required_setting exists
}

rule check_details when check_prerequisites {
    configuration.required_setting == expected_value
}
```

------

### 最佳实践
<a name="config-custom-policy-rules-best-practices"></a>
+ 将变量与 `let` 语句结合使用来提高可读性。
+ 使用命名规则块对相关检查进行分组。
+ 包括描述性注释。
+ 使用适当的运算符（`exists`、`is_string`、`is_list`）。
+ 使用支持不区分大小写匹配的正则表达式模式。

### 例如： dynamodb-pitr-enabled
<a name="config-custom-policy-rules-example"></a>

以下示例显示了 AWS Config 托管规则的 AWS Config 自定义策略规则版本的策略定义[dynamodb-pitr-enabled](dynamodb-pitr-enabled.md)。此规则检查 DynamoDB 表 Point-in-Time是否启用了恢复。

```
# Check if DynamoDB tables have Point-in-Time Recovery enabled
let status = ['ACTIVE']

rule tableisactive when
    resourceType == "AWS::DynamoDB::Table" {
    configuration.tableStatus == %status
}

rule checkcompliance when
    resourceType == "AWS::DynamoDB::Table"
    tableisactive {
    let pitr = supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus
    %pitr == "ENABLED" <<DynamoDB tables must have Point-in-Time Recovery enabled>>
}
```

# 创建 AWS Config 自定义 Lambda 规则
<a name="evaluate-config_develop-rules_lambda-functions"></a>

您可以开发自定义规则并将其添加到 AWS Config AWS Lambda 函数中。

您可以将每条自定义规则与一个 Lambda 函数相关联，该函数包含评估您的 AWS 资源是否符合该规则的逻辑。将此函数与您的规则关联后，该规则会定期或因响应配置更改而调用该函数。然后，该函数会评估您的资源是否符合您的规则，并将其评估结果发送到 AWS Config。

## AWS 规则开发套件 (RDK)
<a name="rdk"></a>

 AWS 规则开发套件 (RDK) 旨在支持直观且高效的 “合规即代码” 工作流程。它抽象了与部署由自定义 Lambda 函数支持的 AWS Config 规则相关的大部分无差别的繁重工作，并提供了简化的迭代流程。 develop-deploy-monitor

有关 step-by-step说明，请参阅[AWS 规则开发套件 (RDK) 文档](https://aws-config-rdk.readthedocs.io/en/master)。

## AWS Config 规则的示例 AWS Lambda 函数 (Node.js)
<a name="evaluate-config_develop-rules_nodejs-sample"></a>

AWS Lambda 执行函数以响应 AWS 服务发布的事件。 AWS Config 自定义 Lambda 规则的函数接收由发布的事件 AWS Config，然后该函数使用从该事件中接收的数据以及从 AWS Config API 检索的数据来评估规则的合规性。用于 Config 规则的函数的运作方式会因其执行的评估是由配置更改触发还是定期触发而有所不同。

有关 AWS Lambda 函数中常见模式的信息，请参阅《*AWS Lambda 开发人员指南》*中的[编程模型](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html)。

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

AWS Config 当它检测到自定义规则范围内的资源的配置更改时，将调用如下例所示的函数。

如果您使用 AWS Config 控制台创建与函数相关联的规则（例如此示例），请选择**配置更改**作为触发器类型。如果您使用 AWS Config API 或创建规则， AWS CLI 请将`MessageType`属性设置为`ConfigurationItemChangeNotification`和`OversizedConfigurationItemChangeNotification`。通过这些设置，无论何时由于资源更改而 AWS Config 生成配置项目或超大配置项目，都可触发您的规则。

此示例评估您的资源并检查实例是否匹配资源类型。`AWS::EC2::Instance`此规则在 AWS Config 生成配置项或过大配置项通知时触发。

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

**函数运作**

本函数在运行时执行以下操作：

1. 该函数在将`event`对象 AWS Lambda 传递给`handler`函数时运行。在此示例中，该函数接受可选`callback`参数，该参数用于向调用者返回信息。 AWS Lambda 还传递一个`context`对象，其中包含函数在运行时可以使用的信息和方法。请注意，在新版本的 Lambda 中，不再使用上下文。

1. 此函数检查事件的 `messageType` 是配置项还是过大配置项，然后返回配置项。

1. 处理程序调用 `isApplicable` 函数来确定资源是否已删除。
**注意**  
报告已删除资源的规则应返回 `NOT_APPLICABLE` 的评估结果，以避免不必要的规则评估。

1. 处理程序调用该`evaluateChangeNotificationCompliance`函数并传递在事件中 AWS Config 发布的`configurationItem`和`ruleParameters`对象。

   函数首先评估资源是否为 EC2 实例。如果资源不是 EC2 实例，函数会返回 `NOT_APPLICABLE` 这一合规性值。

   然后，函数评估配置项中的 `instanceType` 属性是否与 `desiredInstanceType` 参数值一致。如果值相等，该函数将返回。`COMPLIANT`如果值不相等，该函数将返回。`NON_COMPLIANT`

1. 处理程序准备 AWS Config 通过初始化`putEvaluationsRequest`对象将评估结果发送到。该对象包含 `Evaluations` 参数，这一参数用于识别受评估资源的合规性结果、资源类型和 ID。该`putEvaluationsRequest`对象还包括事件的结果标记，用于标识规则和事件 AWS Config。

1.  AWS Config 通过将对象传递给`config`客户端`putEvaluations`的方法，处理程序将评估结果发送到。

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

AWS Config 将调用如下例所示的函数进行定期评估。定期评估按您在 AWS Config中定义规则时指定的频率进行。

如果您使用 AWS Config 控制台创建与函数相关联的规则（例如此示例），请选择**周期**作为触发器类型。如果您使用 AWS Config API 或创建规则， AWS CLI 请将`MessageType`属性设置为`ScheduledNotification`。

本示例会检查指定资源的总数是否超出指定的最大值。

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

**函数运作**

本函数在运行时执行以下操作：

1. 该函数在将`event`对象 AWS Lambda 传递给`handler`函数时运行。在此示例中，该函数接受可选`callback`参数，该参数用于向调用者返回信息。 AWS Lambda 还传递一个`context`对象，其中包含函数在运行时可以使用的信息和方法。请注意，在新版本的 Lambda 中，不再使用上下文。

1. 为计数指定类型的资源，处理程序会调用 `countResourceTypes` 函数，而且它传递其从事件收到的 `applicableResourceType` 参数。`countResourceTypes` 函数调用 `listDiscoveredResources` 客户端的 `config` 方法，该方法返回适用资源的标识符列表。该函数使用此列表的长度来确定适用资源的数量，而且它将此计数返回到处理程序。

1. 处理程序准备 AWS Config 通过初始化`putEvaluationsRequest`对象将评估结果发送到。此对象包括`Evaluations`参数，该参数标识合规性结果和 AWS 账户 在事件中发布的结果。您可以使用 `Evaluations` 参数将结果应用于 AWS Config支持的任何资源类型。该`putEvaluationsRequest`对象还包括事件的结果标记，用于标识规则和事件 AWS Config。

1. 在 `putEvaluationsRequest` 对象中，处理程序调用 `evaluateCompliance` 函数。此函数测试适用资源的数量是否超出分配给事件所提供的 `maxCount` 参数的最大值。如果资源的数量超出最大值，函数将返回。`NON_COMPLIANT`如果资源的数量没有超出最大值，函数将返回。`COMPLIANT`

1.  AWS Config 通过将对象传递给`config`客户端`putEvaluations`的方法，处理程序将评估结果发送到。

------

## AWS Config 规则的示例 AWS Lambda 函数 (Python)
<a name="evaluate-config_develop-rules_python-sample"></a>

AWS Lambda 执行函数以响应 AWS 服务发布的事件。 AWS Config 自定义 Lambda 规则的函数接收由发布的事件 AWS Config，然后该函数使用从该事件中接收的数据以及从 AWS Config API 检索的数据来评估规则的合规性。用于 Config 规则的函数的运作方式会因其执行的评估是由配置更改触发还是定期触发而有所不同。

有关 AWS Lambda 函数中常见模式的信息，请参阅《*AWS Lambda 开发人员指南》*中的[编程模型](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html)。

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

AWS Config 当它检测到自定义规则范围内的资源的配置更改时，将调用如下例所示的函数。

如果您使用 AWS Config 控制台创建与函数相关联的规则（例如此示例），请选择**配置更改**作为触发器类型。如果您使用 AWS Config API 或创建规则， AWS CLI 请将`MessageType`属性设置为`ConfigurationItemChangeNotification`和`OversizedConfigurationItemChangeNotification`。通过这些设置，无论何时由于资源更改而 AWS Config 生成配置项目或超大配置项目，都可触发您的规则。

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

**函数运作**

本函数在运行时执行以下操作：

1. 该函数在将`event`对象 AWS Lambda 传递给`handler`函数时运行。在此示例中，该函数接受可选`callback`参数，该参数用于向调用者返回信息。 AWS Lambda 还传递一个`context`对象，其中包含函数在运行时可以使用的信息和方法。请注意，在新版本的 Lambda 中，不再使用上下文。

1. 此函数检查事件的 `messageType` 是配置项还是过大配置项，然后返回配置项。

1. 处理程序调用 `isApplicable` 函数来确定资源是否已删除。
**注意**  
报告已删除资源的规则应返回 `NOT_APPLICABLE` 的评估结果，以避免不必要的规则评估。

1. 处理程序调用该`evaluateChangeNotificationCompliance`函数并传递在事件中 AWS Config 发布的`configurationItem`和`ruleParameters`对象。

   函数首先评估资源是否为 EC2 实例。如果资源不是 EC2 实例，函数会返回 `NOT_APPLICABLE` 这一合规性值。

   然后，函数评估配置项中的 `instanceType` 属性是否与 `desiredInstanceType` 参数值一致。如果值相等，该函数将返回。`COMPLIANT`如果值不相等，该函数将返回。`NON_COMPLIANT`

1. 处理程序准备 AWS Config 通过初始化`putEvaluationsRequest`对象将评估结果发送到。该对象包含 `Evaluations` 参数，这一参数用于识别受评估资源的合规性结果、资源类型和 ID。该`putEvaluationsRequest`对象还包括事件的结果标记，用于标识规则和事件 AWS Config。

1.  AWS Config 通过将对象传递给`config`客户端`putEvaluations`的方法，处理程序将评估结果发送到。

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

AWS Config 将调用如下例所示的函数进行定期评估。定期评估按您在 AWS Config中定义规则时指定的频率进行。

如果您使用 AWS Config 控制台创建与函数相关联的规则（例如此示例），请选择**周期**作为触发器类型。如果您使用 AWS Config API 或创建规则， AWS CLI 请将`MessageType`属性设置为`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'])
```

**函数运作**

本函数在运行时执行以下操作：

1. 该函数在将`event`对象 AWS Lambda 传递给`handler`函数时运行。在此示例中，该函数接受可选`callback`参数，该参数用于向调用者返回信息。 AWS Lambda 还传递一个`context`对象，其中包含函数在运行时可以使用的信息和方法。请注意，在新版本的 Lambda 中，不再使用上下文。

1. 为计数指定类型的资源，处理程序会调用 `countResourceTypes` 函数，而且它传递其从事件收到的 `applicableResourceType` 参数。`countResourceTypes` 函数调用 `listDiscoveredResources` 客户端的 `config` 方法，该方法返回适用资源的标识符列表。该函数使用此列表的长度来确定适用资源的数量，而且它将此计数返回到处理程序。

1. 处理程序准备 AWS Config 通过初始化`putEvaluationsRequest`对象将评估结果发送到。此对象包括`Evaluations`参数，该参数标识合规性结果和 AWS 账户 在事件中发布的结果。您可以使用 `Evaluations` 参数将结果应用于 AWS Config支持的任何资源类型。该`putEvaluationsRequest`对象还包括事件的结果标记，用于标识规则和事件 AWS Config。

1. 在 `putEvaluationsRequest` 对象中，处理程序调用 `evaluateCompliance` 函数。此函数测试适用资源的数量是否超出分配给事件所提供的 `maxCount` 参数的最大值。如果资源的数量超出最大值，函数将返回。`NON_COMPLIANT`如果资源的数量没有超出最大值，函数将返回。`COMPLIANT`

1.  AWS Config 通过将对象传递给`config`客户端`putEvaluations`的方法，处理程序将评估结果发送到。

------

## AWS Config 规则的示例事件
<a name="evaluate-config_develop-rules_example-events"></a>

当规则的触发器发生时，通过发布事件来 AWS Config 调用规则的 AWS Lambda 函数。然后通过将事件传递给函数的处理程序来 AWS Lambda 执行该函数。

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

AWS Config 当它检测到规则范围内的资源的配置更改时会发布事件。下面的示例事件演示规则被某个 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 ]

某些资源更改会生成过大配置项。下面的示例事件演示规则被某个 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 当它以您指定的频率（例如每 24 小时）评估您的资源时发布一个事件。下面的示例事件演示规则被定期频率触发。

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

------

### 事件属性
<a name="w2aac20c19c20c13b1b7"></a>

 AWS Config 事件的 JSON 对象包含以下属性：

`invokingEvent`  
触发规则评估的事件。如果事件是为了响应资源配置更改而发布的，则此属性的值是一个包含 JSON `configurationItem` 或 `configurationItemSummary`（对于过大配置项）的字符串。配置项目表示 AWS Config 检测到更改时资源的状态。有关配置项目的示例，请参阅中的`get-resource-config-history` AWS CLI 命令生成的输出[查看配置历史记录](view-manage-resource-console.md#get-config-history-cli)。  
如果事件是针对定期评估而发布的，则值是一个包含 JSON 对象的字符串。该对象包含关于已触发的评估的信息。  
对于每种类型的事件，函数必须通过 JSON 解析程序解析字符串，以便能够评估其内容，如下面的 Node.js 示例中所示：  

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

`ruleParameters`  
函数会将其作为评估逻辑的一部分来处理的键/值对。您可以在使用 AWS Config 控制台创建自定义 Lambda 规则时定义参数。您也可以在 `PutConfigRule` AWS Config API 请求或`put-config-rule` AWS CLI 命令中使用`InputParameters`属性定义参数。  
参数的 JSON 代码包含在字符串中，因此，函数必须通过 JSON 解析程序解析字符串，以便能够评估其内容，如下面的 Node.js 示例中所示：  

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

`resultToken`  
函数在调用时必须传递给 AWS Config 的标`PutEvaluations`记。

`eventLeftScope`  
一个布尔值，表示要评估的 AWS 资源是否已从规则的作用域中移除。如果值为，`true`则该函数表示可通过传递 `NOT_APPLICABLE` 作为 `ComplianceType` 调用中的 `PutEvaluations` 属性值来忽略评估。

`executionRoleArn`  
分配给的 IAM 角色的 ARN。 AWS Config

`configRuleArn`  
 AWS Config 分配给规则的 ARN。

`configRuleName`  
您为导致 AWS Config 发布事件和调用函数的规则分配的名称。

`configRuleId`  
 AWS Config 分配给规则的 ID。

`accountId`  
拥有 AWS 账户 该规则的 ID。

`version`  
由分配的版本号 AWS。如果向 AWS Config 事件 AWS 添加属性，则版本将增加。如果函数需要仅在匹配或超过特定版本的事件中的属性，则该函数可以检查此属性的值。  
 AWS Config 事件的当前版本是 1.0。

# 为 AWS Config 自定义 Lambda 规则管理已删除的资源
<a name="evaluate-config_develop-rules-delete"></a>

报告已删除资源的规则应返回 `NOT_APPLICABLE` 的评估结果，以避免不必要的规则评估。

当您删除资源时， AWS Config 会`ResourceDeleted`为创建一个 `configurationItem` with `configurationItemStatus`。您可以使用此元数据检查规则是否报告了已删除的资源。有关配置项的更多信息，请参阅[概念 \$1 配置项](https://docs.aws.amazon.com/config/latest/developerguide/config-concepts.html#config-items.html)。

包括以下代码片段以检查是否有已删除的资源，并将 AWS Config 自定义 lambda 规则的评估结果设置为（`NOT_APPLICABLE`如果它报告了已删除的资源）：

------
#### [ Custom Lambda Rules (Node.js) ]

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

------
#### [ Custom Lambda Rules (Python) ]

```
# Check whether the resource has been deleted. If the resource was deleted, then the evaluation returns not applicable.
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
```

------

**注意**  
AWS Config 默认情况下，托管规则和 AWS Config 自定义策略规则会处理此行为。  
如果您使用 AWS Config 开发套件 (RDK) 和 AWS Config 开发套件库 (RDKlib) 使用 Python 创建 AWS Config 自定义 lambd 规则，则导入的[评估器](https://github.com/awslabs/aws-config-rdklib/blob/master/rdklib/evaluator.py#L56)类将检查此行为。有关如何使用 RDK 和编写规则的信息 RDKlib，请参阅[使用 RDK 编写规则](https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_components.html#evaluate-config_components_logic)和。 RDKlib