
이번 포스팅에서는 Azure Compute Gallery란 무엇인지?? VM 이미지를 저장하는 법과, 저장된 이미지를 기반으로 VM 생성하는 방법을 진행하고자 한다.
VM 배포는 Terraform를 이용하여 배포를 진행한다.
Azure Compute Gallery는 Azure 내에서 사용자 지정 가상 머신 이미지와 애플리케이션 패키지를 중앙에서 관리하고 공유할 수 있도록 하는 서비스입니다.
이전에는 Shared Image Gallery로 불렸으며, 이미지 버전 관리, 글로벌 복제, RBAC를 통한 공유 등 다양한 기능을 제공하여 표준화된 이미지 배포와 빠른 VM 프로비저닝을 지원합니다.
# Azure Logion
az login
# Azure 구독 ID 확인
az account list
# 구독 활성화
az account set --subscription "구독_ID"
# 현재 구독 활성화
az account show --output table
# Azure Principal 생성
## 이미 생성이 되어 있다면 해당 단계는 스킵한다.
az ad sp create-for-rbac --name "terraform-sp" --role="Contributor" --scopes="/subscriptions/<SUBSCRIPTION_ID>"
# 리소스 삭제시 해당 코드 삭제할것
## 이미 생성이 되어 있다면 해당 단계는 스킵한다.
cat << EOF >> ~/.zshrc
export ARM_CLIENT_ID=$(az ad sp list --display-name "terraform-sp" --query "[].appId" -o tsv)"
export ARM_CLIENT_SECRET=${password}" # 해당 부분 수정 필요
export ARM_TENANT_ID=$(az account show --query "tenantId" -o tsv)"
export ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)"
EOF
source ~/.zshrc
# 변수 확인
echo $ARM_CLIENT_ID $ARM_CLIENT_SECRET $ARM_TENANT_ID $ARM_SUBSCRIPTION_ID
tail -n 10 ~/.zshrc


변수 선언
위에 나온 password를 기반으로 아래 코드를 수정한다.
cat << EOF >> ~/.zshrc
export ARM_CLIENT_ID=\$(az ad sp list --display-name "terraform-sp" --query "[].appId" -o tsv)
export ARM_CLIENT_SECRET=${password} # 실제 비밀번호로 대체 필요 (보안 주의)
export ARM_TENANT_ID=$(az account show --query tenantId -o tsv)
export ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)
EOF
source ~/.zshrc
# 변수 확인
echo $ARM_CLIENT_ID $ARM_CLIENT_SECRET $ARM_TENANT_ID $ARM_SUBSCRIPTION_ID
tail -n 10 ~/.zshrc
결과

vm 접속을 위하여 pem 파일 생성이 필요하다.
Azure portal에 접속하여 key 파일을 생성한다. - Link
pem key를 생성하였다면 pem → pub으로 변경하는 작업이 필요하다.
chmod 600 my_key.pem
ssh-keygen -y -f my_key.pem > my_key.pub
# 예시
ssh-keygen -y -f /Users/bokhoshin/azure/bocopile-azure-key.pem > /Users/bokhoshin/azure/bocopile-azure-key.pub

az group create --name ${resource-group-name} --location ${location-path}
az group create --name sample-group --location koreasouth
az sig create --resource-group ${resouce-group-name} --gallery-name ${compute-gallery-name} --location ${location-path}
az sig create --resource-group sample-group --gallery-name sample --location koreasouth
Azure Compute gallery 생성 결과는 Azure Portal에서도 확인할수 있습니다.
해당 단계를 진행하기 위해선 VM 생성이 되어야 한다.
우선 Terraform를 이용하여 VM 생성하도록 하자
git clone https://github.com/bocopile/terraform-azure.git
cd vm/vm-create
해당 코드를 보면 변수 선언이 되어 있다.
variable "resource_group_name" {
description = "Azure Resource Group Name"
type = string
default = "sample-resouce"
}
variable "location" {
description = "Azure Region"
type = string
default = "Korea South"
}
# 해당 부분 수정 필요
variable "ssh_public_key_path" {
description = "Path to SSH Public Key"
type = string
default = "/Users/bokhoshin/azure/bocopile-azure-key.pub"
}
# 해당 부분
variable "admin_username" {
description = "Admin username for the VM"
type = string
default = "bocopile"
}
해당 코드 중에서 ssh_public_key_path 및, admin_username 자신의 환경에 맞춰서 변경한다.
해당 작업을 진행한 후에 아래 코드를 순차적으로 실행한다.
# 테라폼 작업 디렉터리 초기화
terraform init
# 현재 구성 파일과 실제 인프라 상태를 비교하여, 적용될 인프라를 보여준다.
terraform plan
# 인프라 구성
terraform apply -auto-approve



가장 먼저 VM 할당 해제 및 일반화를 진행한다.
단 VM 이미지는 운영체제 상태에 따라서 일반화 / 특수화로 나눌수 있다.
일반화 / 특수화는 다음과 같이 구분이 된다.
해당 블로그 글에선 일반화로 진행한다.
# VM 할당 해제 (중지)
az vm deallocate --resource-group sample-resouce --name sample-vm
# VM 일반화 (Sysprep) - skip
az vm generalize --resource-group sample-resouce --name sample-vm
Azure portal에서 확인하면 해당 VM이 중지되어 있음을 확인 할수 있다.

az image create \
--resource-group ${resource-group-name} \
--name ${image-name} \
--source ${vm-name} \
--hyper-v-generation V2
# 예시
az image create \
--resource-group sample-resouce \
--name sample-vm-image \
--source sample-vm \
--hyper-v-generation V2
결과


이미 해당 Gallery에 정의가 되어 있는 경우 해당 단계는 스킵한다.
확인 방법 - Link
# --gallery-name : 이미지 정의를 생성할 Azure Compute Gallery 명칭
# --gallery-image-definition : 생성할 이미지 이름을 정의
# --publisher : 이미지 게시자
# --offer : 이미지 오퍼 이름을 지정
# --sku : 이미지의 SKU(Stock Keeping Unit)를 지정합니다
# --os-type : 이미지 운영체제 유형을 지정 (Linux, Windows)
# --hyper-v-generation : 이미지가 지원하는 Hyper-V 세대 버전을 지정 (일반적으로 v2)
az sig image-definition create \
--resource-group sample-group \
--gallery-name sample \
--gallery-image-definition "${gallay-image}" \
--publisher "${publisher}" \
--offer "${offer}" \
--sku "${sku}" \
--os-type Linux \
--hyper-v-generation V2
# 예시
az sig image-definition create \
--resource-group sample-group \
--gallery-name sample \
--gallery-image-definition "sample-vm-ubuntu-24" \
--publisher "MyPublisher" \
--offer "MyOffer" \
--sku "MySKU" \
--os-type Linux \
--hyper-v-generation V2
해당 명령어를 실행하면 Azure Compute Gallery에 다음과 같은 이미지가 정의 된다.

이미지가 정의가 됬다면 VM 이미지를 Azure Compute Gallery에 저장 하는 것이 필요하다.
여기서 몇가지 주의할 내용이 있다.
(주의사항)
${managed-resource-group-name} : Managed Image 가 속한 리소스 그룹명 → sample-resouce
${managed-resource-image-name} : Managed Image 생성시 지정했던 이미지명 → sample-vm-image
${compute-gallery-resource-name} : Azure Compute Gallery가 속한 리소스 그룹명 → sample-group
${compute-gallery-name} : Azure Compute Gallery 명 → sample
${compute-gallery-image-name} : Azure Compute Gallery 이미지 정의 명칭 : sample-vm-ubuntu-24
code
# Managed Image의 ID 조회
image_id=$(az image show \
--resource-group ${managed-resource-group-name}\
--name ${managed-resource-image-name} \
--query id --output tsv)
az image list \
--resource-group ${managed-resource-group-name} \
--query "[?name=='${managed-resource-image-name}].id" -o tsv
# 해당 갤러리에 Image 등록
az sig image-version create \
--resource-group ${compute-gallery-resource-name} \
--gallery-name ${compute-gallery-name} \
--gallery-image-definition " ${compute-gallery-image-name}" \
--gallery-image-version 1.0.0 \
--target-regions "koreasouth" \
--replica-count 1 \
--managed-image $(az image list --resource-group ${managed-resource-group-name} --query "[?name=='${managed-resource-image-name}'].id" -o tsv)
# Managed Image의 ID 조회 - 예시
image_id=$(az image show \
--resource-group sample-resouce \
--name sample-vm-image \
--query id --output tsv)
az image list \
--resource-group sample-resouce \
--query "[?name=='sample-vm-image'].id" -o tsv
# 조회된 ID를 명령어에 직접 입력
az sig image-version create \
--resource-group sample-group \
--gallery-name sample \
--gallery-image-definition "sample-vm-ubuntu-24" \
--gallery-image-version 1.0.0 \
--target-regions "koreasouth" \
--replica-count 1 \
--managed-image $(az image list --resource-group sample-resouce --query "[?name=='sample-vm-image'].id" -o tsv)



)
이미지 생성이 완료되었다면 VM을 재실행 및 VM 생성했던 폴더로 돌아가 VM 및 리소스를 삭제한다.
단 일반화/특수화 설정에 따라서 VM 삭제 하는 방법이 다르다.
일반화를 설정한 경우 VM은 더 이상 부팅할 수 없는 상태가 됩니다.
# Azure VM 실행
az vm start --resource-group sample-group --name sample-vm
cd vm/vm-create
# terraform를 이용하여 리소스 삭제 명령어
terraform destroy -auto-approve
해당 경우에는 Azure portal를 이용하여 삭제가 필요하다.
VM 생성시 Clone 하였던 프로젝트에 vm/vm-create-compute-gallery 해당 코드를 이용하여 배포를 진행한다.
우선 Variables.tf 파일에서 아래 변수들을 자신의 환경에 맞게 수정 한다.
variable "vm_version" {
description = "Azure VM version"
type = string
default = "1.0.0"
}
variable "vm_image_name" {
description = "Azure VM image name"
type = string
default = "sample-vm-ubuntu-24"
}
variable "vm_gallery_name" {
description = "Azure Gallery Name"
type = string
default = "sample"
}
variable "vm_resource_group_name" {
description = "Azure Gallery resource group"
type = string
default = "sample-group"
}
해당 코드를 수정하였다면 terraform을 이용하여 배포 해보자
# 테라폼 작업 디렉터리 초기화
terraform init
# 현재 구성 파일과 실제 인프라 상태를 비교하여, 적용될 인프라를 보여준다.
terraform plan
# 인프라 구성
terraform apply -auto-approve


ssh -i ${pem-path} ${id}@${VM-ip}
#예시
ssh -i /Users/bokhoshin/azure/bocopile-azure-key.pem bocopile@52.231.185.204
실습이 완료되었다면 다음 순서 대로 삭제를 진행한다.
# image 삭제
az sig image-version delete \
--resource-group sample-group \
--gallery-name sample \
--gallery-image-definition sample-vm-ubuntu-24 \
--gallery-image-version 1.0.0
# image 정의 삭제
az sig image-definition delete \
--resource-group sample-group \
--gallery-name sample \
--gallery-image-definition sample-vm-ubuntu-24
# Azure Compute Gallery 삭제
az sig delete \
--resource-group sample-group \
--gallery-name sample-group
# Resource Group 삭제
az group delete --name sample-group --yes --no-wait