[Open Source Project] : Bicep

문승현·2022년 7월 31일
0

BeDev_2

목록 보기
7/8
post-thumbnail

오픈 소스 프로젝트에서 사용할 Azure 리소스 관리를 위해 Bicep을 학습하였다.
지금까지의 클라우드 환경 작업은 AWS를 이용해왔었기에 Azure는 무척 낯설었다.
그래도 Bicep을 공부하다보니 익숙해지면 굉장히 편리할 것 같다는 생각이 들었다.

Bicep은 Azure 리소스를 선언적으로 배포하기 위한 DSL(Domain Specific Language)로,
사용자는 Bicep 언어로 템플릿에 리소스를 구성하고 배포 방법 등을 정의할 수 있다.
그리고 이러한 템플릿을 작성하여 Azure Resource Manager에 제출하면
Azure Resource Manager가 사용자를 대신하여 리소스 배포 작업을 진행한다.

Azure 리소스 관리 파일로 ARM 템플릿(Azure Resource Manager Template)이 존재한다.
Bicep이 출시 전에는 이 ARM 템플릿을 이용하여 리소스를 정의하고 배포해야 했다.
그런데 이는 특수한 JSON 형식으로 작성해야했기에 구문이 복잡하고 작업 난이도가 높았다.

Bicep은 ARM 템플릿의 이러한 문제를 해결한다.
Bicep 역시 내부적으로는 ARM 템플릿과 유사하게 JSON 형식으로 작동하지만,
훨씬 간단한 언어로 템플릿을 작성하고 빌드하면 자동으로 JSON 형식의 템플릿으로 변환된다.

Bicep 템플릿을 사용하여 수행하는 주요 작업은 Azure 리소스를 정의하는 것이다.
아래는 storageAccount 리소스를 정의한 내용이다.

시작 부분에 있는 resource 키워드는 리소스 정의를 의미한다.
다음으로 리소스 기호 이름을 지정한다. 아래에서는 기호 이름이 sotrageAccount이다.
이는 Bicep 템플릿 내에서 리소스를 참조하는데 사용된다.

기호 이름 다음의 내용은 리소스 종류 및 API 버전을 의미한다.
Microsoft.Storage/storageAccounts는 storageAccounts 선언을 의미하며,
2021-08-01은 Bicep이 리소스를 만들 때 사용할 Azure Storage API의 버전이다.

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = {
  name: 'bewishstorage'
  location: 'westus3'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

다음으로 리소스의 이름과 위치, SKU(가격 책정 계층), 종류, 속성을 정의해야 한다.
이러한 정의 사항은 리소스마다, API 버전마다 다를 수 있다.

Bicep 템플릿은 일반적으로 여러 리소스를 포함한다. 이러한 관계를 종속성이라고 한다.
따라서 리소스를 다른 리소스에 종속시켜야 하는 경우가 종종 발생한다.
리소스를 정의하기 위해 다른 리소스에서 일부 정보를 추출해야 할 수도 있다.
또는 웹 애플리케이션을 배포하는 경우, 서버 인프라를 만들어야 애플리케이션을 추가할 수 있다.

예를 들어 App Service 애플리케이션을 배포하려고 한다.
그러나 App Service 애플리케이션을 만들려면 먼저 App Service 플랜을 만들어야 한다.
App Service 플랜은 서버 호스팅 리소스를 의미하며 아래와 같이 선언된다.

resource appServicePlan 'Microsoft.Web/serverFarms@2021-03-01' = {
  name: 'bewisesh-product-launch-plan'
  location: 'westus3'
  sku: {
    name: 'F1'
  }
}

App Service 애플리케이션은 아래와 같이 선언된다.
앞서 정의한 App Service 플랜에서 애플리케이션을 호스트할 수 있도록 종속성을 만들어야한다.
이를 위해 속성의 serverFarmId를 App Service 플랜의 ID로 지정한다.

resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = {
  name: 'toy-product-launch-1'
  location: 'westus3'
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}

Bicep은 아래와 같이 매개 변수와 변수를 지정할 수 있다.
매개 변수의 키워드는 param이며 string, int, bool, array, object 형식을 갖는다.
변수의 키워드는 var이며, 특별한 형식이 필요하지 않지만 초기 값을 반드시 지정해주어야 한다.
또한, 매개 변수는 allowed 키워드를 이용하여 입력에 허용되는 값 목록을 지정할 수 있다.
매개 변수와 변수를 선언한 후에는 템플릿의 나머지 부분에서 이를 참조할 수 있다.

param appServiceAppName string = 'bewisesh-product-launch-1'
var appServicePlanName = 'bewisesh-product-launch-plan'

@allowed([
  'nonprod'
  'prod'
])
param environmentType string

Bicep 템플릿 내의 코드가 복잡해지고 정의되는 리소스가 많아지는 경우 모듈화 할 필요가 있다.
모듈화를 통해 아래와 같이 한 템플릿의 리소스를 다른 템플릿에서 이용하도록 하는 것이다.
Bicep에서는 output과 module이라는 키워드를 이용하여 모듈화를 할 수 있다.

위의 내용을 바탕으로 기존에 작성했던 코드를 수정하면 아래와 같다.
우선, 기존에 작성했던 코드의 파일명을 main.bicep이라 하자.
main.bicep의 위치에서 modules라는 폴더를 만들고 아래와 같이 appService.bicep 파일을 생성하자.

param location string
param appServiceAppName string

@allowed([
  'nonprod'
  'prod'
])
param environmentType string

var appServicePlanName = 'toy-product-launch-plan'
var appServicePlanSkuName = (environmentType == 'prod') ? 'P2v3' : 'F1'

resource appServicePlan 'Microsoft.Web/serverFarms@2021-03-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSkuName
  }
}

resource appServiceApp 'Microsoft.Web/sites@2021-03-01' = {
  name: appServiceAppName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}

output appServiceAppHostName string = appServiceApp.properties.defaultHostName

매개 변수와 변수를 사용하고 있고, 맨 아래에 output이라는 키워드가 추가되었다.
이제 main.bicep을 아래와 같이 수정하자.

param location string = 'westus3'
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'
param appServiceAppName string = 'toylaunch${uniqueString(resourceGroup().id)}'

@allowed([
  'nonprod'
  'prod'
])
param environmentType string

var storageAccountSkuName = (environmentType == 'prod') ? 'Standard_GRS' : 'Standard_LRS'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountSkuName
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

module appService 'modules/appService.bicep' = {
  name: 'appService'
  params: {
    location: location
    appServiceAppName: appServiceAppName
    environmentType: environmentType
  }
}

output appServiceAppHostName string = appService.outputs.appServiceAppHostName

appService.bicep 파일과 마찬가지로 매개 변수와 변수, output을 사용하고 있다.
또한, module이라는 키워드를 이용하여 appServcie를 정의하고 있다.
module 키워드는 Bicep에게 다른 Bicep 파일을 모듈로 사용한다는 것을 알려주는 것으로,
자세히 보면 이는 appService.bicep을 사용하는 것을 알 수 있다.
이것이 가능한 것은 두 파일이 서로 output을 통해 연결되었기 때문이다.
같은 output 키워드를 사용하지만 약간 작성된 내용이 다른 것에 주의할 필요가 있다.

참고 자료 1) - What is Bicep?

0개의 댓글