

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 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 ([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 為 AWS Config 自訂規則建立 Lambda 函數。* 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：//[https://console.aws.amazon.com/config/home](https://console.aws.amazon.com/config/home) 開啟 AWS Config 主控台。

1. 在 AWS 管理主控台 選單中，確認區域選擇器已設定為支援 AWS Config 規則的區域 AWS 。如需支援區域的清單，請參閱《*Amazon Web Services 一般參考*》中的 [AWS Config 區域與端點](https://docs.aws.amazon.com/general/latest/gr/awsconfig.html)。

1. 在左側導覽中，選擇 **規則**。

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 來檢查您在這些命令中指定的資源是否會被您區域中帳戶中的主動規則標記為「NON\$1COMPLIANT」。

          如需使用此命令的詳細資訊，請參閱[使用 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 使用者指南中的撰寫](https://docs.aws.amazon.com/cfn-guard/latest/ug/writing-rules.html) AWS CloudFormation Guard 規則和 [AWS CloudFormation Guard GitHub 儲存庫中的 Guard 2.0 的操作模式](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard)。 GitHub 

### 基本規則結構
<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  
與資源相關聯的 12 位數 AWS 帳戶 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`)。
+ 使用不區分大小寫比對的 regex 模式。

### 範例：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) 旨在支援直覺且具生產力的「Compliance-as-Code」工作流程。它抽象了與部署由自訂 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. 處理常式會將 物件傳遞至 `config`用戶端的 `putEvaluations`方法， AWS Config 將評估結果傳送至 。

------
#### [ 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. 處理常式會將 物件傳遞至 `config`用戶端的 `putEvaluations`方法， AWS Config 將評估結果傳送至 。

------

## AWS Config 規則 (Python) 的範例 AWS Lambda 函數
<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. 處理常式會將 物件傳遞至 `config`用戶端的 `putEvaluations`方法， AWS Config 將評估結果傳送至 。

------
#### [ 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. 處理常式會將 物件傳遞至 `config`用戶端的 `putEvaluations`方法， AWS Config 將評估結果傳送至 。

------

## 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`  
函數必須與`PutEvaluations`呼叫 AWS Config 一起傳遞的字符。

`eventLeftScope`  
布林值，指出要評估 AWS 的資源是否已從規則的範圍中移除。若值為 `true`，則函數會透過在 `PutEvaluations` 呼叫中將 `NOT_APPLICABLE` 做為 `ComplianceType` 屬性的值傳遞，指出可忽略評估。

`executionRoleArn`  
指派給 之 IAM 角色的 ARN AWS Config。

`configRuleArn`  
 AWS Config 指派給規則的 ARN。

`configRuleName`  
您指派給規則的名稱，導致 AWS Config 發佈事件並叫用 函數。

`configRuleId`  
 AWS Config 指派給規則的 ID。

`accountId`  
 AWS 帳戶 擁有規則的 ID。

`version`  
指派的版本編號 AWS。如果 AWS 將屬性新增至 AWS Config 事件，則版本會遞增。若函數需要只存在於符合或超過特定版本事件中的屬性，則該函數可檢查此屬性的值。  
 AWS Config 事件的目前版本為 1.0。

# 管理 AWS Config 自訂 Lambda 規則的已刪除資源
<a name="evaluate-config_develop-rules-delete"></a>

報告已刪除資源的規則，應傳回 `NOT_APPLICABLE` 的評估結果，以避免不必要的規則評估。

當您刪除資源時， 會使用 `configurationItem``ResourceDeleted`為 AWS Config 建立 `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 和 RDKLib 撰寫規則](https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_components.html#evaluate-config_components_logic)》。