다음을 통해 공유


자습서: Go SDK를 사용하여 Azure 퍼블릭 MEC에 리소스 배포

이 자습서에서는 Go SDK를 사용하여 Azure 퍼블릭 MEC(멀티 액세스 에지 컴퓨팅)에서 리소스를 배포하는 방법을 알아봅니다. 이 자습서에서는 Azure 퍼블릭 MEC 솔루션에서 가상 머신 및 공용 IP 리소스를 배포하기 위해 Go로 작성된 코드 조각을 제공합니다. 동일한 모델 및 템플릿을 사용하여 Azure 퍼블릭 MEC에 대해 지원되는 다른 리소스 및 서비스를 배포할 수 있습니다. 이 글은 Go에 대한 자습서가 아닙니다. Azure 퍼블릭 MEC에서 리소스를 배포하는 데 필요한 API 호출에만 집중합니다.

Go에 대한 자세한 내용은 Azure for Go 개발자를 참조하세요. Go 샘플은 Azure Go SDK 샘플을 참조하세요.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • 가상 머신 만들기
  • 공용 IP 주소 만들기
  • 가상 네트워크 및 공용 IP 주소 배포

필수 조건

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

  • Azure 계정에 허용된 구독을 추가하면 Azure 퍼블릭 MEC에서 리소스를 배포할 수 있습니다. 활성 허용 구독이 없는 경우 Azure 퍼블릭 MEC 제품 팀에 문의하세요.

Go 설치

최신 버전의 Go를 다운로드하여 설치할 수 있습니다. 이는 사용자의 컴퓨터에 있는 기존 Go를 바꿉니다. 동일한 컴퓨터에 여러 Go 버전을 설치하려면 Go 설치 관리를 참조하세요.

인증

Azure 서비스를 사용하려면 먼저 인증을 가져와야 합니다. Azure CLI를 사용하여 로그인하거나 인증 환경 변수를 설정할 수 있습니다.

Azure CLI를 사용하여 로그인

명령줄에서 az login을 사용하여 기본 브라우저를 통해 Azure에 로그인할 수 있습니다. 자세한 지침은 Azure CLI로 로그인을 참조하세요.

환경 변수 설정

Azure에 인증하려면 다음 값이 필요합니다.

  • 구독 ID
  • 클라이언트 ID
  • 클라이언트 암호
  • 테넌트 ID

다음 지침에 따라 포털에서 이러한 값을 가져옵니다.

  • 구독 ID 가져오기

    1. Azure 계정에 로그인
    2. 왼쪽 사이드바에서 구독 선택
    3. 필요한 구독 선택
    4. 개요를 선택합니다
    5. 구독 ID 복사
  • 클라이언트 ID/클라이언트 암호/테넌트 ID 가져오기

    클라이언트 ID, 클라이언트 암호, 테넌트 ID를 가져오는 방법에 대한 자세한 내용은 리소스에 액세스할 수 있는 Microsoft Entra 애플리케이션 및 서비스 주체 만들기를 참조하세요.

  • 환경 변수 설정

    값을 가져오는 후에는 다음 값을 환경 변수로 설정해야 합니다.

    • AZURE_CLIENT_ID
    • AZURE_CLIENT_SECRET
    • AZURE_TENANT_ID
    • AZURE_SUBSCRIPTION_ID

    개발 시스템에서 다음 환경 변수를 설정하려면:

    Windows(관리자 액세스가 필요함)

    1. 제어판
    2. 시스템 보안>시스템을 선택합니다.
    3. 왼쪽에서 고급 시스템 설정을 선택합니다.
    4. 시스템 속성 창 내에서 Environment Variables… 단추를 선택합니다.
    5. 변경하려는 속성을 선택한 다음 편집…을 선택합니다. 속성 이름이 나열되지 않으면 새로 만들기…를 선택합니다.

    Linux 기반 OS:

        export AZURE_CLIENT_SECRET="__CLIENT_SECRET__"
        export AZURE_TENANT_ID="__TENANT_ID__"
        export AZURE_SUBSCRIPTION_ID="__SUBSCRIPTION_ID__"````
    
    

패키지 설치

새 SDK는 버전 관리 및 종속성 관리를 위해 Go 모듈을 사용합니다.

다음 명령을 실행하여 프로젝트 폴더 아래에 이 자습서의 패키지를 설치합니다.

go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5
go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3
go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources
go get github.com/Azure/azure-sdk-for-go/sdk/azcore
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

가상 머신 프로비저닝

package main

import (
	"context"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3"
	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
	"log"
	"os"
)

func main() {
	subscriptionId := os.Getenv("AZURE_SUBSCRIPTION_ID")

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		log.Fatalf("authentication failure: %+v", err)
	}

	// client factory
	resourcesClientFactory, err := armresources.NewClientFactory(subscriptionId, cred, nil)
	if err != nil {
		log.Fatalf("cannot create client factory: %+v", err)
	}

	computeClientFactory, err := armcompute.NewClientFactory(subscriptionId, cred, nil)
	if err != nil {
		log.Fatalf("cannot create client factory: %+v", err)
	}

	networkClientFactory, err := armnetwork.NewClientFactory(subscriptionId, cred, nil)
	if err != nil {
		log.Fatalf("cannot create client factory: %+v", err)
	}

	// Step 1: Provision a resource group
	_, err = resourcesClientFactory.NewResourceGroupsClient().CreateOrUpdate(
		context.Background(),
		"<resourceGroupName>",
		armresources.ResourceGroup{
			Location: to.Ptr("westus"),
		},
		nil,
	)
	if err != nil {
		log.Fatal("cannot create resources group:", err)
	}

	// Step 2: Provision a virtual network
	virtualNetworksClientCreateOrUpdateResponsePoller, err := networkClientFactory.NewVirtualNetworksClient().BeginCreateOrUpdate(
		context.Background(),
		"<resourceGroupName>",
		"<virtualNetworkName>",
		armnetwork.VirtualNetwork{
			Location: to.Ptr("westus"),
			ExtendedLocation: &armnetwork.ExtendedLocation{
				Name: to.Ptr("<edgezoneid>"),
				Type: to.Ptr(armnetwork.ExtendedLocationTypesEdgeZone),
			},
			Properties: &armnetwork.VirtualNetworkPropertiesFormat{
				AddressSpace: &armnetwork.AddressSpace{
					AddressPrefixes: []*string{
						to.Ptr("10.0.0.0/16"),
					},
				},
				Subnets: []*armnetwork.Subnet{
					{
						Name: to.Ptr("test-1"),
						Properties: &armnetwork.SubnetPropertiesFormat{
							AddressPrefix: to.Ptr("10.0.0.0/24"),
						},
					},
				},
			},
		},
		nil,
	)
	if err != nil {
		log.Fatal("network creation failed", err)
	}
	virtualNetworksClientCreateOrUpdateResponse, err := virtualNetworksClientCreateOrUpdateResponsePoller.PollUntilDone(context.Background(), nil)
	if err != nil {
		log.Fatal("cannot create virtual network:", err)
	}
	subnetID := *virtualNetworksClientCreateOrUpdateResponse.Properties.Subnets[0].ID

	// Step 3: Provision an IP address
	publicIPAddressesClientCreateOrUpdateResponsePoller, err := networkClientFactory.NewPublicIPAddressesClient().BeginCreateOrUpdate(
		context.Background(),
		"<resourceGroupName>",
		"<publicIPName>",
		armnetwork.PublicIPAddress{
			Name:     to.Ptr("<publicIPName>"),
			Location: to.Ptr("westus"),
			ExtendedLocation: &armnetwork.ExtendedLocation{
				Name: to.Ptr("<edgezoneid>"),
				Type: to.Ptr(armnetwork.ExtendedLocationTypesEdgeZone),
			},
			SKU: &armnetwork.PublicIPAddressSKU{
				Name: to.Ptr(armnetwork.PublicIPAddressSKUNameStandard),
			},
			Properties: &armnetwork.PublicIPAddressPropertiesFormat{
				PublicIPAllocationMethod: to.Ptr(armnetwork.IPAllocationMethodStatic),
			},
		},
		nil,
	)
	if err != nil {
		log.Fatal("public ip creation failed", err)
	}
	publicIPAddressesClientCreateOrUpdateResponse, err := publicIPAddressesClientCreateOrUpdateResponsePoller.PollUntilDone(context.Background(), nil)
	if err != nil {
		log.Fatal("cannot create public ip: ", err)
	}

	// Step 4: Provision the network interface client
	interfacesClientCreateOrUpdateResponsePoller, err := networkClientFactory.NewInterfacesClient().BeginCreateOrUpdate(
		context.Background(),
		"<resourceGroupName>",
		"<networkInterfaceName>",
		armnetwork.Interface{
			Location: to.Ptr("westus"),
			ExtendedLocation: &armnetwork.ExtendedLocation{
				Name: to.Ptr("<edgezoneid>"),
				Type: to.Ptr(armnetwork.ExtendedLocationTypesEdgeZone),
			},
			Properties: &armnetwork.InterfacePropertiesFormat{
				EnableAcceleratedNetworking: to.Ptr(true),
				IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
					{
						Name: to.Ptr("<ipConfigurationName>"),
						Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
							Subnet: &armnetwork.Subnet{
								ID: to.Ptr(subnetID),
							},
							PublicIPAddress: &armnetwork.PublicIPAddress{
								ID: publicIPAddressesClientCreateOrUpdateResponse.ID,
							},
						},
					},
				},
			},
		},
		nil,
	)
	if err != nil {
		log.Fatal("interface creation failed", err)
	}
	interfacesClientCreateOrUpdateResponse, err := interfacesClientCreateOrUpdateResponsePoller.PollUntilDone(context.Background(), nil)
	if err != nil {
		log.Fatal("cannot create interface:", err)
	}

	// Step 5: Provision the virtual machine
	virtualMachinesClientCreateOrUpdateResponsePoller, err := computeClientFactory.NewVirtualMachinesClient().BeginCreateOrUpdate(
		context.Background(),
		"<resourceGroupName>",
		"<vmName>",
		armcompute.VirtualMachine{
			Location: to.Ptr("westus"),
			ExtendedLocation: &armcompute.ExtendedLocation{
				Name: to.Ptr("<edgezoneid>"),
				Type: to.Ptr(armcompute.ExtendedLocationTypesEdgeZone),
			},
			Properties: &armcompute.VirtualMachineProperties{
				StorageProfile: &armcompute.StorageProfile{
					ImageReference: &armcompute.ImageReference{
						Publisher: to.Ptr("<publisher>"),
						Offer:     to.Ptr("<offer>"),
						SKU:       to.Ptr("<sku>"),
						Version:   to.Ptr("<version>"),
					},
				},
				HardwareProfile: &armcompute.HardwareProfile{
					VMSize: to.Ptr(armcompute.VirtualMachineSizeTypesStandardD2SV3),
				},
				OSProfile: &armcompute.OSProfile{
					ComputerName:  to.Ptr("<computerName>"),
					AdminUsername: to.Ptr("<adminUsername>"),
					AdminPassword: to.Ptr("<adminPassword>"),
				},
				NetworkProfile: &armcompute.NetworkProfile{
					NetworkInterfaces: []*armcompute.NetworkInterfaceReference{
						{
							ID: interfacesClientCreateOrUpdateResponse.ID,
							Properties: &armcompute.NetworkInterfaceReferenceProperties{
								Primary: to.Ptr(true),
							},
						},
					},
				},
			},
		},
		nil,
	)
	if err != nil {
		log.Fatal("virtual machine creation failed", err)
	}
	_, err = virtualMachinesClientCreateOrUpdateResponsePoller.PollUntilDone(context.Background(), nil)
	if err != nil {
		log.Fatal("cannot create virtual machine:", err)
	}
}

리소스 정리

이 자습서에서는 Go SDK를 사용하여 Azure 퍼블릭 MEC에서 VM을 만들었습니다. 나중에 이러한 리소스가 필요하지 않을 것으로 예상되는 경우 Azure Portal을 사용하여 만든 리소스 그룹을 삭제합니다.

다음 단계

Python SDK를 사용하여 Azure 퍼블릭 MEC에서 가상 머신을 배포하려면 다음 문서로 이동합니다.