shuhelohelo’s blog

Xamarin.Forms多めです.

Azure Client SDKでリソースを作成する準備

docs.microsoft.com

Azureのリソースを作成する選択肢は,Azure Portal, Azure CLI, Azure PowerShell, Azure REST API, Azure Client SDKなど様々あり, 目的や状況に適したものを使うことができます.

ここではAzure Client SDKを使って,C#プログラムからAzureのリソースを作成するまでの手順をメモします.

具体的にはこちらです.

docs.microsoft.com

前提として,Azure CLIをインストールしておくこと.

SDKからAzureサブスクリプション内のリソースの読み取り,作成を行うアクセス許可を.NETアプリケーションに与える必要がある.

サービスプリンシパルを作成して,その資格情報でアクセスを許可するようにアプリを構成する.

  1. Azure Cloud Shellにログインする
  2. az account showを実行.以下の情報がJSON形式で得られる.
{
  "environmentName": "AzureCloud",
  "id": "15dbcfa8-4b93-4c9a-881c-6189d39f04d4",
  "isDefault": true,
  "name": "my-subscription",
  "state": "Enabled",
  "tenantId": "43413cc1-5886-4711-9804-8cfea3d1c3ee",
  "user": {
    "cloudShellID": true,
    "name": "jane@contoso.com",
    "type": "user"
  }
}
  1. az ad sp create-for-rbac --sdk-authを実行してサービスプリンシパルを作成する.

サービスプリンシパルとは以下のとおり。

サービス プリンシパル - 特定の Azure リソースにアクセスするためにアプリケーションまたはサービスによって使用されるセキュリティ ID です。 アプリケーションに対する "ユーザー ID" (ユーザー名とパスワード、または証明書) と考えることができます。

これは,Azure Active Directoryの範疇のようだ.

すると,以下のサービスプリンシパル情報がJSON形式で得られる.

{
  "clientId": "b52dd125-9272-4b21-9862-0be667bdf6dc",
  "clientSecret": "ebc6e170-72b2-4b6f-9de2-99410964d2d0",
  "subscriptionId": "ffa52f27-be12-4cad-b1ea-c2c241b6cceb",
  "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
  "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
  "resourceManagerEndpointUrl": "https://management.azure.com/",
  "activeDirectoryGraphResourceId": "https://graph.windows.net/",
  "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
  "galleryEndpointUrl": "https://gallery.azure.com/",
  "managementEndpointUrl": "https://management.core.windows.net/"
}

これをアプリケーションから利用する際は,userSecrets.json,に入れておき,安全を確保すると良い.

{
  "azure": {
    "credentials": {
      "clientId": "b52dd125-9272-4b21-9862-0be667bdf6dc",
      "clientSecret": "ebc6e170-72b2-4b6f-9de2-99410964d2d0",
      "subscriptionId": "ffa52f27-be12-4cad-b1ea-c2c241b6cceb",
      "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
      "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
      "resourceManagerEndpointUrl": "https://management.azure.com/",
      "activeDirectoryGraphResourceId": "https://graph.windows.net/",
      "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
      "galleryEndpointUrl": "https://gallery.azure.com/",
      "managementEndpointUrl": "https://management.core.windows.net/"
    }
  }
}

利用する際は以下のように.(参考)

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace AzureSDKPractice
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var confBuilder = new ConfigurationBuilder();
            var conf = confBuilder
                .AddUserSecrets<Program>(true)
                .Build();

            var clientId = conf["azure:credentials:clientId"];
            var clientSecret = conf["azure:credentials:clientSecret"];
            var tenantId = conf["azure:credentials:tenantId"];
            var subscriptionId = conf["azure:credentials:subscriptionId"];

....略

Virtual Networkの作成

サンプルにあるように作成する.

gist.github.com

            var creatableNetwork = azure.Networks
                            .Define("az-fluent-vnet")
                            .WithRegion(Region.UK_WEST)
                            .WithExistingResourceGroup("testing")
                            .WithAddressSpace("172.16.0.0/16");

OS Imageの確認の仕方

VMを作成する際には使用するOSのイメージを指定する必要がある. 指定に必要な情報はpublisher,"offer","sku"の3つの情報. これらはaz vm image listで確認でき,以下のJSON形式の情報が得られる.

[
  {
    "offer": "CentOS",
    "publisher": "OpenLogic",
    "sku": "7.5",
    "urn": "OpenLogic:CentOS:7.5:latest",
    "urnAlias": "CentOS",
    "version": "latest"
  },
  {
    "offer": "CoreOS",
    "publisher": "CoreOS",
    "sku": "Stable",
    "urn": "CoreOS:CoreOS:Stable:latest",
    "urnAlias": "CoreOS",
    "version": "latest"
  },
  {
    "offer": "debian-10",
    "publisher": "Debian",
    "sku": "10",
    "urn": "Debian:debian-10:10:latest",
    "urnAlias": "Debian",
    "version": "latest"
  },
  {
    "offer": "openSUSE-Leap",
    "publisher": "SUSE",
    "sku": "42.3",
    "urn": "SUSE:openSUSE-Leap:42.3:latest",
    "urnAlias": "openSUSE-Leap",
    "version": "latest"
  },
  {
    "offer": "RHEL",
    "publisher": "RedHat",
    "sku": "7-LVM",
    "urn": "RedHat:RHEL:7-LVM:latest",
    "urnAlias": "RHEL",
    "version": "latest"
  },
  {
    "offer": "SLES",
    "publisher": "SUSE",
    "sku": "15",
    "urn": "SUSE:SLES:15:latest",
    "urnAlias": "SLES",
    "version": "latest"
  },
  {
    "offer": "UbuntuServer",
    "publisher": "Canonical",
    "sku": "18.04-LTS",
    "urn": "Canonical:UbuntuServer:18.04-LTS:latest",
    "urnAlias": "UbuntuLTS",
    "version": "latest"
  },
  {
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2019-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest",
    "urnAlias": "Win2019Datacenter",
    "version": "latest"
  },
  {
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2016-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest",
    "urnAlias": "Win2016Datacenter",
    "version": "latest"
  },
  {
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2012-R2-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2012-R2-Datacenter:latest",
    "urnAlias": "Win2012R2Datacenter",
    "version": "latest"
  },
  {
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2012-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2012-Datacenter:latest",
    "urnAlias": "Win2012Datacenter",
    "version": "latest"
  },
  {
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2008-R2-SP1",
    "urn": "MicrosoftWindowsServer:WindowsServer:2008-R2-SP1:latest",
    "urnAlias": "Win2008R2SP1",
    "version": "latest"
  }
]

最終的に以下のコードで仮想マシンが作成される.

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var confBuilder = new ConfigurationBuilder();
            var conf = confBuilder
                .AddUserSecrets<Program>(true)
                .Build();

            var clientId = conf["azure:credentials:clientId"];
            var clientSecret = conf["azure:credentials:clientSecret"];
            var tenantId = conf["azure:credentials:tenantId"];
            var subscriptionId = conf["azure:credentials:subscriptionId"];

            var credentials = SdkContext.AzureCredentialsFactory
                .FromServicePrincipal(clientId, clientSecret, tenantId, AzureEnvironment.AzureGlobalCloud);
            var azure = Azure.Configure()
                .Authenticate(credentials)
                .WithSubscription(subscriptionId);//明示するのを推奨.


            var creatableNetwork = azure.Networks
                .Define("test-vm")
                .WithRegion(Region.JapanEast)
                .WithExistingResourceGroup("TestResourceGroup")
                .WithAddressSpace("172.16.0.0/16");

            var vmName = "test-vm";
            var rootId = conf["azure:vmRootInfo:rootId"];
            var rootPass = conf["azure:vmRootInfo:rootPassword"];

            azure.VirtualMachines
                .Define(vmName)
                .WithRegion(Region.JapanEast)
                .WithExistingResourceGroup("TestResourceGroup")
                .WithNewPrimaryNetwork(creatableNetwork)
                .WithPrimaryPrivateIPAddressDynamic()
                .WithoutPrimaryPublicIPAddress()
                .WithLatestLinuxImage("Canonical", "UbuntuServer", "18.04-LTS")
                .WithRootUsername(rootId)
                .WithRootPassword(rootPass)
                .WithComputerName(vmName)
                .WithSize(VirtualMachineSizeTypes.BasicA0)
                .Create();
        }

f:id:shuhelohelo:20200906171000p:plain

なるほど.

ソースコード

https://github.com/shuheydev/AzureSDKPractice