빠른 시작: Azure SDK for Go를 사용하여 템플릿에서 Azure 가상 머신 배포

이 빠른 시작에서는 Azure SDK for Go를 사용하여 Azure Resource Manager 템플릿에서 리소스를 배포하는 방법을 보여 줍니다. 템플릿은 Azure 리소스 그룹의 모든 리소스의 스냅샷. 이 과정에서 SDK의 기능 및 규칙에 익숙해집니다.

이 빠른 시작이 끝나면 사용자 이름 및 암호로 로그인하는 실행 중인 VM이 있습니다.

참고 항목

Resource Manager 템플릿 을 사용하지 않고 Go에서 VM을 만드는 방법을 보려면 SDK를 사용하여 모든 VM 리소스를 빌드하고 구성하는 방법을 보여 주는 명령적 샘플 이 있습니다. 이 샘플에서 템플릿을 사용하면 Azure 서비스 아키텍처에 대한 세부 정보를 너무 많이 가져오지 않고도 SDK 규칙에 집중할 수 있습니다.

Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

Azure Cloud Shell 시작

Azure Cloud Shell은 Azure에서 실행되는 대화형 셸입니다. 여기에는 계정과 함께 사용하도록 미리 설치되고 구성된 일반적인 도구가 있습니다. 복사를 선택하여 코드를 복사하고 Cloud Shell에 붙여넣은 다음 Enter 키를 눌러 실행합니다.

Cloud Shell을 시작하는 몇 가지 방법이 있습니다.

코드 블록의 오른쪽 위 모서리에서 시도를 선택합니다.

Cloud Shell in this article

브라우저에서 Cloud Shell을 엽니다.

https://shell.azure.com/bash

Azure Portal 오른쪽 위에 있는 메뉴에서 Cloud Shell 버튼을 선택합니다.

Cloud Shell in the portal

Azure CLI의 로컬 설치를 사용할 경우, 이 빠른 시작을 위해서는 CLI 버전 2.0.28 이상이 필요합니다. CLI 설치가 이 요구 사항을 충족하는지 확인하려면 실행 az --version 합니다. 설치 또는 업그레이드가 필요한 경우, Azure CLI 설치를 참조하세요.

Go용 Azure SDK 설치

Go용 Azure SDK는 Go 버전 1.8 이상과 호환됩니다. Azure Stack Profiles를 사용하는 환경의 경우 Go 버전 1.9가 최소 요구 사항입니다. Go를 설치해야 할 경우 Go 설치 지침을 따릅니다.

Go용 Azure SDK 및 해당 종속성은 go get을 통해 다운로드할 수 있습니다.

go get -u -d github.com/Azure/azure-sdk-for-go/...

Warning

URL에서 Azure은(는) 대문자로 표시해야 합니다. 그렇지 않으면 SDK로 작업할 때 대/소문자 관련 가져오기 문제가 발생할 수 있습니다. 또한 import 문에서 대문 Azure 자로 표시해야 합니다.

서비스 주체 만들기

애플리케이션을 사용하여 Azure에 비대화형으로 로그인하려면 서비스 주체가 필요합니다. 서비스 주체는 고유한 사용자 ID를 만드는 RBAC(역할 기반 액세스 제어)의 일부입니다. CLI를 사용하여 새 서비스 주체를 만들려면 다음 명령을 실행합니다.

az ad sp create-for-rbac --role Contributor \
    --scopes /subscriptions/<subscription_id> \
    --sdk-auth > quickstart.auth

환경 변수 AZURE_AUTH_LOCATION 를 이 파일의 전체 경로로 설정합니다. 그런 다음 SDK는 서비스 주체에서 정보를 변경하거나 기록할 필요 없이 이 파일에서 직접 자격 증명을 찾아 읽습니다.

코드 가져오기

빠른 시작 코드와 모든 종속성을 go get가져옵니다.

go get -u -d github.com/Azure-Samples/azure-sdk-for-go-samples/quickstarts/deploy-vm/...

변수가 제대로 설정된 경우 AZURE_AUTH_LOCATION 소스 코드를 수정할 필요가 없습니다. 프로그램이 실행되면 해당 위치에서 필요한 모든 인증 정보를 로드합니다.

코드 실행

명령을 사용하여 빠른 시작을 실행합니다 go run .

cd $GOPATH/src/github.com/Azure-Samples/azure-sdk-for-go-samples/quickstarts/deploy-vm
go run main.go

배포에 성공하면 새로 만든 가상 머신에 로그인하기 위한 사용자 이름, IP 주소 및 암호를 제공하는 메시지가 표시됩니다. 이 컴퓨터에 SSH를 실행하여 실행 중인지 확인합니다.

정리

CLI를 사용하여 리소스 그룹을 삭제하여 이 빠른 시작 중에 만든 리소스를 정리합니다.

az group delete -n GoVMQuickstart

또한 생성된 서비스 주체를 삭제합니다. quickstart.auth 파일에 clientId에 대한 JSON 키가 있습니다. 이 값을 환경 변수에 CLIENT_ID_VALUE 복사하고 다음 Azure CLI 명령을 실행합니다.

az ad sp delete --id ${CLIENT_ID_VALUE}

에 대한 CLIENT_ID_VALUEquickstart.auth값을 제공하는 위치입니다.

Warning

이 애플리케이션의 서비스 주체를 삭제하지 못하면 Microsoft Entra 테넌트에서 활성 상태로 남습니다. 서비스 주체의 이름과 암호는 모두 UUID로 생성되지만 사용하지 않는 서비스 주체와 Microsoft Entra 애플리케이션을 삭제하여 적절한 보안 사례를 준수해야 합니다.

코드 심화 안내

빠른 시작 코드는 변수 및 여러 작은 기능들의 블록으로 세분화됩니다. 여기에서는 이러한 각 블록에 대해 자세히 설명합니다.

변수, 상수 및 형식

빠른 시작은 자체 포함되므로 전역 상수 및 변수를 사용합니다.

const (
    resourceGroupName     = "GoVMQuickstart"
    resourceGroupLocation = "eastus"

    deploymentName = "VMDeployQuickstart"
    templateFile   = "vm-quickstart-template.json"
    parametersFile = "vm-quickstart-params.json"
)

// Information loaded from the authorization file to identify the client
type clientInfo struct {
    SubscriptionID string
    VMPassword     string
}

var (
    ctx        = context.Background()
    clientData clientInfo
    authorizer autorest.Authorizer
)

생성된 리소스의 이름을 지정하는 값이 선언됩니다. 또한 여기에 지정된 위치는 다른 데이터 센터에서의 배포 동작을 확인할 수 있도록 변경할 수 있습니다. 모든 데이터 센터에 필요한 리소스를 모두 사용할 수 있는 것은 아닙니다.

이 형식은 clientInfo SDK에서 클라이언트를 설정하고 VM 암호를 설정하기 위해 인증 파일에서 로드된 정보를 보유합니다.

parametersFile 상수는 templateFile 배포에 필요한 파일을 가리킵니다. 인증 authorizer 을 위해 Go SDK에서 구성되며ctx, 변수는 네트워크 작업에 대한 Go 컨텍스트입니다.

인증 및 초기화

함수는 init 인증을 설정합니다. 인증은 빠른 시작에 포함된 모든 항목들의 사전 조건이므로, 초기화 중에 준비하는 것이 좋습니다. 또한 클라이언트 및 VM을 구성하기 위해 인증 파일에서 필요한 일부 정보를 로드합니다.

func init() {
    var err error
    authorizer, err = auth.NewAuthorizerFromFile(azure.PublicCloud.ResourceManagerEndpoint)
    if err != nil {
        log.Fatalf("Failed to get OAuth config: %v", err)
    }

    authInfo, err := readJSON(os.Getenv("AZURE_AUTH_LOCATION"))
    clientData.SubscriptionID = (*authInfo)["subscriptionId"].(string)
    clientData.VMPassword = (*authInfo)["clientSecret"].(string)
}

첫째, 인증. NewAuthorizerFromFile 은 에 AZURE_AUTH_LOCATION있는 파일에서 인증 정보를 로드하기 위해 호출됩니다. 다음으로, 이 파일은 함수(여기서 생략)를 통해 readJSON 수동으로 로드되어 프로그램의 나머지 부분을 실행하는 데 필요한 두 값인 클라이언트의 구독 ID와 VM의 암호에도 사용되는 서비스 주체의 비밀을 가져옵니다.

Warning

빠른 시작을 간단하게 유지하기 위해 서비스 주체 암호가 재사용됩니다. 프로덕션 환경에서는 Azure 리소스에 대한 액세스를 제공하는 암호를 다시 사용해서는 안 됩니다.

기본()의 작업 흐름

함수는 main 작업 흐름을 나타내고 오류 검사 수행하기만 하는 간단한 함수입니다.

func main() {
    group, err := createGroup()
    if err != nil {
        log.Fatalf("failed to create group: %v", err)
    }
    log.Printf("Created group: %v", *group.Name)

    log.Printf("Starting deployment: %s", deploymentName)
    result, err := createDeployment()
    if err != nil {
        log.Fatalf("Failed to deploy: %v", err)
    }
    if result.Name != nil {
        log.Printf("Completed deployment %v: %v", deploymentName, *result.Properties.ProvisioningState)
    } else {
        log.Printf("Completed deployment %v (no data returned to SDK)", deploymentName)
    }
    getLogin()
}

코드가 실행하는 단계는 순서대로 다음과 같습니다.

  • ()에 배포할createGroup 리소스 그룹 만들기
  • 이 그룹 내에서 배포 만들기(createDeployment)
  • 배포된 VM에 대한 로그인 정보 가져오기 및 표시(getLogin)

리소스 그룹 만들기

이 함수는 createGroup 리소스 그룹을 만듭니다. 호출 흐름 및 인수를 살펴보면 서비스 상호 작용이 SDK에서 구조화되는 방식을 보여 줍니다.

func createGroup() (group resources.Group, err error) {
    groupsClient := resources.NewGroupsClient(clientData.SubscriptionID)
    groupsClient.Authorizer = authorizer

        return groupsClient.CreateOrUpdate(
                ctx,
                resourceGroupName,
                resources.Group{
                        Location: to.StringPtr(resourceGroupLocation)})
}

Azure 서비스와의 일반적인 상호 작용 흐름은 다음과 같습니다.

  • 상호 작용하려는 리소스 종류가 있는 * 메서드를 service 사용하여 service.New*Client() 클라이언트를 만듭니다. 이 함수는 항상 구독 ID를 사용합니다.
  • 클라이언트에 대한 권한 부여 방법을 설정하여 원격 API와 상호 작용할 수 있도록 합니다.
  • 원격 API에 해당하는 클라이언트에서 메서드를 호출합니다. 서비스 클라이언트 메서드는 일반적으로 리소스의 이름과 메타데이터 개체를 사용합니다.

to.StringPtr 함수는 여기에서 형식 변환을 수행하는 데 사용됩니다. SDK 메서드에 대한 매개 변수는 거의 독점적으로 포인터를 사용하므로 형식 변환을 쉽게 하기 위해 편리한 메서드가 제공됩니다. 편리한 변환기의 전체 목록 및 동작을 보려면 autorest/to 모듈 설명서를 참조하십시오.

이 메서드는 groupsClient.CreateOrUpdate 리소스 그룹을 나타내는 데이터 형식에 대한 포인터를 반환합니다. 이러한 종류의 직접 반환 값은 동기적으로 수행되어야 하는 단기 실행 작업을 나타냅니다. 다음 섹션에서는 장기 실행 작업의 예와 상호 작용하는 방법을 확인할 수 있습니다.

배포 수행

리소스 그룹을 만든 다음에는 배포를 실행해야 합니다. 이 코드는 논리의 여러 부분을 강조하기 위해 더 작은 섹션으로 나뉩니다.

func createDeployment() (deployment resources.DeploymentExtended, err error) {
    template, err := readJSON(templateFile)
    if err != nil {
        return
    }
    params, err := readJSON(parametersFile)
    if err != nil {
        return
    }
    (*params)["vm_password"] = map[string]string{
        "value": clientData.VMPassword,
    }
        // ...

배포 파일은 여기서 건너뛰는 세부 정보를 통해 readJSON로드됩니다. 이 함수는 *map[string]interface{}리소스 배포 호출에 대한 메타데이터를 생성하는 데 사용되는 형식인 형식을 반환합니다. VM의 암호는 배포 매개 변수에서도 수동으로 설정됩니다.

        // ...

    deploymentsClient := resources.NewDeploymentsClient(clientData.SubscriptionID)
    deploymentsClient.Authorizer = authorizer

    deploymentFuture, err := deploymentsClient.CreateOrUpdate(
        ctx,
        resourceGroupName,
        deploymentName,
        resources.Deployment{
            Properties: &resources.DeploymentProperties{
                Template:   template,
                Parameters: params,
                Mode:       resources.Incremental,
            },
        },
    )
    if err != nil {
        return
    }

이 코드는 리소스 그룹을 만드는 것과 동일한 패턴을 따릅니다. 새로운 클라이언트가 생성되고 Azure에서 인증을 수행할 수 있는 기능이 제공된 다음, 메서드가 호출됩니다. 메서드는 리소스 그룹에 대한 해당 메서드와 동일한 이름(CreateOrUpdate)을 가집니다. 이 패턴은 SDK 전체에서 볼 수 있습니다. 비슷한 작업을 수행하는 메서드는 일반적으로 이름이 같습니다.

가장 큰 차이점은 메서드의 반환 값에 있습니다 deploymentsClient.CreateOrUpdate . 이 값은 미래 디자인 패턴을 따르는 미래 형식입니다. 미래는 Azure에서 완료 시 폴링, 취소 또는 차단할 수 있는 장기 실행 작업을 나타냅니다.

        //...
    err = deploymentFuture.Future.WaitForCompletion(ctx, deploymentsClient.BaseClient.Client)
    if err != nil {
        return
    }
    return deploymentFuture.Result(deploymentsClient)
}

이 예제에서 가장 좋은 방법은 작업이 완료되기를 기다리는 것입니다. 미래 개체를 기다리기 위해서는 컨텍스트 개체Future를 생성한 클라이언트가 모두 필요합니다. 여기에는 두 가지 가능한 오류 원본이 있습니다. 메서드를 호출하려고 할 때 클라이언트 쪽에서 발생한 오류와 서버의 오류 응답입니다. 후자는 호출의 일부로 반환됩니다 deploymentFuture.Result .

할당된 IP 주소 가져오기

새로 만든 VM을 사용하여 모든 작업을 수행하려면 할당된 IP 주소가 필요합니다. IP 주소는 NIC(네트워크 인터페이스 컨트롤러) 리소스에 바인딩된 고유의 개별 Azure 리소스입니다.

func getLogin() {
    params, err := readJSON(parametersFile)
    if err != nil {
        log.Fatalf("Unable to read parameters. Get login information with `az network public-ip list -g %s", resourceGroupName)
    }

    addressClient := network.NewPublicIPAddressesClient(clientData.SubscriptionID)
    addressClient.Authorizer = authorizer
    ipName := (*params)["publicIPAddresses_QuickstartVM_ip_name"].(map[string]interface{})
    ipAddress, err := addressClient.Get(ctx, resourceGroupName, ipName["value"].(string), "")
    if err != nil {
        log.Fatalf("Unable to get IP information. Try using `az network public-ip list -g %s", resourceGroupName)
    }

    vmUser := (*params)["vm_user"].(map[string]interface{})

    log.Printf("Log in with ssh: %s@%s, password: %s",
        vmUser["value"].(string),
        *ipAddress.PublicIPAddressPropertiesFormat.IPAddress,
        clientData.VMPassword)
}

이 메서드는 매개 변수 파일에 저장된 정보를 사용합니다. 코드는 VM을 직접 쿼리하여 NIC를 가져와 IP 리소스를 가져오는 NIC를 쿼리한 다음 IP 리소스를 직접 쿼리할 수 있습니다. 이는 해결해야 할 종속성 및 작업의 긴 체인으로, 비용이 많이 듭니다. JSON 정보는 로컬이기 때문에 대신 로드할 수 있습니다.

VM 사용자의 값도 JSON에서 로드됩니다. 이전에는 VM 암호가 인증 파일에서 로드되었습니다.

다음 단계

이 빠른 시작에서는 기존 템플릿을 가져와 Go를 통해 배포했습니다. 그런 다음 SSH를 통해 새로 만든 VM에 연결했습니다.

Go를 사용한 Azure 환경에서 가상 머신을 사용하는 방법에 대해 학습을 계속하려면 Go용 Azure 컴퓨팅 샘플 또는 Go용 Azure 리소스 관리 샘플을 참조하십시오.

SDK에서 사용 가능한 인증 방법 및 지원하는 인증 유형에 대한 자세한 내용은 Azure SDK for Go를 사용한 인증을 참조 하세요.