Ao acionar uma regra de função personalizada, o Cloud Config invoca a função associada no Function Compute para avaliar seus recursos e retornar um resultado de conformidade. Esta página explica a estrutura do código da função e os parâmetros de entrada com um exemplo em Python.
Regra de função personalizada
Uma regra de função personalizada utiliza uma função do Function Compute para definir e executar sua lógica de avaliação.
Cenários
Se as regras gerenciadas e condicionais não atenderem aos seus requisitos de conformidade, escreva funções personalizadas para avaliações complexas. Cenários adicionais e exemplos de código estão disponíveis na Biblioteca de amostras de regras de função personalizada.
Mecanismo
A figura a seguir ilustra o fluxo de execução de uma regra de função personalizada.

Etapas de execução:
Crie uma função no Function Compute.
-
Crie uma regra personalizada baseada na função no Cloud Config. O sistema aciona uma avaliação automaticamente.
NotaO Cloud Config aciona automaticamente uma avaliação após a criação da regra.
O Cloud Config usa sua função vinculada ao serviço (AliyunServiceRoleForConfig) para obter permissões das operações de API GetFunction e InvokeFunction.
O Cloud Config chama a operação de API InvokeFunction para executar a função, transmitindo o item de configuração e as informações da regra.
A função avalia o recurso.
-
A função chama a operação de API PutEvaluations para retornar o resultado da avaliação de conformidade ao Cloud Config.
O Cloud Config salva e exibe o resultado no console. Em seguida, corrija recursos não conformes ou entregue dados a outros serviços da Alibaba Cloud.
Código da função
Uma regra consiste em uma lógica de avaliação armazenada em uma função. O Cloud Config invoca essa função durante a auditoria. O código da função possui duas partes:
-
handlerO
handleré a função de entrada invocada ao acionar a regra. Especifique o handler ao criar uma função no console do Function Compute. Consulte Handlers.NotaO Cloud Config suporta apenas event handlers.
-
put_evaluationsEsta função chama a operação de API PutEvaluations para enviar o resultado da avaliação de conformidade ao Cloud Config.
O código a seguir apresenta um exemplo em Python:
# #!/usr/bin/env python
# # -*- encoding: utf-8 -*-
import json
import logging
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
logger = logging.getLogger()
# The compliance type of a resource.
COMPLIANCE_TYPE_COMPLIANT = 'COMPLIANT'
COMPLIANCE_TYPE_NON_COMPLIANT = 'NON_COMPLIANT'
COMPLIANCE_TYPE_NOT_APPLICABLE = 'NOT_APPLICABLE'
# The delivery type of a resource configuration.
CONFIGURATION_TYPE_COMMON = 'COMMON'
CONFIGURATION_TYPE_OVERSIZE = 'OVERSIZE'
CONFIGURATION_TYPE_NONE = 'NONE'
# The entry function that orchestrates and processes the business logic.
def handler(event, context):
"""
The handler function.
:param event: The event.
:param context: The context.
:return: The evaluation result.
"""
# Validate the event. You can copy this code block.
evt = validate_event(event)
if not evt:
return None
creds = context.credentials
rule_parameters = evt.get('ruleParameters')
result_token = evt.get('resultToken')
invoking_event = evt.get('invokingEvent')
ordering_timestamp = evt.get('orderingTimestamp')
# The configuration of the resource. The trigger of the rule must be set to Configuration Change. When you create or manually run a rule, Cloud Config invokes the function to evaluate all resources one by one. If the configuration of a resource changes, Cloud Config automatically invokes the function to evaluate the resource based on the change information.
configuration_item = invoking_event.get('configurationItem')
account_id = configuration_item.get('accountId')
resource_id = configuration_item.get('resourceId')
resource_type = configuration_item.get('resourceType')
region_id = configuration_item.get('regionId')
# Check whether the size of the delivered resource configuration is greater than or equal to 100 KB. If it is, you must call the GetDiscoveredResource operation to query the resource details.
configuration_type = invoking_event.get('configurationType')
if configuration_type and configuration_type == CONFIGURATION_TYPE_OVERSIZE:
resource_result = get_discovered_resource(creds, resource_id, resource_type, region_id)
resource_json = json.loads(resource_result)
configuration_item["configuration"] = resource_json["DiscoveredResourceDetail"]["Configuration"]
# Evaluate the resource. You must implement the evaluation logic based on your business requirements. The following code is for reference only.
compliance_type, annotation = evaluate_configuration_item(
rule_parameters, configuration_item)
# Set the evaluation result. The format must comply with the following example.
evaluations = [
{
'accountId': account_id,
'complianceResourceId': resource_id,
'complianceResourceType': resource_type,
'complianceRegionId': region_id,
'orderingTimestamp': ordering_timestamp,
'complianceType': compliance_type,
'annotation': annotation
}
]
# Submit the evaluation result to Cloud Config. You can copy this code block.
put_evaluations(creds, result_token, evaluations)
return evaluations
# Evaluate the resource based on the rule information and resource configuration. You must implement the evaluation logic based on your business requirements. The following code is for reference only.
def evaluate_configuration_item(rule_parameters, configuration_item):
"""
The evaluation logic.
:param rule_parameters: The rule information.
:param configuration_item: The resource configuration.
:return: The compliance type.
"""
# Initialize the return value.
compliance_type = COMPLIANCE_TYPE_NON_COMPLIANT
annotation = None
# Obtain the full resource configuration.
full_configuration = configuration_item['configuration']
if not full_configuration:
annotation = 'Configuration is empty.'
return compliance_type, annotation
# Convert the configuration to the JSON format.
configuration = parse_json(full_configuration)
if not configuration:
annotation = 'Configuration:{} is invalid.'.format(full_configuration)
return compliance_type, annotation
return compliance_type, annotation
def validate_event(event):
"""
Validate the event.
:param event: The event.
:return: A JSON object.
"""
if not event:
logger.error('Event is empty.')
evt = parse_json(event)
logger.info('Loading event: %s .' % evt)
if 'resultToken' not in evt:
logger.error('ResultToken is empty.')
return None
if 'ruleParameters' not in evt:
logger.error('RuleParameters is empty.')
return None
if 'invokingEvent' not in evt:
logger.error('InvokingEvent is empty.')
return None
return evt
def parse_json(content):
"""
Convert data to the JSON format.
:param content: A JSON string.
:return: A JSON object.
"""
try:
return json.loads(content)
except Exception as e:
logger.error('Parse content:{} to json error:{}.'.format(content, e))
return None
# Submit the evaluation result to Cloud Config. You can copy this code block.
def put_evaluations(creds, result_token, evaluations):
"""
Call an API operation to return and write the evaluation result.
:param creds: The credentials of the function.
:param result_token: The result token.
:param evaluations: The evaluation results.
:return: None
"""
# The service-linked role for Function Compute must have the AliyunConfigFullAccess policy attached.
client = AcsClient(creds.access_key_id, creds.access_key_secret, region_id='ap-southeast-1')
# Create a request and set its parameters. The domain name is config.ap-southeast-1.aliyuncs.com.
request = CommonRequest()
request.set_domain('config.ap-southeast-1.aliyuncs.com')
request.set_version('2019-01-08')
request.set_action_name('PutEvaluations')
request.add_body_params('ResultToken', result_token)
request.add_body_params('Evaluations', evaluations)
request.add_body_params('SecurityToken', creds.security_token)
request.set_method('POST')
try:
response = client.do_action_with_exception(request)
logger.info('PutEvaluations with request: {}, response: {}.'.format(request, response))
except Exception as e:
logger.error('PutEvaluations error: %s' % e)
# Retrieve the full resource details. You can copy this code block.
def get_discovered_resource(creds, resource_id, resource_type, region_id):
"""
Call an API operation to obtain the resource configuration details.
:param creds: The credentials of the function.
:param resource_id: The resource ID.
:param resource_type: The resource type.
:param region_id: The ID of the region in which the resource resides.
:return: The resource details.
"""
# The service-linked role for Function Compute must have the AliyunConfigFullAccess policy attached.
client = AcsClient(creds.access_key_id, creds.access_key_secret, region_id='ap-southeast-1')
request = CommonRequest()
request.set_domain('config.ap-southeast-1.aliyuncs.com')
request.set_version('2020-09-07')
request.set_action_name('GetDiscoveredResource')
request.add_query_param('ResourceId', resource_id)
request.add_query_param('ResourceType', resource_type)
request.add_query_param('Region', region_id)
request.add_query_param('SecurityToken', creds.security_token)
request.set_method('GET')
try:
response = client.do_action_with_exception(request)
resource_result = str(response, encoding='utf-8')
return resource_result
except Exception as e:
logger.error('GetDiscoveredResource error: %s' % e)
Verifique o campo configuration no item de configuração do console do Cloud Config para identificar os nomes dos parâmetros da sua regra. Consulte a Etapa 6 em Visualizar informações do recurso.
Entradas da função
Os parâmetros de entrada da função consistem em um item de configuração e nas informações da regra. O conteúdo enviado ao Function Compute varia conforme o Trigger da regra.
Para obter os parâmetros de entrada da função no Function Compute, visualize os logs de invocação.
-
Se o Trigger da regra estiver definido apenas como Periodic, o Cloud Config não envia itens de configuração para o Function Compute.
Na primeira execução, execução agendada ou manual da regra, o Cloud Config envia um único registro sem item de configuração. Exemplo:
{ "orderingTimestamp": 1716365226714, "invokingEvent": { "accountId": 120886317861****, "messageType": "ScheduledNotification", "notificationCreationTimestamp": 1716365226714, "configurationType": "NONE" }, "ruleParameters": { "CpuCount": "2" }, "resultToken": "HLQr3BZx/C+DLjwudFcYdXxZFPF2HnGqlg1uHceZ5kDEFeQF2K5LZGofyhn+GE4NP5VgkwANUH3qcdeSjWwODk1ymtmLWLzFV4JForVWYIKdbwwhbDBOgVwF7Ov9c3uVCNz/KpxNElwhTzMkZB95U1vmLs4vUYXuB/Txw4jiCYBYZZnVumhwXWswTLvAhIe5Y451FckObyM3I47AaB+4KtDW3I5q8O+Kx7eSYkqqGTawmJEYjvWXz9CHHMLFtNYyJX54a35mpVdxFSvgeXYDJTStxqb+d9UH/162fZh7T78OHxpQZgl8bcXzZhml****" } -
Se o Trigger da regra incluir Configuration Changes, o Cloud Config envia o item de configuração para o Function Compute.
Na primeira execução, execução agendada ou manual, o Cloud Config envia os itens de configuração individualmente. Ao criar ou alterar um recurso, o Cloud Config envia apenas o item de configuração afetado. Exemplo:
{ "orderingTimestamp":1695786337959, "invokingEvent":{ "accountId":120886317861****, "messageType":"Manual", "notificationCreationTimestamp":1695786337959, "configurationType":"COMMON", "configurationItem":{ "accountId":120886317861****, "arn":"acs:ecs:ap-southeast-1:120886317861****:instance/i-t4n0vr6x7v54jdbu****", "availabilityZone":"ap-southeast-1a", "regionId":"ap-southeast-1", "configuration":"{\\"ResourceGroupId\\":\\"\\",\\"Memory\\":4096,\\"InstanceChargeType\\":\\"PostPaid\\",\\"Cpu\\":2,\\"OSName\\":\\"Alibaba Cloud Linux 3.2104 LTS 64\xe4\xbd\x8d\\",\\"InstanceNetworkType\\":\\"vpc\\",\\"InnerIpAddress\\":{\\"IpAddress\\":[]},\\"ExpiredTime\\":\\"2099-12-31T15:59Z\\",\\"ImageId\\":\\"aliyun_3_x64_20G_alibase_20230727.vhd\\",\\"EipAddress\\":{\\"AllocationId\\":\\"\\",\\"IpAddress\\":\\"\\",\\"InternetChargeType\\":\\"\\"},\\"ImageOptions\\":{},\\"VlanId\\":\\"\\",\\"HostName\\":\\"iZt4n0vr6x7v54jdbuk****\\",\\"Status\\":\\"Running\\",\\"HibernationOptions\\":{\\"Configured\\":false},\\"MetadataOptions\\":{\\"HttpTokens\\":\\"\\",\\"HttpEndpoint\\":\\"\\"},\\"InstanceId\\":\\"i-t4n0vr6x7v54jdbu****\\",\\"StoppedMode\\":\\"Not-applicable\\",\\"CpuOptions\\":{\\"ThreadsPerCore\\":2,\\"Numa\\":\\"ON\\",\\"CoreCount\\":1},\\"StartTime\\":\\"2023-08-18T09:02Z\\",\\"DeletionProtection\\":false,\\"VpcAttributes\\":{\\"PrivateIpAddress\\":{\\"IpAddress\\":[\\"192.168.XX.XX\\"]},\\"VpcId\\":\\"vpc-t4nmwd0l9a7aj09yr****\\",\\"VSwitchId\\":\\"vsw-t4njclm0dlz2szayi****\\",\\"NatIpAddress\\":\\"\\"},\\"SecurityGroupIds\\":{\\"SecurityGroupId\\":[\\"sg-t4n5pulxj2lvechw****\\"]},\\"InternetChargeType\\":\\"PayByTraffic\\",\\"InstanceName\\":\\"zs-test-peer****\\",\\"DeploymentSetId\\":\\"\\",\\"InternetMaxBandwidthOut\\":0,\\"SerialNumber\\":\\"8c3fadf7-2ea1-4486-84ce-7784aeb7****\\",\\"OSType\\":\\"linux\\",\\"CreationTime\\":\\"2023-08-18T09:02Z\\",\\"AutoReleaseTime\\":\\"\\",\\"Description\\":\\"\\",\\"InstanceTypeFamily\\":\\"ecs.c7\\",\\"DedicatedInstanceAttribute\\":{\\"Tenancy\\":\\"\\",\\"Affinity\\":\\"\\"},\\"PublicIpAddress\\":{\\"IpAddress\\":[]},\\"GPUSpec\\":\\"\\",\\"NetworkInterfaces\\":{\\"NetworkInterface\\":[{\\"Type\\":\\"Primary\\",\\"PrimaryIpAddress\\":\\"192.168.XX.XX\\",\\"MacAddress\\":\\"00:16:3e:04:XX:XX\\",\\"NetworkInterfaceId\\":\\"eni-t4n16tmnpp794y1o****\\",\\"PrivateIpSets\\":{\\"PrivateIpSet\\":[{\\"PrivateIpAddress\\":\\"192.168.XX.XX\\",\\"Primary\\":true}]}}]},\\"SpotPriceLimit\\":0.0,\\"SaleCycle\\":\\"\\",\\"DeviceAvailable\\":true,\\"InstanceType\\":\\"ecs.c7.large\\",\\"OSNameEn\\":\\"Alibaba Cloud Linux 3.2104 LTS 64 bit\\",\\"SpotStrategy\\":\\"NoSpot\\",\\"IoOptimized\\":true,\\"ZoneId\\":\\"ap-southeast-1a\\",\\"ClusterId\\":\\"\\",\\"EcsCapacityReservationAttr\\":{\\"CapacityReservationPreference\\":\\"\\",\\"CapacityReservationId\\":\\"\\"},\\"DedicatedHostAttribute\\":{\\"DedicatedHostId\\":\\"\\",\\"DedicatedHostName\\":\\"\\",\\"DedicatedHostClusterId\\":\\"\\"},\\"GPUAmount\\":0,\\"OperationLocks\\":{\\"LockReason\\":[]},\\"InternetMaxBandwidthIn\\":-1,\\"Recyclable\\":false,\\"RegionId\\":\\"ap-southeast-1\\",\\"CreditSpecification\\":\\"\\"}", "captureTime":1695786337959, "resourceCreateTime":1692349320000, "resourceId":"i-t4n0vr6x7v54jdbu****", "resourceName":"zs-test-peer****", "resourceGroupId":"rg-acfmw3ty5y7****", "resourceType":"ACS::ECS::Instance", "tags":"{}" } }, "ruleParameters":{ "CpuCount":"2" }, "resultToken":"HLQr3BZx/C+DLjwudFcYdXxZFPF2HnGqlg1uHceZ5kDEFeQF2K5LZGofyhn+GE4NP5VgkwANUH3qcdeSjWwODk1ymtmLWLzFV4JForVWYIKdbwwhbDBOgVwF7Ov9c3uVCNz/KpxNElwhTzMkZB95U1vmLs4vUYXuB/Txw4jiCYBYZZnVumhwXWswTLvAhIe5Y451FckObyM3I47AaB+4KtDW3I5q8O+Kx7eSYkqqGTawmJEYjvWXz9CHHMLFtNYyJX54a35mpVdxFSvgeXYDJTStxqb+d9UH/162fZh7T78OHxpQZgl8bcXzZhml****" }Se um item de configuração tiver 100 KB ou mais, o Cloud Config envia apenas um resumo do recurso sem o campo
configuration. Exemplo:NotaPara obter a configuração completa do recurso, chame a operação de API GetDiscoveredResource.
{ "orderingTimestamp":1695786337959, "invokingEvent":{ "accountId":120886317861****, "messageType":"Manual", "notificationCreationTimestamp":1695786337959, "configurationType":"OVERSIZE", "configurationItem":{ "accountId":120886317861****, "arn":"acs:ecs:ap-southeast-1:120886317861****:instance/i-t4n0vr6x7v54jdbu****", "availabilityZone":"ap-southeast-1a", "regionId":"ap-southeast-1", "captureTime":1695786337959, "resourceCreateTime":1692349320000, "resourceId":"i-t4n0vr6x7v54jdbu****", "resourceName":"zs-test-peer****", "resourceGroupId":"rg-acfmw3ty5y7****", "resourceType":"ACS::ECS::Instance", "tags":"{}" } }, "ruleParameters":{ "CpuCount":"2" }, "resultToken":"HLQr3BZx/C+DLjwudFcYdXxZFPF2HnGqlg1uHceZ5kDEFeQF2K5LZGofyhn+GE4NP5VgkwANUH3qcdeSjWwODk1ymtmLWLzFV4JForVWYIKdbwwhbDBOgVwF7Ov9c3uVCNz/KpxNElwhTzMkZB95U1vmLs4vUYXuB/Txw4jiCYBYZZnVumhwXWswTLvAhIe5Y451FckObyM3I47AaB+4KtDW3I5q8O+Kx7eSYkqqGTawmJEYjvWXz9CHHMLFtNYyJX54a35mpVdxFSvgeXYDJTStxqb+d9UH/162fZh7T78OHxpQZgl8bcXzZhml****" }
A tabela a seguir lista os principais parâmetros de entrada da função por categoria.
|
Categoria |
Parâmetro |
Descrição |
|
Item de configuração |
configurationItem |
Objeto JSON que representa o estado da configuração do recurso em um momento específico. Inclui ID do recurso, tipo, região, timestamp de criação, tags e configuração completa. |
|
configurationType |
Tipo de entrega do item de configuração. Valores válidos:
|
|
|
Informações da regra |
orderingTimestamp |
Timestamp de início da avaliação. |
|
invokingEvent |
Evento de invocação. |
|
|
accountId |
ID da conta associado ao evento de invocação. |
|
|
messageType |
Tipo de mensagem. Valores válidos:
|
|
|
notificationCreationTimestamp |
Timestamp de acionamento da regra. |
|
|
ruleParameters |
Parâmetros de entrada da regra personalizada, incluindo nomes de parâmetros e valores esperados. |
|
|
resultToken |
Token obrigatório para enviar resultados de avaliação por meio da operação de API PutEvaluations. |