자습서: Azure CLI를 사용한 Linux 가상 머신 관리에 대해 알아보기

리소스를 Azure에 배포할 때 배포할 리소스의 형식, 위치 및 설정 방법을 결정하는 데 놀라운 유연성을 경험할 수 있습니다. 단, 그러한 유연성으로 인해 조직에서 허용하려는 것보다 더 많은 선택 사항이 있을 수도 있습니다. 리소스를 Azure에 배포할 때 다음에 대해 궁금하실 수도 있습니다.

  • 특정 국가/지역에서 데이터 독립성에 대한 법률 요구 사항을 충족하려면 어떻게 해야 하나요?
  • 비용은 어떻게 관리할 수 있나요?
  • 누군가가 중요한 시스템을 실수로 변경하지 않도록 보장하려면 어떻게 해야 하나요?
  • 리소스 비용을 추적하고 정확하게 청구하려면 어떻게 해야 하나요?

이 문서에서는 그러한 질문을 해결합니다. 특히,

  • 사용자가 추가 동작이 아닌 예상된 동작을 수행할 수 있는 사용 권한을 갖도록 사용자를 역할에 할당하고 역할을 범위에 할당합니다.
  • 구독에서 리소스에 대한 규칙을 규정하는 정책을 적용합니다.
  • 시스템에 중요한 리소스를 잠급니다.
  • 조직에 의미 있는 값으로 추적할 수 있도록 리소스에 태그를 지정합니다.

이 문서에서는 거버넌스를 구현하기 위해 수행하는 작업에 중점을 둡니다. 개념보다 더 광범위한 논의는 Azure에서 거버넌스를 참조하세요.

사전 요구 사항

  • Azure Cloud Shell에서 Bash 환경을 사용합니다.

    새 창에서 Cloud Shell 시작

  • 원하는 경우 Azure CLI를 설치하여 CLI 참조 명령을 실행합니다.

    • 로컬 설치를 사용하는 경우 az login 명령을 사용하여 Azure CLI에 로그인합니다. 인증 프로세스를 완료하려면 터미널에 표시되는 단계를 수행합니다. 추가 로그인 옵션은 Azure CLI를 사용하여 로그인을 참조하세요.

    • 메시지가 표시되면 처음 사용할 때 Azure CLI 확장을 설치합니다. 확장에 대한 자세한 내용은 Azure CLI에서 확장 사용을 참조하세요.

    • az version을 실행하여 설치된 버전과 종속 라이브러리를 찾습니다. 최신 버전으로 업그레이드하려면 az upgrade를 실행합니다.

  • 이 자습서에는 Azure CLI 버전 2.0.30 이상이 필요합니다. Azure Cloud Shell을 사용하는 경우 최신 버전이 이미 설치되어 있습니다.

범위 이해

항목을 만들기 전에 범위 개념을 검토해 보겠습니다. Azure는 네 가지 관리 수준인 관리 그룹, 구독, 리소스 그룹 및 리소스를 제공합니다. 관리 그룹은 미리 보기 릴리스에 포함되어 있습니다. 다음 그림은 세 가지 계층의 예를 보여 줍니다.

Scope

이러한 범위 수준에서 관리 설정을 적용합니다. 선택한 수준은 설정이 적용되는 범위를 결정합니다. 하위 수준은 상위 수준의 설정을 상속합니다. 구독에 설정을 적용하면 해당 설정이 구독의 모든 리소스 그룹 및 리소스에 적용됩니다. 리소스 그룹에 설정을 적용하면 해당 설정이 리소스 그룹 및 모든 리소스에 적용됩니다. 그러나 다른 리소스 그룹에는 해당 설정이 적용되지 않습니다.

일반적으로 중요한 설정은 상위 수준에서 적용하고, 프로젝트별 요구 사항은 하위 수준에서 적용하는 것이 좋습니다. 예를 들어, 조직의 모든 리소스가 특정 지역에 배포되도록 하려고 할 경우 이러한 요구 사항을 달성하기 위해 허용되는 위치를 지정하는 정책을 구독에 적용합니다. 조직의 다른 사용자가 새 리소스 그룹 및 리소스를 추가하게 되면 허용되는 위치에 자동으로 적용됩니다.

이 자습서에서는 이러한 설정이 완료된 후 쉽게 제거할 수 있도록 모든 관리 설정을 리소스 그룹에 적용합니다.

해당 리소스 그룹을 만들어 보겠습니다.

az group create --name myResourceGroup --location "East US"

현재 리소스 그룹이 비어 있습니다.

Azure 역할 기반 액세스 제어

조직의 사용자에게 이러한 리소스에 대한 적절한 수준의 액세스 권한이 있는지 확인하려고 합니다. 사용자에게 무제한 액세스 권한은 부여하지 않으면서 동시에 사용자가 작업을 수행할 수 있는지 확인해야 합니다. Azure RBAC(Azure 역할 기반 액세스 제어)를 통해 범위에서 특정 작업을 완료할 수 있는 권한이 있는 사용자를 관리할 수 있습니다.

역할 할당을 만들고 제거하려면 사용자에게 Microsoft.Authorization/roleAssignments/* 액세스가 있어야 합니다. 이 액세스는 소유자 또는 사용자 액세스 관리자 역할을 통해 부여됩니다.

가상 머신 솔루션을 관리하기 위해서는 일반적으로 필요한 액세스 권한을 제공하는 세 가지 리소스 특정 역할이 있습니다.

개별 사용자에게 역할을 할당하는 대신 비슷한 동작을 수행해야 하는 사용자에게 Azure Active Directory 그룹을 사용하기가 더 쉽습니다. 그런 다음, 해당 그룹에 적절한 역할을 할당합니다. 이 문서에서는 가상 머신 관리에 기존 그룹을 사용하거나, 포털을 사용하여 Azure Active Directory 그룹을 만듭니다.

새 그룹을 만들거나 기존 그룹을 찾은 뒤 az role assignment create 명령을 사용하여 새로운 Azure Active Directory 그룹을 리소스 그룹에 대한 Virtual Machine 기여자 역할에 할당합니다.

adgroupId=$(az ad group show --group <your-group-name> --query objectId --output tsv)

az role assignment create --assignee-object-id $adgroupId --role "Virtual Machine Contributor" --resource-group myResourceGroup

디렉터리에 보안 주체 <GUID>가 없다는 오류가 표시되면 새 그룹이 Azure Active Directory 전체에 전파되지 않았습니다. 명령을 다시 실행합니다.

일반적으로 네트워크 참가자Storage 계정 참가자를 위한 프로세스를 반복해 배포된 리소스를 관리하도록 사용자가 할당됐는지 확인합니다. 이 문서에서는 이러한 단계를 건너뛸 수 있습니다.

Azure Policy

Azure Policy는 구독의 모든 리소스가 회사 표준을 따르도록 관리하는 데 유용합니다. 사용 중인 구독에 이미 여러 개의 정책 정의가 있습니다. 사용 가능한 정책 정의를 보려면 az policy definition list 명령을 사용합니다.

az policy definition list --query "[].[displayName, policyType, name]" --output table

기존 정책 정의를 참조할 수 있습니다. 해당 정책 유형은 BuiltIn 또는 사용자 지정 중 하나입니다. 할당하고자 하는 조건을 설명하는 정책에 대한 정의를 검토해 보세요. 이 문서에서는 다음과 같은 정책을 할당할 수 있습니다.

  • 모든 리소스의 위치를 제한합니다.
  • 가상 머신에 대한 SKU를 제한합니다.
  • 관리 디스크를 사용하지 않는 가상 머신을 감사합니다.

다음 예제에서는 표시 이름을 기준으로 세 가지 정책 정의를 검색합니다. az policy assignment create 명령을 사용하여 해당 정의를 리소스 그룹에 할당합니다. 일부 정책의 경우 매개 변수 값을 제공하여 허용된 값을 지정합니다.

# Get policy definitions for allowed locations, allowed SKUs, and auditing VMs that don't use managed disks
locationDefinition=$(az policy definition list --query "[?displayName=='Allowed locations'].name | [0]" --output tsv)
skuDefinition=$(az policy definition list --query "[?displayName=='Allowed virtual machine SKUs'].name | [0]" --output tsv)
auditDefinition=$(az policy definition list --query "[?displayName=='Audit VMs that do not use managed disks'].name | [0]" --output tsv)

# Assign policy for allowed locations
az policy assignment create --name "Set permitted locations" \
  --resource-group myResourceGroup \
  --policy $locationDefinition \
  --params '{ 
      "listOfAllowedLocations": {
        "value": [
          "eastus", 
          "eastus2"
        ]
      }
    }'

# Assign policy for allowed SKUs
az policy assignment create --name "Set permitted VM SKUs" \
  --resource-group myResourceGroup \
  --policy $skuDefinition \
  --params '{ 
      "listOfAllowedSKUs": {
        "value": [
          "Standard_DS1_v2", 
          "Standard_E2s_v2"
        ]
      }
    }'

# Assign policy for auditing unmanaged disks
az policy assignment create --name "Audit unmanaged disks" \
  --resource-group myResourceGroup \
  --policy $auditDefinition

앞의 예제는 정책에 대한 매개 변수를 이미 알고 있다고 가정합니다. 매개 변수를 확인해야 할 경우 다음을 사용합니다.

az policy definition show --name $locationDefinition --query parameters

가상 머신 배포

솔루션을 배포할 수 있도록 역할 및 정책을 할당했습니다. 기본 크기는 허용된 SKU 중 하나인 Standard_DS1_v2입니다. 명령은 기본 위치에 SSH 키가 없는 경우 해당 키를 만듭니다.

az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys

배포를 완료한 후 솔루션에 추가 관리 설정을 적용할 수 있습니다.

리소스 잠금

리소스 잠금은 조직의 사용자가 실수로 중요한 리소스를 삭제하거나 수정하는 것을 방지합니다. 역할 기반 액세스 제어와 달리 리소스 잠금은 모든 사용자와 역할 전반에 제한을 적용합니다. 잠금 수준을 CanNotDelete 또는 ReadOnly로 설정할 수 있습니다.

관리 잠금을 만들거나 삭제하려면 Microsoft.Authorization/locks/* 작업에 대한 액세스 권한이 있어야 합니다. 기본 제공 역할의 경우 소유자사용자 액세스 관리자에게만 이러한 작업의 권한이 부여됩니다.

가상 머신 및 네트워크 보안 그룹을 잠그려면 az lock create 명령을 사용합니다.

# Add CanNotDelete lock to the VM
az lock create --name LockVM \
  --lock-type CanNotDelete \
  --resource-group myResourceGroup \
  --resource-name myVM \
  --resource-type Microsoft.Compute/virtualMachines

# Add CanNotDelete lock to the network security group
az lock create --name LockNSG \
  --lock-type CanNotDelete \
  --resource-group myResourceGroup \
  --resource-name myVMNSG \
  --resource-type Microsoft.Network/networkSecurityGroups

잠금을 테스트하려면 다음 명령을 실행해 봅니다.

az group delete --name myResourceGroup

삭제 작업이 잠금 때문에 수행할 수 없음을 나타내는 오류가 표시됩니다. 리소스 그룹은 특별히 잠금을 제거하는 경우에 삭제할 수 있습니다. 해당 단계는 리소스 정리에 표시됩니다.

리소스 태그 지정

Azure 리소스에 태그를 적용하여 범주별로 논리적으로 구성합니다. 각 태그는 이름과 값으로 이루어져 있습니다. 예를 들어 프로덕션의 모든 리소스에 "환경" 이름과 "프로덕션" 값을 적용할 수 있습니다.

리소스 그룹에 두 개의 태그를 추가하려면 az group update 명령을 사용합니다.

az group update -n myResourceGroup --set tags.Environment=Test tags.Dept=IT

세 번째 태그를 추가하려 한다고 가정해보겠습니다. 새로운 태그로 명령을 다시 실행합니다. 기존 태그에 추가됩니다.

az group update -n myResourceGroup --set tags.Project=Documentation

리소스는 리소스 그룹에서 태그를 상속하지 않습니다. 현재, 리소스 그룹에 3개의 태그가 있지만 리소스에는 태그가 없습니다. 리소스 그룹의 모든 태그를 리소스에 적용하고 리소스의 기존 태그를 유지하려면 다음 스크립트를 사용합니다.

# Get the tags for the resource group
jsontag=$(az group show -n myResourceGroup --query tags)

# Reformat from JSON to space-delimited and equals sign
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')

# Get the resource IDs for all resources in the resource group
r=$(az resource list -g myResourceGroup --query [].id --output tsv)

# Loop through each resource ID
for resid in $r
do
  # Get the tags for this resource
  jsonrtag=$(az resource show --id $resid --query tags)
  
  # Reformat from JSON to space-delimited and equals sign
  rt=$(echo $jsonrtag | tr -d '"{},' | sed 's/: /=/g')
  
  # Reapply the updated tags to this resource
  az resource tag --tags $t$rt --id $resid
done

또는 기존 태그를 유지하지 않고 리소스 그룹의 태그를 리소스에 적용할 수도 있습니다.

# Get the tags for the resource group
jsontag=$(az group show -n myResourceGroup --query tags)

# Reformat from JSON to space-delimited and equals sign
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')

# Get the resource IDs for all resources in the resource group
r=$(az resource list -g myResourceGroup --query [].id --output tsv)

# Loop through each resource ID
for resid in $r
do
  # Apply tags from resource group to this resource
  az resource tag --tags $t --id $resid
done

여러 값을 단일 태그에 결합하려면 JSON 문자열을 사용합니다.

az group update -n myResourceGroup --set tags.CostCenter='{"Dept":"IT","Environment":"Test"}'

리소스 그룹의 모든 태그를 제거 하려면 다음을 사용합니다.

az group update -n myResourceGroup --remove tags

가상 머신에 태그를 적용하려면 az resource tag 명령을 사용합니다. 리소스의 기존 태그는 유지되지 않습니다.

az resource tag -n myVM \
  -g myResourceGroup \
  --tags Dept=IT Environment=Test Project=Documentation \
  --resource-type "Microsoft.Compute/virtualMachines"

태그로 리소스 찾기

태그 이름 및 값을 사용하여 리소스를 찾으려면 az resource list 명령을 사용합니다.

az resource list --tag Environment=Test --query [].name

태그 값으로 모든 가상 머신 중지와 같은 관리 작업에 대한 반환 값을 사용할 수 있습니다.

az vm stop --ids $(az resource list --tag Environment=Test --query "[?type=='Microsoft.Compute/virtualMachines'].id" --output tsv)

태그 값으로 비용 보기

태그를 리소스에 적용한 후 해당 태그를 사용하여 리소스에 대한 비용을 볼 수 있습니다. 최신 사용법을 표시하기 위한 비용 분석에 시간이 걸리므로 아직 비용을 참조할 수 없습니다. 해당 비용을 사용할 수 있는 경우 사용 중인 구독에서 여러 리소스 그룹에 걸친 리소스에 대한 비용을 볼 수 있습니다. 사용자는 비용을 확인하려면 청구 정보에 대한 구독 수준의 액세스 권한을 가져야 합니다.

해당 포털에서 태그로 비용을 보려면 구독을 선택하고 비용 분석을 선택합니다.

비용 분석

태그 값으로 필터링하고 적용을 선택합니다.

태그로 비용 보기

Azure 소비 API 개요를 사용하여 프로그래밍 방식으로 비용을 볼 수도 있습니다.

리소스 정리

잠금이 해제될 때까지는 잠긴 네트워크 보안 그룹을 삭제할 수 없습니다. 잠금을 제거하려면 잠금의 ID를 검색하고 az lock delete 명령을 입력합니다.

vmlock=$(az lock show --name LockVM \
  --resource-group myResourceGroup \
  --resource-type Microsoft.Compute/virtualMachines \
  --resource-name myVM --output tsv --query id)
nsglock=$(az lock show --name LockNSG \
  --resource-group myResourceGroup \
  --resource-type Microsoft.Network/networkSecurityGroups \
  --resource-name myVMNSG --output tsv --query id)
az lock delete --ids $vmlock $nsglock

더 이상 필요하지 않은 경우 az group delete 명령을 사용하여 리소스 그룹, VM 및 모든 관련된 리소스를 제거할 수 있습니다. VM에 대한 SSH 세션을 종료한 후 다음과 같이 리소스를 삭제합니다.

az group delete --name myResourceGroup

다음 단계

이 자습서에서는 사용자 지정 VM 이미지를 만들었습니다. 구체적으로 다음 작업 방법을 알아보았습니다.

  • 역할에 사용자 할당
  • 표준을 적용하는 정책 적용
  • 잠금을 사용하여 중요한 리소스 보호
  • 결제 및 관리에 대한 리소스 태그 지정

다음 자습서로 진행하여 가상 머신에서 변경 내용을 식별하고 패키지 업데이트를 관리하는 방법에 대해 알아봅니다.