아래의 절차는 Azure DevOps에서 Azure Image Builder를 사용하는 과정을 참고하는 예제이며, 실제 업무상에 적용을 위해서는 많은 부분의 고려가 필요함을 미리 언급합니다.
Azure DevOps에서 ‘Build immutable image’ Task를 이용하면, 원하는 머신 이미지를 만들 수 있습니다. 이를 이용하여 몇몇 프로그램이 수행가능한 환경이 설치된 이미지를 생성할 수 있으며, 해당 이미지는 예를 들어 Azure VM Scale Set과 같은 환경의 인스턴스 생성에 이용할 수 있습니다.
먼저, java 실행 환경(Spring Boot 앱)이 포함된 머신 이미지를 생성하여, Azure 리소스 그룹에 포함시키는 과정은 아래와 같습니다.
Azure DevOps Repo의 구성
- Azure DevOps 포털에 로그온 합니다.
- New Project를 선택하여 새로운 Project를 생성합니다.
- 생성된 Project로 들어가서 좌측의 Repos메뉴를 선택합니다.
- 이후 Import a Repository 부분에서 사용하고자 하는 Spring Boot 예제를 import 하여 구성합니다. (예, https://github.com/spring-guides/gs-spring-boot.git )
Azure DevOps Service Connection 추가
- 이전 단계에서 생성된 Project의 Project settings에 들어갑니다.
- Service Connections에서 새로운 Service Connection을 생성합니다.
- New Service Connection에서 Azure Resource Manager를 선택합니다.
- Authentication Metod는 Service principal (automatic)을 선택한 후 다음을 누릅니다.
- Scope level은 Subscription으로 선택하고 Subscription, Resource Group(기존에 생성한 Resource Group을 선택) 그리고, Service Connection 이름을 입력하고 저장합니다.
Storage Account의 생성
- Azure 포털에 로그온 합니다.
- 좌측 메뉴에서 Create Resource를 선택합니다.
- 찾기에서 Storage Account찾아 선택합니다.
- 생성 시, 새로운 resource group을 만들고, 임의의 Storage Account의 이름을 입력한 후, 적당한 Region을 선택하여 생성합니다.
Shell Script 파일의 추가
- Azure DevOps 포털에 로그온 합니다.
- 이전 단계에서 생성한 Project 내의 Repos의 Files로 이동합니다.
- 기존의 소스 폴더에 deploy.sh라는 새로운 파일을 생성합니다.
- Deploy.sh 파일의 구성은 아래와 같습니다.
1
2
3
4
5
sudo apt-get update -y
sudo apt-get install -y default-jre
sudo mkdir /lib/artifacts/
sudo cp /deployTemp/drop/*.jar /lib/artifacts/
- 참고로.jar는 Build Pipeline을 통해서 생성될 바이너리입니다.
- /deployTemp/drop/ 폴더의 위치는 Release Pipeline의 Build Immutable Image Task수행시 Artifacts가 이동될 위치입니다.
Azure Build Pipeline을 구성
- Pipelines에서 New Pipeline을 선택합니다.
- Azure Repos Git을 선택하여 이전 단계에서 구성한 Repo를 선택합니다.
- Configure your pipeline 단계에서는 Repo에 구성된 소스를 컴파일하기 위해 Maven (build your java project and run tests with Apache Maven)을 선택합니다.
- 프로젝트 내에 azure-pipelines.yml 파일이 자동 생성되고, 아래와 같이 내용을 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- task: Maven@3
inputs:
mavenPomFile: 'complete/pom.xml'
mavenOptions: '-Xmx3072m'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.8'
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/surefire-reports/TEST-*.xml'
goals: 'package'
- task: CopyFiles@2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(system.defaultworkingdirectory)'
Contents: '**/*.?(jar|sh)'
TargetFolder: '$(build.artifactstagingdirectory)'
flattenFolders: true
condition: succeededOrFailed()
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container' - 빌드가 완료되면, Artifacts가 생성됩니다. 해당 Artifacts는 Azure Release Pipeline에서 download 받아서 처리될 예정입니다.
Azure DevOps의 Release Pipeline구성
- Azure DevOps 포털에 로그온 합니다.
- 해당 Project로 들어가서 좌측의 Release 메뉴를 선택합니다. 이후 New Pipeline을 생성합니다.
- Empty Job을 선택합니다.
- Agent Job에서 Agent Specification을 ubuntu-18.04 로 선택합니다.
- Agent Job에 Build Immutable Image task를 추가합니다.
- 적당한 Display Name을 입력합니다.
- Packer template 은 “Auto generated”로 선택합니다.
- Azure subscription을 선택합니다.
- Managed VM Disk image의 체크 박스를 체크하고, Name을 입력합니다. (해당 이름으로 Azure 리소스 그룹에 이미지가 생성됩니다.)
- Storage location에 적절한 region을 지정합니다.
- Storage account에 앞서서 생성한 storage account를 선택합니다.
- Resource Group에는 Storage account와 동일한 Resource group을 선택합니다.
- Base image source는 “Gallery”로 선택합니다.
- Base image는 “ubuntu 18.04-LTS”를 선택합니다.
- Deployment Package는 일반적으로 Artifacts가 생성된 위치를 지정합니다. (일반적으로 $(System.DefaultWorkingDirectory)에 대한 상대적인 위치인데, _<project 이름>/drop이라는 형태를 갖습니다.)
- Deployment script는 앞서서 생성한 script 파일을 입력합니다. (Build pipeline에서 .sh파일도 artifacts에 포함했으므로 해당 파일 이름을 입력합니다.)
- 설정을 마치면, YAML 파일로는 아래와 같이 구성됩니다.
1
2
3
4
5
6
7
8
9
10
11
12steps:
- task: PackerBuild@1
displayName: 'Build immutable image'
inputs:
ConnectedServiceName: ‘<service connection>'
managedImageName: myvmssimage2
location: koreasouth
storageAccountName: myvmssstorage
azureResourceGroup: 'vmss_rg'
baseImage: 'Canonical:UbuntuServer:18.04-LTS:linux'
packagePath: '_vmsstest/drop'
deployScriptPath: deploy.sh - Build Pipepline과 Release Pipeline이 정상적으로 run 된다면, ‘vmss_rg’ 라는 Azure 리소스 그룹내에 myvmssstorage 라는 storage account 와 myvmssimage2 라는 이름이 image가 생성된 것으로 확인할 수 있습니다.
- 해당 머신 이미지안에는 Java 실행환경과 build Pipeline을 통해 만들어진 spring boot 앱이 포함되어 있습니다. 그러므로, 해당 머신 이미지를 기반으로 Azure VM Scale Set 인스턴스를 구성할 수 있습니다.
Azure Virtual Machine Scale Set에 이미지 업데이트
- 앞서서 생성한 머신 이미지를 이용하여 만들어진 Azure VM Scale Set 인스턴스에 포함된 Spring Boot 앱의 업데이트가 필요하다면, 앞선 절차의 Build/Release Pipeline을 통해서 머신 이미지를 다시 생성할 수 있으며 이를 기존의 Azure VM Scale Set의 인스턴스에 업데이트 해야 합니다.
- 기존의 절차에 따라 새롭게 생성된 머신 이미지를 기존의 Azure VM Scale Set 인스턴스에 업데이트를 하기 위해 Release Pipeline에 Azure CLI Task를 추가합니다.
- Azure CLI Task를 추가합니다.
- Azure Resource Manager Connection에 기존의 생성된 머신 이미지가 존재하는 Azure 리소스 그룹에 접근이 가능하도록 선택합니다.
- Script Type은 shell을 선택합니다.
- Script location은 inline Script를 선택합니다.
- Inline script에 아래를 추가합니다. (‘vms’는 VMSS의 이름, ‘vmss_rg’는 VMSS가 존재하는 resource group)
1
az vmss update --name vms --resource-group vmss_rg --set virtualMachineProfile.storageProfile.imageReference.id="/subscriptions/<subcscription-Id>/resourceGroups/vmss_rg/providers/Microsoft.Compute/images/<managed image name>"
- 새롭게 배포된 spring boot 앱을 이미지 업데이트 이후에 즉시 실행해야 한다면, 추가적으로 Azure CLI Task를 이용하여 원격에서 구동할 수 있습니다.
- Azure CLI Task를 추가합니다.
- 앞선 Azure CLI task의 작업과 동일하며, inline script에 아래와 같이 다르게 입력합니다.
1
az vmss list-instances -n vms -g vmss_rg --query "[].id" --output tsv | az vmss run-command invoke --scripts "java -jar /lib/artifacts/spring-boot-complete-0.0.1-SNAPSHOT.jar >/dev/null 2>&1 &" --command-id RunShellScript --ids @-
- 모든 Pipeline이 정상적으로 실행 완료가 되면 새롭게 배포된 spring boot앱이 VMSS에 정상적으로 실행되는 지 확인하십시오.
※본 정보의 내용(첨부문서, 링크처 등을 포함)은 작성일 현재이며, 예고없이 변경될 수 있습니다.