Bicep 모듈

Bicep을 사용하면 모듈로 배포를 구성할 수 있습니다. 모듈은 다른 Bicep 파일에서 배포되는 Bicep 파일(또는 ARM JSON 템플릿)입니다. 모듈을 사용하면 배포의 복잡한 세부 정보를 캡슐화하여 Bicep 파일의 가독성을 높일 수 있습니다. 다른 배포에 모듈을 쉽게 다시 사용할 수도 있습니다.

조직의 다른 사용자와 모듈을 공유하려면 템플릿 사양, 공용 레지스트리 또는 프라이빗 레지스트리를 만듭니다. 레지스트리의 템플릿 사양 및 모듈은 올바른 권한이 있는 사용자만 사용할 수 있습니다.

모듈 레지스트리와 템플릿 사양 간의 선택은 대부분 기본 설정의 문제입니다. 두 가지 중 선택할 때 고려해야 할 몇 가지가 있습니다.

  • 모듈 레지스트리는 Bicep에서만 지원됩니다. 아직 Bicep를 사용하지 않는 경우 템플릿 사양을 사용합니다.
  • Bicep 모듈 레지스트리의 콘텐츠는 다른 Bicep 파일에서만 배포할 수 있습니다. 템플릿 사양은 API, Azure PowerShell, Azure CLI 및 Azure Portal에서 직접 배포할 수 있습니다. UiFormDefinition을 사용하여 포털 배포 환경을 사용자 지정할 수도 있습니다.
  • Bicep에는 loadTextContentloadFileAsBase64 함수를 사용하여 다른 프로젝트 아티팩트(Bicep 및 ARM이 아닌 템플릿 파일 포함. 예: PowerShell 스크립트, CLI 스크립트 및 기타 이진 파일 포함)를 포함하는 데 몇 가지 제한된 기능이 있습니다. 템플릿 사양은 이러한 아티팩트를 패키지할 수 없습니다.

Bicep 모듈은 중첩된 템플릿이 있는 단일 Azure Resource Manager 템플릿으로 변환됩니다. Bicep이 구성 파일을 확인하는 방법 및 Bicep이 사용자 정의 구성 파일을 기본 구성 파일과 병합하는 방법에 대한 자세한 내용은 구성 파일 확인 프로세스구성 파일 병합 프로세스를 참조하세요.

학습 리소스

단계별 지침을 통해 모듈에 대해 알아보려면 모듈을 사용하여 작성 가능한 Bicep 파일 만들기를 참조하세요.

정의 구문

모듈을 정의하는 기본 구문은 다음과 같습니다.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

따라서 간단한 실제 예제는 다음과 같습니다.

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

ARM JSON 템플릿을 모듈로 사용할 수도 있습니다.

module stgModule '../storageAccount.json' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

기호 이름을 사용하여 Bicep 파일의 다른 부분에서 모듈을 참조합니다. 예를 들어 기호 이름을 사용하여 모듈에서 출력을 가져올 수 있습니다. 기호 이름에는 a-z, A-Z, 0-9 및 밑줄(_)이 포함될 수 있습니다. 이름은 숫자로 시작할 수 없습니다. 모듈은 매개 변수, 변수 또는 리소스와 동일한 이름을 가질 수 없습니다.

경로는 로컬 파일 또는 레지스트리의 파일일 수 있습니다. 로컬 파일은 Bicep 파일 또는 ARM JSON 템플릿일 수 있습니다. 자세한 내용은 모듈 경로를 참조하세요.

이름 속성은 필수입니다. 생성된 템플릿에서 중첩된 배포 리소스의 이름이 됩니다.

정적 이름을 가진 모듈이 동일한 범위에 동시에 배포되는 경우 한 배포가 다른 배포의 출력을 방해할 가능성이 있습니다. 예를 들어 두 개의 Bicep 파일이 동일한 정적 이름(examplemodule)을 가진 동일한 모듈을 사용하고 동일한 리소스 그룹을 대상으로 하는 경우 하나의 배포에서 잘못된 출력을 표시할 수 있습니다. 동일한 범위에 대한 동시 배포가 우려되는 경우 모듈에 고유한 이름을 지정합니다.

다음 예제에서는 배포 이름을 모듈 이름에 연결합니다. 배포에 고유한 이름을 제공하는 경우 모듈 이름도 고유합니다.

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

기본 파일의 범위와 다른 범위를 지정해야 하는 경우 범위 속성을 추가합니다. 자세한 내용은 모듈 범위 설정을 참조하세요.

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

모듈을 조건부로 배포하려면 if 식을 추가합니다. 사용은 리소스를 조건부로 배포하는 것과 유사합니다.

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

모듈의 인스턴스를 두 개 이상 배포하려면 for 식을 추가합니다. batchSize 데코레이터를 사용하여 인스턴스를 직렬로 또는 병렬로 배포할지 여부를 지정할 수 있습니다. 자세한 내용은 Bicep의 반복 루프를 참조하세요.

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

리소스와 마찬가지로 모듈은 다른 모듈이나 리소스에 의존하지 않는 한 병렬로 배포됩니다. 일반적으로 종속성은 암시적으로 결정되므로 설정할 필요가 없습니다. 명시적 종속성을 설정해야 하는 경우 모듈 정의에 dependsOn를 추가할 수 있습니다. 종속성에 대해 알아보려면 리소스 종속성을 참조하세요.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

모듈 경로

모듈의 파일은 로컬 파일 또는 외부 파일일 수 있습니다. 외부 파일은 템플릿 사양 또는 Bicep 모듈 레지스트리에 있을 수 있습니다. 이러한 모든 옵션은 아래에 나와 있습니다.

로컬 파일

모듈이 로컬 파일인 경우 해당 파일에 대한 상대 경로를 제공합니다. Bicep의 모든 경로는 플랫폼 간에 일관된 컴파일을 보장하기 위해 슬래시(/) 디렉터리 구분 기호를 사용하여 지정해야 합니다. Windows 백슬래시(\) 문자는 지원되지 않습니다. 경로에는 공백을 포함할 수 있습니다.

예를 들어 기본 파일에서 디렉터리의 한 수준 위에 있는 파일을 배포하려면 다음을 사용합니다.

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

레지스트리의 파일

공용 모듈 레지스트리

공용 모듈 레지스트리는 MCR(Microsoft 컨테이너 레지스트리)에서 호스팅됩니다. 소스 코드와 모듈은 GitHub에 저장됩니다. 사용 가능한 모듈 및 해당 버전을 보려면 Bicep 레지스트리 모듈 인덱스를 참조하세요.

The screenshot of public module registry.

사용 가능한 버전을 보려면 버전을 선택합니다. 소스 코드를 선택하여 모듈 소스 코드를 보고 추가 정보 파일을 열 수도 있습니다.

현재 게시된 모듈은 몇 가지뿐입니다. 추가 모듈이 제공될 예정입니다. 레지스트리에 기여하려면 기여 가이드를 참조하세요.

공용 레지스트리 모듈에 연결하려면 다음 구문을 사용하여 모듈 경로를 지정합니다.

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public은 공용 모듈 레지스트리의 별칭입니다. 이 별칭은 구성에 미리 정의되어 있습니다.
  • 파일 경로에는 / 문자로 구분할 수 있는 세그먼트가 포함될 수 있습니다.
  • 태그는 모듈의 버전을 지정하는 데 사용됩니다.

예시:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

참고 항목

br/public은 공용 레지스트리의 별칭입니다. 다음으로 작성할 수도 있습니다.

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

개인 모듈 레지스트리

레지스트리에 모듈을 게시한 경우 해당 모듈에 연결할 수 있습니다. Azure 컨테이너 레지스트리의 이름과 모듈 경로를 제공합니다. 다음 구문을 사용하여 모듈 경로를 지정합니다.

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br은 Bicep 레지스트리의 스키마 이름입니다.
  • 파일 경로는 Azure Container Registry에서 repository라고 합니다. 파일 경로에는 / 문자로 구분된 세그먼트가 포함되어 있습니다.
  • 태그는 모듈의 버전을 지정하는 데 사용됩니다.

예시:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

레지스트리에서 모듈을 참조할 때 Visual Studio Code의 Bicep 확장은 자동으로 bicep 복원을 호출하여 외부 모듈을 로컬 캐시에 복사합니다. 외부 모듈을 복원하는 데 몇 분 정도가 소요됩니다. 모듈에 대한 intellisense가 즉시 작동하지 않으면 복원이 완료될 때까지 기다립니다.

레지스트리에 있는 모듈의 전체 경로는 길 수 있습니다. 모듈을 사용할 때마다 전체 경로를 제공하는 대신 bicepconfig.json 파일에서 별칭을 구성할 수 있습니다. 별칭을 통해 모듈을 보다 쉽게 참조할 수 있습니다. 예를 들어 별칭을 사용하여 다음과 같이 경로를 단축할 수 있습니다.

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

공용 모듈 레지스트리에 대한 별칭이 미리 정의되었습니다.

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

bicepconfig.json 파일에서 공용 별칭을 재정의할 수 있습니다.

템플릿 사양의 파일

템플릿 사양을 생성한 후 모듈에서 해당 템플릿 사양에 연결할 수 있습니다. 템플릿 사양을 다음 형식으로 지정합니다.

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

그러나 템플릿 사양을 포함하는 리소스 그룹에 대한 별칭을 생성하여 Bicep 파일을 단순화할 수 있습니다. 별칭을 사용하는 경우 구문은 다음이 됩니다.

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

다음 모듈에서는 템플릿 사양을 배포하여 스토리지 계정을 만듭니다. 템플릿 사양에 대한 구독 및 리소스 그룹은 ContosoSpecs라는 별칭에 정의되어 있습니다.

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

매개 변수

모듈 정의에서 제공하는 매개 변수는 Bicep 파일의 매개 변수와 일치합니다.

다음 Bicep 예제에는 storagePrefix, storageSKU 및 위치의 세 가지 매개 변수가 있습니다. storageSKU 매개 변수에는 기본값이 있으므로 배포하는 동안 해당 매개 변수에 대한 값을 제공할 필요가 없습니다.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

위의 예제를 모듈로 사용하려면 해당 매개 변수에 대한 값을 제공합니다.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

모듈 범위 설정

모듈을 선언할 때 포함된 Bicep 파일의 범위와 다른 모듈의 범위를 설정할 수 있습니다. scope 속성을 사용하여 모듈의 범위를 설정합니다. Scope 속성을 제공하지 않으면 모듈이 부모의 대상 범위에 배포됩니다.

다음 Bicep 파일은 해당 리소스 그룹에 리소스 그룹 및 스토리지 계정을 만듭니다. 파일은 구독에 배포되지만 모듈은 새 리소스 그룹에 범위가 지정됩니다.

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

다음 예제에서는 스토리지 계정을 두 개의 서로 다른 리소스 그룹에 배포합니다. 이러한 두 리소스 그룹은 모두 이미 있어야 합니다.

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

범위 속성을 유효한 범위 개체로 설정해야 합니다. Bicep 파일이 리소스 그룹, 구독 또는 관리 그룹을 배포하는 경우 모듈의 범위를 해당 리소스의 기호 이름으로 설정할 수 있습니다. 또는 범위 함수를 사용하여 유효한 범위를 얻을 수 있습니다.

해당 함수는 다음과 같습니다.

다음 예제에서는 managementGroup 함수를 사용하여 범위를 설정합니다.

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

출력

모듈에서 값을 가져와 기본 Bicep 파일에서 사용할 수 있습니다. 모듈에서 출력 값을 가져오려면 모듈 개체의 outputs 속성을 사용합니다.

첫 번째 예제에서는 스토리지 계정을 만들고 기본 엔드포인트를 반환합니다.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

모듈로 사용하면 해당 출력 값을 가져올 수 있습니다.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

다음 단계