Saat aturan fungsi kustom dipicu, Cloud Config memanggil fungsi terkait di Function Compute untuk mengevaluasi resource Anda dan mengembalikan hasil kepatuhannya. Halaman ini menjelaskan struktur kode fungsi dan parameter inputnya dengan contoh dalam Python.
Aturan fungsi kustom
Aturan fungsi kustom menggunakan fungsi Function Compute untuk mendefinisikan dan menjalankan logika evaluasinya.
Skenario
Jika aturan terkelola (managed rules) dan aturan kondisi tidak memenuhi kebutuhan kepatuhan Anda, buatlah fungsi kustom untuk evaluasi yang lebih kompleks. Skenario tambahan dan contoh kode tersedia di pustaka contoh aturan fungsi kustom.
Mekanisme
Gambar berikut menunjukkan alur eksekusi aturan fungsi kustom.

Langkah-langkah eksekusi:
-
Buat fungsi di Function Compute.
-
Buat aturan kustom berdasarkan fungsi tersebut di Cloud Config. Evaluasi akan dipicu secara otomatis.
CatatanCloud Config secara otomatis memicu evaluasi setelah pembuatan aturan.
-
Cloud Config menggunakan peran terkait layanan (AliyunServiceRoleForConfig) untuk memperoleh izin bagi operasi API GetFunction dan InvokeFunction.
-
Cloud Config memanggil operasi API InvokeFunction untuk menjalankan fungsi dan meneruskan item konfigurasi serta informasi aturan.
-
Fungsi mengevaluasi resource tersebut.
-
Fungsi memanggil operasi API PutEvaluations untuk mengembalikan hasil evaluasi kepatuhan ke Cloud Config.
Cloud Config menyimpan dan menampilkan hasil tersebut di Konsol. Anda kemudian dapat melakukan remediasi terhadap resource yang tidak patuh atau mengirimkan datanya ke layanan Alibaba Cloud lainnya.
Kode fungsi
Aturan merupakan logika evaluasi yang disimpan dalam suatu fungsi. Cloud Config memanggil fungsi ini selama proses auditing. Kode fungsi terdiri dari dua bagian:
-
handlerhandleradalah fungsi entri yang dipanggil saat aturan dipicu. Anda harus menentukan handler saat membuat fungsi di Konsol Function Compute. Handlers.CatatanCloud Config hanya mendukung event handlers.
-
put_evaluationsFungsi ini memanggil operasi API PutEvaluations untuk mengirimkan hasil evaluasi kepatuhan ke Cloud Config.
Kode berikut memberikan contoh dalam 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()
# Jenis kepatuhan suatu resource.
COMPLIANCE_TYPE_COMPLIANT = 'COMPLIANT'
COMPLIANCE_TYPE_NON_COMPLIANT = 'NON_COMPLIANT'
COMPLIANCE_TYPE_NOT_APPLICABLE = 'NOT_APPLICABLE'
# Jenis pengiriman konfigurasi resource.
CONFIGURATION_TYPE_COMMON = 'COMMON'
CONFIGURATION_TYPE_OVERSIZE = 'OVERSIZE'
CONFIGURATION_TYPE_NONE = 'NONE'
# Fungsi entri yang mengoordinasikan dan memproses logika bisnis.
def handler(event, context):
"""
Fungsi handler.
:param event: Event.
:param context: Konteks.
:return: Hasil evaluasi.
"""
# Validasi event. Anda dapat menyalin blok kode ini.
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')
# Konfigurasi resource. Pemicu aturan harus diatur ke Configuration Change. Saat Anda membuat atau menjalankan aturan secara manual, Cloud Config memanggil fungsi untuk mengevaluasi semua resource satu per satu. Jika konfigurasi suatu resource berubah, Cloud Config secara otomatis memanggil fungsi untuk mengevaluasi resource tersebut berdasarkan informasi perubahan.
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')
# Periksa apakah ukuran konfigurasi resource yang dikirimkan lebih besar atau sama dengan 100 KB. Jika ya, Anda harus memanggil operasi GetDiscoveredResource untuk mengambil detail resource.
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"]
# Evaluasi resource. Anda harus mengimplementasikan logika evaluasi sesuai kebutuhan bisnis Anda. Kode berikut hanya sebagai referensi.
compliance_type, annotation = evaluate_configuration_item(
rule_parameters, configuration_item)
# Tetapkan hasil evaluasi. Formatnya harus sesuai contoh berikut.
evaluations = [
{
'accountId': account_id,
'complianceResourceId': resource_id,
'complianceResourceType': resource_type,
'complianceRegionId': region_id,
'orderingTimestamp': ordering_timestamp,
'complianceType': compliance_type,
'annotation': annotation
}
]
# Kirim hasil evaluasi ke Cloud Config. Anda dapat menyalin blok kode ini.
put_evaluations(creds, result_token, evaluations)
return evaluations
# Evaluasi resource berdasarkan informasi aturan dan konfigurasi resource. Anda harus mengimplementasikan logika evaluasi sesuai kebutuhan bisnis Anda. Kode berikut hanya sebagai referensi.
def evaluate_configuration_item(rule_parameters, configuration_item):
"""
Logika evaluasi.
:param rule_parameters: Informasi aturan.
:param configuration_item: Konfigurasi resource.
:return: Jenis kepatuhan.
"""
# Inisialisasi nilai kembali.
compliance_type = COMPLIANCE_TYPE_NON_COMPLIANT
annotation = None
# Dapatkan konfigurasi resource lengkap.
full_configuration = configuration_item['configuration']
if not full_configuration:
annotation = 'Konfigurasi kosong.'
return compliance_type, annotation
# Konversi konfigurasi ke format JSON.
configuration = parse_json(full_configuration)
if not configuration:
annotation = 'Konfigurasi:{} tidak valid.'.format(full_configuration)
return compliance_type, annotation
return compliance_type, annotation
def validate_event(event):
"""
Validasi event.
:param event: Event.
:return: Objek JSON.
"""
if not event:
logger.error('Event kosong.')
evt = parse_json(event)
logger.info('Memuat event: %s .' % evt)
if 'resultToken' not in evt:
logger.error('ResultToken kosong.')
return None
if 'ruleParameters' not in evt:
logger.error('RuleParameters kosong.')
return None
if 'invokingEvent' not in evt:
logger.error('InvokingEvent kosong.')
return None
return evt
def parse_json(content):
"""
Konversi data ke format JSON.
:param content: String JSON.
:return: Objek JSON.
"""
try:
return json.loads(content)
except Exception as e:
logger.error('Gagal mengurai konten:{} ke JSON: {}.'.format(content, e))
return None
# Kirim hasil evaluasi ke Cloud Config. Anda dapat menyalin blok kode ini.
def put_evaluations(creds, result_token, evaluations):
"""
Panggil operasi API untuk mengembalikan dan menyimpan hasil evaluasi.
:param creds: Kredensial fungsi.
:param result_token: Token hasil.
:param evaluations: Hasil evaluasi.
:return: None
"""
# Peran terkait layanan untuk Function Compute harus memiliki kebijakan AliyunConfigFullAccess.
client = AcsClient(creds.access_key_id, creds.access_key_secret, region_id='ap-southeast-1')
# Buat permintaan dan atur parameternya. Nama domain adalah 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 dengan permintaan: {}, respons: {}.'.format(request, response))
except Exception as e:
logger.error('Kesalahan PutEvaluations: %s' % e)
# Ambil detail resource lengkap. Anda dapat menyalin blok kode ini.
def get_discovered_resource(creds, resource_id, resource_type, region_id):
"""
Panggil operasi API untuk mendapatkan detail konfigurasi resource.
:param creds: Kredensial fungsi.
:param resource_id: ID resource.
:param resource_type: Jenis resource.
:param region_id: ID wilayah tempat resource berada.
:return: Detail resource.
"""
# Peran terkait layanan untuk Function Compute harus memiliki kebijakan AliyunConfigFullAccess.
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('Kesalahan GetDiscoveredResource: %s' % e)
Lihat bidang configuration pada item konfigurasi di Konsol Cloud Config untuk mengidentifikasi nama parameter aturan Anda. Lihat Langkah 6 dalam Lihat informasi resource.
Input fungsi
Parameter input fungsi terdiri dari item konfigurasi dan informasi aturan. Konten yang dikirim ke Function Compute bervariasi tergantung pada Trigger aturan.
Untuk mendapatkan parameter input fungsi di Function Compute, lihat log pemanggilan.
-
Jika Trigger aturan diatur hanya ke Periodic, Cloud Config tidak mengirimkan item konfigurasi ke Function Compute.
Saat aturan dijalankan pertama kali, sesuai jadwal, atau secara manual, Cloud Config mengirimkan satu catatan tanpa item konfigurasi. Contoh:
{ "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****" } -
Jika Trigger aturan mencakup Configuration Changes, Cloud Config mengirimkan item konfigurasi ke Function Compute.
Pada jalankan pertama, sesuai jadwal, atau manual, Cloud Config mengirimkan item konfigurasi satu per satu. Saat resource dibuat atau diubah, Cloud Config hanya mengirimkan item konfigurasi yang terpengaruh. Contoh:
{ "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****" }Jika item konfigurasi berukuran 100 KB atau lebih besar, Cloud Config hanya mengirimkan ringkasan resource tanpa bidang
configuration. Contoh:CatatanUntuk mendapatkan konfigurasi resource lengkap, Anda dapat memanggil operasi 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****" }
Tabel berikut mencantumkan parameter input fungsi utama berdasarkan kategori.
|
Kategori |
Parameter |
Deskripsi |
|
Item konfigurasi |
configurationItem |
Objek JSON yang merepresentasikan status konfigurasi resource pada waktu tertentu, termasuk ID resource, jenis, wilayah, timestamp pembuatan, tag, dan konfigurasi lengkap. |
|
configurationType |
Jenis pengiriman item konfigurasi. Nilai yang valid:
|
|
|
Informasi aturan |
orderingTimestamp |
Timestamp saat evaluasi dimulai. |
|
invokingEvent |
Event pemanggilan. |
|
|
accountId |
ID akun yang terkait dengan event pemanggilan. |
|
|
messageType |
Jenis pesan. Nilai yang valid:
|
|
|
notificationCreationTimestamp |
Timestamp saat aturan dipicu. |
|
|
ruleParameters |
Parameter input untuk aturan kustom, termasuk nama parameter dan nilai yang diharapkan. |
|
|
resultToken |
Token yang diperlukan saat mengirimkan hasil evaluasi melalui operasi API PutEvaluations. |