Bagikan melalui


Menggunakan skrip penyebaran di Bicep

Dengan menggunakan sumber daya deploymentScripts , Anda dapat menjalankan skrip dalam penyebaran Bicep dan meninjau hasil eksekusi. Anda dapat menggunakan skrip ini untuk melakukan langkah-langkah kustom seperti:

  • Menambahkan pengguna ke direktori.
  • Melakukan operasi sarana data; misalnya, salin blob atau seed database.
  • Mencari dan memvalidasi kunci lisensi.
  • Membuat sertifikat yang ditandatangani sendiri.
  • Buat objek di ID Microsoft Entra.
  • Cari blok alamat IP dari sistem kustom.

Manfaat skrip penyebaran meliputi:

  • Mereka mudah dikodekan, digunakan, dan di-debug. Anda dapat mengembangkan skrip penyebaran di lingkungan pengembangan favorit Anda. Skrip tersebut dapat disematkan dalam file Bicep atau dalam file skrip eksternal.
  • Anda dapat menentukan bahasa dan platform skrip. Saat ini, skrip penyebaran Azure PowerShell dan Azure CLI di lingkungan Linux didukung.
  • Anda dapat mengizinkan meneruskan argumen baris perintah ke skrip.
  • Anda dapat menentukan output skrip dan meneruskannya kembali ke penyebaran.

Sumber daya skrip penyebaran hanya tersedia di wilayah tempat Azure Container Instances tersedia. Untuk informasi selengkapnya, lihat Ketersediaan sumber daya untuk Azure Container Instances di wilayah Azure.

Peringatan

Layanan skrip penyebaran memerlukan dua sumber daya tambahan untuk menjalankan dan memecahkan masalah skrip: akun penyimpanan dan instans kontainer. Umumnya, layanan membersihkan sumber daya ini setelah skrip penyebaran selesai. Anda dikenakan biaya untuk sumber daya ini hingga dihapus.

Untuk informasi harga, lihat Harga Container Instances dan harga Azure Storage. Untuk mempelajari lebih lanjut, lihat Membersihkan sumber daya skrip penerapan.

Sumber daya pelatihan

Jika Anda lebih suka mempelajari tentang skrip penyebaran melalui panduan langkah demi langkah, lihat Memperluas templat Bicep dan ARM dengan menggunakan skrip penyebaran.

Mengonfigurasi izin minimum

Untuk versi 2020-10-01 API skrip penyebaran atau yang lebih baru, dua prinsipal terlibat dalam eksekusi skrip penyebaran:

  • Prinsip penyebaran: Prinsipal ini digunakan untuk menyebarkan file Bicep. Ini membuat sumber daya yang mendasari yang diperlukan agar sumber daya skrip penyebaran berjalan—akun penyimpanan dan instans kontainer Azure. Untuk mengonfigurasi izin hak istimewa paling sedikit, tetapkan peran kustom dengan properti berikut ke prinsip penyebaran:

    {
      "roleName": "deployment-script-minimum-privilege-for-deployment-principal",
      "description": "Configure least privilege for the deployment principal in deployment script",
      "type": "customRole",
      "IsCustom": true,
      "permissions": [
        {
          "actions": [
            "Microsoft.Storage/storageAccounts/*",
            "Microsoft.ContainerInstance/containerGroups/*",
            "Microsoft.Resources/deployments/*",
            "Microsoft.Resources/deploymentScripts/*"
          ],
        }
      ],
      "assignableScopes": [
        "[subscription().id]"
      ]
    }
    

    Jika penyedia sumber daya Azure Storage dan Azure Container Instances tidak terdaftar, pastikan untuk menambahkan Microsoft.Storage/register/action dan Microsoft.ContainerInstance/register/action.

  • Prinsipal skrip penyebaran: Prinsipal ini diperlukan hanya jika skrip penyebaran perlu mengautentikasi ke Azure dan memanggil Azure CLI atau PowerShell. Ada dua cara untuk menentukan prinsip skrip penyebaran:

    • Tentukan identitas terkelola yang ditetapkan pengguna di identity properti . (Lihat sintaks sumber daya skrip penyebaran.) Saat Anda menentukan identitas terkelola yang ditetapkan pengguna, layanan skrip memanggil Connect-AzAccount -Identity sebelum memanggil skrip penyebaran. Identitas terkelola harus memiliki akses yang diperlukan untuk menyelesaikan operasi dalam skrip. Saat ini, hanya identitas terkelola yang ditetapkan pengguna yang didukung untuk properti .identity Untuk masuk dengan identitas yang berbeda, gunakan metode kedua dalam daftar ini.
    • Teruskan kredensial perwakilan layanan sebagai variabel lingkungan yang aman, lalu panggil Connect-AzAccount atau az login dalam skrip penyebaran.

    Jika Anda menggunakan identitas terkelola, prinsip penyebaran memerlukan peran Operator Identitas Terkelola bawaan yang ditetapkan ke sumber daya identitas terkelola.

Saat ini, tidak ada peran bawaan yang disesuaikan untuk mengonfigurasi izin skrip penyebaran.

Membuat skrip penyebaran

Contoh berikut menunjukkan file Bicep sederhana dengan sumber daya skrip penyebaran. Skrip mengambil satu parameter string dan membuat string lain.

param name string = 'John Dole'
param location string = resourceGroup().location

resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'inlineCLI'
  location: location
  kind: 'AzureCLI'
  properties: {
    azCliVersion: '2.52.0'
    arguments: name
    scriptContent: 'echo "The argument is ${name}."; jq -n -c --arg st "Hello ${name}" \'{"text": $st}\' > $AZ_SCRIPTS_OUTPUT_PATH'
    retentionInterval: 'PT1H'
  }
}

output text string = deploymentScript.properties.outputs.text

Untuk informasi selengkapnya tentang membuat sumber daya skrip penyebaran, lihat Membuat skrip penyebaran. Untuk pembuatan skrip untuk sumber daya skrip penyebaran, kami menyarankan Anda untuk membuat lingkungan pengembangan skrip khusus, seperti instans kontainer Azure atau gambar Docker. Setelah mengembangkan dan menguji skrip secara menyeluruh, Anda dapat mengintegrasikan atau memanggil file skrip dari sumber daya skrip penyebaran. Untuk informasi selengkapnya, lihat Mengonfigurasi lingkungan pengembangan skrip.

Simpan skrip dalam file inlineScript.bicep , lalu sebarkan sumber daya dengan menggunakan skrip berikut:

$resourceGroupName = Read-Host -Prompt "Enter the name of the resource group to be created"
$location = Read-Host -Prompt "Enter the location (i.e. centralus)"

New-AzResourceGroup -Name $resourceGroupName -Location $location

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile "inlineScript.bicep"

Write-Host "Press [ENTER] to continue ..."

Gunakan identitas terkelola

Contoh berikut menunjukkan cara menggunakan identitas terkelola untuk berinteraksi dengan Azure dari dalam skrip penyebaran.

@description('The location of the resources.')
param location string = resourceGroup().location

@description('The storage account to list blobs from.')
param storageAccountData {
  name: string
  container: string
}

@description('The role id of Storage Blob Data Reader.')
var storageBlobDataReaderRoleId = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'

@description('The storage account to read blobs from.')
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = {
  name: storageAccountData.name
}

@description('The Storage Blob Data Reader Role definition from [Built In Roles](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles).')
resource storageBlobDataReaderRoleDef 'Microsoft.Authorization/roleDefinitions@2022-05-01-preview' existing = {
  scope: subscription()
  name: storageBlobDataReaderRoleId
}

@description('The user identity for the deployment script.')
resource scriptIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview' = {
  name: 'script-identity'
  location: location
}

@description('Assign permission for the deployment scripts user identity access to the read blobs from the storage account.')
resource dataReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: storageAccount
  name: guid(storageBlobDataReaderRoleDef.id, scriptIdentity.id, storageAccount.id)
  properties: {
    principalType: 'ServicePrincipal'
    principalId: scriptIdentity.properties.principalId
    roleDefinitionId: storageBlobDataReaderRoleDef.id
  }
}

@description('The deployment script.')
resource script 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'script'
  location: location
  kind: 'AzureCLI'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${scriptIdentity.id}': {}
    }
  }
  properties: {
    azCliVersion: '2.59.0'
    retentionInterval: 'PT1H'
    arguments: '${storageAccount.properties.primaryEndpoints.blob} ${storageAccountData.container}'
    scriptContent: '''
      #!/bin/bash
      set -e
      az storage blob list --auth-mode login --blob-endpoint $1 --container-name $2
    '''
  }
}

Memantau dan memecahkan masalah skrip penyebaran

Saat Anda menyebarkan sumber daya skrip penyebaran, Anda memerlukan akun penyimpanan untuk menyimpan skrip pengguna, hasil eksekusi, dan stdout file. Anda dapat menentukan akun penyimpanan Anda sendiri. Untuk informasi selengkapnya, lihat Menggunakan akun penyimpanan yang sudah ada.

Alternatif untuk menentukan akun penyimpanan Anda sendiri melibatkan pengaturan cleanupPreference ke OnExpiration. Anda kemudian mengonfigurasi retentionInterval durasi yang memungkinkan cukup waktu untuk meninjau output sebelum akun penyimpanan dihapus. Untuk informasi selengkapnya, lihat Membersihkan sumber daya skrip penyebaran.

cleanupPreference Tambahkan properti ke file Bicep sebelumnya, dan atur nilainya ke OnExpiration. Nilai defaultnya adalah Always. Selain itu, atur rentalInterval ke PT1H (satu jam) atau lebih pendek.

param name string = 'John Dole'
param location string = resourceGroup().location

resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'inlineCLI'
  location: location
  kind: 'AzureCLI'
  properties: {
    azCliVersion: '2.52.0'
    arguments: name
    scriptContent: 'echo "The argument is ${name}."; jq -n -c --arg st "Hello ${name}" \'{"text": $st}\' > $AZ_SCRIPTS_OUTPUT_PATH'
    cleanupPreference: 'OnExpiration'
    retentionInterval: 'PT1H'
  }
}

output text string = deploymentScript.properties.outputs.text

Setelah Anda berhasil menyebarkan file Bicep, gunakan portal Azure, Azure CLI, Azure PowerShell, atau REST API untuk memeriksa hasilnya.

Portal Azure

Setelah Anda menerapkan sumber daya skrip penyebaran, sumber daya tercantum di bawah grup sumber daya di portal Microsoft Azure. Halaman Gambaran Umum mencantumkan dua sumber daya pendukung selain sumber daya skrip penyebaran. Sumber daya pendukung akan dihapus setelah interval retensi kedaluwarsa.

Perhatikan bahwa kedua sumber daya pendukung memiliki akhiran azscript atas namanya karena sumber daya ini dibuat secara otomatis. Cara lain untuk mengidentifikasi sumber daya pendukung adalah dengan menggunakan tag.

Cuplikan layar grup sumber daya skrip penyebaran.

Pilih sumber daya skrip penyebaran dari daftar. Halaman Gambaran Umum sumber daya skrip penyebaran menampilkan informasi penting tentang sumber daya, seperti Status provisi dan dua sumber daya pendukung (Akun penyimpanan dan instans Kontainer). Area Log memperlihatkan teks cetak dari skrip.

Cuplikan layar informasi tentang sumber daya skrip penyebaran.

Pilih Output untuk menampilkan output skrip.

Cuplikan layar output skrip penyebaran.

Kembali ke grup sumber daya, pilih akun penyimpanan, pilih Berbagi file, lalu pilih berbagi file dengan azscript yang ditambahkan ke nama berbagi. Dua folder muncul dalam daftar: azscriptinput dan azscriptoutput. Folder output berisi file executionresult.json dan file output skrip. File executionresult.json berisi pesan kesalahan eksekusi skrip. File output dibuat hanya ketika Anda berhasil menjalankan skrip.

Cuplikan layar konten folder output skrip penyebaran.

Folder input berisi file skrip sistem dan file skrip penyebaran pengguna. Anda dapat mengganti file skrip penyebaran pengguna dengan yang direvisi dan menjalankan ulang skrip penyebaran dari instans kontainer Azure.

Azure CLI

Anda dapat menggunakan Azure CLI untuk mengelola skrip penyebaran di cakupan grup langganan atau sumber daya:

Output perintah daftar mirip dengan contoh ini:

{
  "arguments": "John Dole",
  "azCliVersion": "2.52.0",
  "cleanupPreference": "OnExpiration",
  "containerSettings": {
    "containerGroupName": null
  },
  "environmentVariables": null,
  "forceUpdateTag": null,
  "id": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlineCLI",
  "identity": null,
  "kind": "AzureCLI",
  "location": "centralus",
  "name": "inlineCLI",
  "outputs": {
    "text": "Hello John Dole"
  },
  "primaryScriptUri": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "dsDemo",
  "retentionInterval": "1:00:00",
  "scriptContent": "echo \"The argument is John Dole.\"; jq -n -c --arg st \"Hello John Dole\" '{\"text\": $st}' > $AZ_SCRIPTS_OUTPUT_PATH",
  "status": {
    "containerInstanceId": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/jgczqtxom5oreazscripts",
    "endTime": "2023-12-11T20:20:12.149468+00:00",
    "error": null,
    "expirationTime": "2023-12-11T21:20:12.149468+00:00",
    "startTime": "2023-12-11T20:18:26.674492+00:00",
    "storageAccountId": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/jgczqtxom5oreazscripts"
  },
  "storageAccountSettings": null,
  "supportingScriptUris": null,
  "systemData": {
    "createdAt": "2023-12-11T19:45:32.239063+00:00",
    "createdBy": "johndole@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2023-12-11T20:18:26.183565+00:00",
    "lastModifiedBy": "johndole@contoso.com",
    "lastModifiedByType": "User"
  },
  "tags": null,
  "timeout": "1 day, 0:00:00",
  "type": "Microsoft.Resources/deploymentScripts"
}

Azure PowerShell

Anda dapat menggunakan Azure PowerShell untuk mengelola skrip penyebaran di cakupan grup langganan atau sumber daya:

Outputnya Get-AzDeploymentScript mirip dengan contoh ini:

Name                : inlinePS
Id                  : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlinePS
ResourceGroupName   : dsDemo
Location            : centralus
SubscriptionId      : 01234567-89AB-CDEF-0123-456789ABCDEF
ProvisioningState   : Succeeded
Identity            :
ScriptKind          : AzurePowerShell
AzPowerShellVersion : 10.0
StartTime           : 12/11/2023 9:45:50 PM
EndTime             : 12/11/2023 9:46:59 PM
ExpirationDate      : 12/11/2023 10:46:59 PM
CleanupPreference   : OnExpiration
StorageAccountId    : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/ee5o4rmoo6ilmazscripts
ContainerInstanceId : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/ee5o4rmoo6ilmazscripts
Outputs             :
                      Key                 Value
                      ==================  ==================
                      text                Hello John Dole.

RetentionInterval   : PT1H
Timeout             : P1D

REST API

Anda dapat menggunakan REST API untuk mendapatkan informasi tentang sumber daya skrip penyebaran di tingkat grup sumber daya dan tingkat langganan:

/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/microsoft.resources/deploymentScripts/<DeploymentScriptResourceName>?api-version=2020-10-01
/subscriptions/<SubscriptionID>/providers/microsoft.resources/deploymentScripts?api-version=2020-10-01

Contoh berikut menggunakan ARMClient. ARMClient bukan alat Microsoft yang didukung.

armclient login
armclient get /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/myrg/providers/microsoft.resources/deploymentScripts/myDeployementScript?api-version=2020-10-01

Outputnya mirip dengan contoh ini:

{
  "kind": "AzureCLI",
  "identity": null,
  "location": "centralus",
  "systemData": {
    "createdAt": "2023-12-11T19:45:32.239063+00:00",
    "createdBy": "johndole@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2023-12-11T20:18:26.183565+00:00",
    "lastModifiedBy": "johndole@contoso.com",
    "lastModifiedByType": "User"
  },
  "properties": {
    "provisioningState": "Succeeded",
    "azCliVersion": "2.52.0",
    "scriptContent": "echo \"The argument is John Dole.\"; jq -n -c --arg st \"Hello John Dole\" '{\"text\": $st}' > $AZ_SCRIPTS_OUTPUT_PATH",
    "arguments": "John Dole",
    "retentionInterval": "1:00:00",
    "timeout": "1 day, 0:00:00",
    "containerSettings": {
      "containerGroupName": null
    },
    "status": {
      "containerInstanceId": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/jgczqtxom5oreazscripts",
      "endTime": "2023-12-11T20:20:12.149468+00:00",
      "error": null,
      "expirationTime": "2023-12-11T21:20:12.149468+00:00",
      "startTime": "2023-12-11T20:18:26.674492+00:00",
      "storageAccountId": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/jgczqtxom5oreazscripts"
    },
    "outputs": {
      "text": "Hello John Dole"
    },
    "cleanupPreference": "OnSuccess"
  },
  "id": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlineCLI",
  "type": "Microsoft.Resources/deploymentScripts",
  "name": "inlineCLI",
}

REST API berikut mengembalikan log:

/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/microsoft.resources/deploymentScripts/<DeploymentScriptResourceName>/logs?api-version=2020-10-01

Ini hanya berfungsi sebelum sumber daya skrip penyebaran dihapus.


Kode kesalahan skrip penyebaran

Tabel berikut mencantumkan kode kesalahan untuk skrip penyebaran:

Kode kesalahan Deskripsi
DeploymentScriptInvalidOperation Definisi sumber daya skrip penyebaran dalam file Bicep berisi nama properti yang tidak valid.
DeploymentScriptResourceConflict Anda tidak dapat menghapus sumber daya skrip penyebaran jika berada dalam status nonterminal dan eksekusi belum melebihi satu jam. Atau Anda tidak dapat menjalankan ulang skrip penyebaran yang sama dengan pengidentifikasi sumber daya yang sama (langganan yang sama, nama grup sumber daya, dan nama sumber daya) tetapi konten isi skrip yang berbeda secara bersamaan.
DeploymentScriptOperationFailed Operasi skrip penyebaran gagal secara internal. Hubungi dukungan Microsoft.
DeploymentScriptStorageAccountAccessKeyNotSpecified Kunci akses tidak ditentukan untuk akun penyimpanan yang ada.
DeploymentScriptContainerGroupContainsInvalidContainers Grup kontainer yang dibuat layanan skrip penyebaran dimodifikasi secara eksternal, dan kontainer yang tidak valid ditambahkan.
DeploymentScriptContainerGroupInNonterminalState Dua atau lebih sumber daya skrip penyebaran menggunakan nama instans kontainer Azure yang sama dalam grup sumber daya yang sama, dan salah satunya belum menyelesaikan eksekusinya.
DeploymentScriptExistingStorageNotInSameSubscriptionAsDeploymentScript Penyimpanan yang ada yang disediakan dalam penyebaran tidak ditemukan di langganan tempat skrip sedang disebarkan.
DeploymentScriptStorageAccountInvalidKind Akun penyimpanan yang ada dari BlobBlobStorage jenis atau BlobStorage tidak mendukung berbagi file dan tidak dapat digunakan.
DeploymentScriptStorageAccountInvalidKindAndSku Akun penyimpanan yang ada tidak mendukung file share. Untuk daftar jenis akun penyimpanan yang didukung, lihat Menggunakan akun penyimpanan yang sudah ada.
DeploymentScriptStorageAccountNotFound Akun penyimpanan tidak ada, atau proses atau alat eksternal menghapusnya.
DeploymentScriptStorageAccountWithServiceEndpointEnabled Akun penyimpanan yang ditentukan memiliki titik akhir layanan. Akun penyimpanan dengan titik akhir layanan tidak didukung.
DeploymentScriptStorageAccountInvalidAccessKey Kunci akses yang tidak valid ditentukan untuk akun penyimpanan yang ada.
DeploymentScriptStorageAccountInvalidAccessKeyFormat Kunci akun penyimpanan memiliki format yang tidak valid. Lihat Mengelola kunci akses akun penyimpanan.
DeploymentScriptExceededMaxAllowedTime Waktu eksekusi skrip penyebaran melebihi nilai batas waktu yang ditentukan dalam definisi sumber daya skrip penyebaran.
DeploymentScriptInvalidOutputs Output skrip penyebaran bukan objek JSON yang valid.
DeploymentScriptContainerInstancesServiceLoginFailure Identitas terkelola yang ditetapkan pengguna tidak dapat masuk setelah 10 upaya dengan interval satu menit.
DeploymentScriptContainerGroupNotFound Alat atau proses eksternal menghapus grup kontainer yang dibuat layanan skrip penyebaran.
DeploymentScriptDownloadFailure Pengunduhan skrip pendukung gagal. Lihat Menggunakan skrip pendukung.
DeploymentScriptError Skrip pengguna menghasilkan kesalahan.
DeploymentScriptBootstrapScriptExecutionFailed Skrip bootstrap menghasilkan kesalahan. Skrip bootstrap adalah skrip sistem yang mengatur eksekusi skrip penyebaran.
DeploymentScriptExecutionFailed Terjadi kesalahan yang tidak diketahui selama eksekusi skrip penyebaran.
DeploymentScriptContainerInstancesServiceUnavailable Selama pembuatan instans kontainer, layanan Azure Container Instances melemparkan kesalahan "layanan tidak tersedia".
DeploymentScriptContainerGroupInNonterminalState Selama pembuatan instans kontainer, skrip penyebaran lain menggunakan nama instans kontainer yang sama dalam cakupan yang sama (langganan yang sama, nama grup sumber daya, dan nama sumber daya).
DeploymentScriptContainerGroupNameInvalid Nama instans kontainer yang ditentukan tidak memenuhi persyaratan Azure Container Instances. Lihat Memecahkan masalah umum di Azure Container Instances.

Mengakses jaringan virtual privat

Anda dapat menjalankan skrip penyebaran di jaringan privat dengan beberapa konfigurasi tambahan. Untuk informasi selengkapnya, lihat Mengakses jaringan virtual privat menggunakan titik akhir layanan atau Menjalankan skrip penyebaran Bicep secara privat melalui titik akhir privat.

Langkah berikutnya

Dalam artikel ini, Anda telah mempelajari cara menggunakan skrip penyebaran. Untuk mempelajari selengkapnya, lihat: