프라이빗 엔드포인트를 통해 Bicep 배포 스크립트를 비공개로 실행
Microsoft.Resources/deploymentScripts
리소스 API 버전 2023-08-01
을 사용하면 ACI(Azure Container Instance) 내에서 배포 스크립트를 비공개로 실행할 수 있습니다.
환경 구성
이 설정에서는 배포 스크립트로 만들어진 ACI가 가상 네트워크 내에서 실행되고 개인 IP 주소를 가져옵니다. 그런 다음 프라이빗 엔드포인트를 통해 새 스토리지 계정이나 기존 스토리지 계정에 대한 연결을 설정합니다. containerSettings/subnetIds
속성은 가상 네트워크의 서브넷에 배포되어야 하는 ACI를 지정합니다.
배포 스크립트를 비공개로 실행하려면 아키텍처 다이어그램에서 볼 수 있는 다음과 같은 인프라가 필요합니다.
- 두 서브넷이 있는 가상 네트워크 만들기:
- 프라이빗 엔드포인트용 서브넷
- ACI에 대한 서브넷, 이 서브넷에는
Microsoft.ContainerInstance/containerGroups
위임이 필요합니다.
- 공용 네트워크에 액세스하지 않고 스토리지 계정을 만듭니다.
- 스토리지 계정의
file
하위 리소스로 구성된 가상 네트워크 내에 프라이빗 엔드포인트를 만듭니다. - 프라이빗 DNS 영역
privatelink.file.core.windows.net
을 만들고 프라이빗 엔드포인트 IP 주소를 A 레코드로 등록합니다. 만들어진 가상 네트워크에 프라이빗 DNS 영역을 연결합니다. - 스토리지 계정에
Storage File Data Privileged Contributor
권한이 있는 사용자가 할당한 관리 ID를 만들고 배포 스크립트 리소스의identity
속성에 지정합니다. ID를 할당하려면 ID를 참조하세요. - ACI 리소스는 배포 스크립트 리소스에 의해 자동으로 만들어집니다.
다음 Bicep 파일은 배포 스크립트를 비공개로 실행하는 데 필요한 인프라를 구성합니다.
@maxLength(10) // Required maximum length, because the storage account has a maximum of 26 characters
param namePrefix string
param location string = resourceGroup().location
param userAssignedIdentityName string = '${namePrefix}Identity'
param storageAccountName string = '${namePrefix}stg${uniqueString(resourceGroup().id)}'
param vnetName string = '${namePrefix}Vnet'
param deploymentScriptName string = '${namePrefix}ds'
var roleNameStorageFileDataPrivilegedContributor = '69566ab7-960f-475b-8e7c-b3118f30c6bd'
var vnetAddressPrefix = '192.168.4.0/23'
var subnetEndpointAddressPrefix = '192.168.4.0/24'
var subnetACIAddressPrefix = '192.168.5.0/24'
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: userAssignedIdentityName
location: location
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
name: storageAccountName
kind: 'StorageV2'
location: location
sku: {
name: 'Standard_LRS'
}
properties: {
publicNetworkAccess: 'Disabled'
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = {
name: storageAccount.name
location: location
properties: {
privateLinkServiceConnections: [
{
name: storageAccount.name
properties: {
privateLinkServiceId: storageAccount.id
groupIds: [
'file'
]
}
}
]
customNetworkInterfaceName: '${storageAccount.name}-nic'
subnet: {
id: virtualNetwork::privateEndpointSubnet.id
}
}
}
resource storageFileDataPrivilegedContributorReference 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: roleNameStorageFileDataPrivilegedContributor
scope: tenant()
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(storageFileDataPrivilegedContributorReference.id, managedIdentity.id, storageAccount.id)
scope: storageAccount
properties: {
principalId: managedIdentity.properties.principalId
roleDefinitionId: storageFileDataPrivilegedContributorReference.id
principalType: 'ServicePrincipal'
}
}
resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.file.core.windows.net'
location: 'global'
resource virtualNetworkLink 'virtualNetworkLinks' = {
name: uniqueString(virtualNetwork.name)
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: {
id: virtualNetwork.id
}
}
}
resource resRecord 'A' = {
name: storageAccount.name
properties: {
ttl: 10
aRecords: [
{
ipv4Address: first(first(privateEndpoint.properties.customDnsConfigs)!.ipAddresses)
}
]
}
}
}
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = {
name: vnetName
location: location
properties:{
addressSpace: {
addressPrefixes: [
vnetAddressPrefix
]
}
}
resource privateEndpointSubnet 'subnets' = {
name: 'PrivateEndpointSubnet'
properties: {
addressPrefixes: [
subnetEndpointAddressPrefix
]
}
}
resource containerInstanceSubnet 'subnets' = {
name: 'ContainerInstanceSubnet'
properties: {
addressPrefix: subnetACIAddressPrefix
delegations: [
{
name: 'containerDelegation'
properties: {
serviceName: 'Microsoft.ContainerInstance/containerGroups'
}
}
]
}
}
}
resource privateDeploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
name: deploymentScriptName
dependsOn: [
privateEndpoint
privateDnsZone::virtualNetworkLink
]
location: location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}' : {}
}
}
properties: {
storageAccountSettings: {
storageAccountName: storageAccount.name
}
containerSettings: {
subnetIds: [
{
id: virtualNetwork::containerInstanceSubnet.id
}
]
}
azPowerShellVersion: '9.0'
retentionInterval: 'P1D'
scriptContent: 'Write-Host "Hello World!"'
}
}
ACI는 Microsoft Container Registry에서 컨테이너 이미지를 다운로드합니다. 방화벽을 사용하는 경우 URL mcr.microsoft.com을 허용 목록에 추가하여 이미지를 다운로드합니다. 컨테이너 이미지를 다운로드하지 못하면 ACI가 waiting
상태로 전환되고 결국 시간 제한 오류가 발생합니다.
다음 단계
이 문서에서는 프라이빗 엔드포인트에서 배포 스크립트를 실행하는 방법을 알아보았습니다. 자세히 알아보려면 다음을 수행합니다.