LoginSignup
0
0

More than 3 years have passed since last update.

Azure Stack Hub でおれおれ Web App を作る

Last updated at Posted at 2021-02-15

はじめに

2020年10月現在、Azure Stack Hub 上の App Service は、ASP.NET (.NET Framework / Core), PHP, Java, クラシックASP に対応しています。

参考:App Service on Azure Stack Hub 2020 Q3 のリリース ノート

App Service 自体は Microsoft が Azure Stack Hub のリソースプロバイダとして提供する「ソフトウェア」です。App Service を動かす IaaS レイヤーの管理は、Azure Stack Hub Operator の役割です。折角そこを管理している(管理する必要がある)のだから、好きなプラットフォームを追加して、おれおれ App Service を作りたくなるのが人情というものです。

環境

この記事は以下の環境でのものです。

  • Azure Stack Hub 1910
  • App Service Update 7 (84.0.2.10)

これと異なる環境では同じようにならない可能性が、大いにあります。

App Service の IaaS レイヤー

App Service の裏側は以下のようなリソースで構成されています。
image.png
https://blog.aimless.jp/archives/2019-03-05-install-appservice-resource-provider-to-azurestack より引用(Azure Stack Hub 上の App Service 構築については、こちらが大変参考になります)

このうち、Worker Tier が実際に Web アプリケーションをホストする役割を担っており、仮想マシンスケールセット (VMSS) で構成されています。

通常の Worker Tier 作成

Worker Tier の作成自体は、管理者用の Web ポータルから普通に出来ます。
image.png

ただし、使用するイメージは「2016-Datacenter」以外には選択出来ません。

この時点で真っ当なやり方では難しそうです。
しかしながら、Worker Tier の実体が VMSS である事が判っています。VMSS は任意の仮想マシンイメージから作成する事が出来る事から、この VMSS を弄ってみます。

手順

一旦「2016-Datacenter」で Worker Tier を作成してから、VMSS のイメージを変更します。

手順としては以下のようになります。

  1. カスタムイメージの作成
  2. 「2016-Datacenter」で Worker Tier を作成
  3. WorkerTierVmss のイメージを変更
  4. VMSS インスタンスの追加と PricingTier の作成

カスタムイメージの作成

Azure Stack Hub 管理者として、2016-Datacenter で仮想マシンを作成します。
通常のカスタムイメージ作成手順と変わりありません。イメージを登録する際に OS ディスクの Blob URI が必要なので、マネージドディスクを使わない方が楽だと思います。

参考:Azure Stack Hub に対してカスタム VM イメージを追加または削除する

image.png

イメージを登録する際は以下を指定します。

項目
Publisher MicrosoftWindowsServer
Offer WindowsServer
Sku 任意
Version 任意
Blob URI カスタムイメージ用 OS ディスクのURL

注意すべきは Publisher と Offer です。
VMSS を更新する際にはこれらを変更する事は出来ないので、「2016-Datacenter」と同じものにする必要があります。

また、仮想ディスクが格納されている Blob コンテナを読取アクセス可能にしておく事も忘れないでください。
image.png

ステータスが「Succeeded」になればイメージは完成です。
image.png

プラットフォームやミドルウェアには、今回は以下をインストールしておきます。この辺のチョイスはただの趣味です。

  • ASP.NET 5
  • Go
  • Oracle Data Provider for .NET 11.2.0.3

Worker Tier の作成

管理者ポータルから「2016-Datacenter」の Worker Tier を作成します。
image.png

当たり前に作られます。
2020-12-14_19h14_20.png

App Service のリソースグループ内には VMSS が作られている事も確認できます。
image.png

VMSS の変更

管理者用の Powershell モジュールを利用して、VMSS を変更します。

$vmss = Get-AzureRmVmss -ResourceGroupName appservice.local -VMScaleSetName CustomWorkerTierScaleSet
$vmss.VirtualMachineProfile.StorageProfile.ImageReference.Sku = "2016-Custom"
$vmss.VirtualMachineProfile.StorageProfile.ImageReference.Version = "0.0.1"
Update-AzureRmVmss -ResourceGroupName appservice.local -VMScaleSetName CustomWorkerTierScaleSet -VirtualMachineScaleSet $vmss

OS イメージの Sku に上で作成したカスタムイメージ(必要に応じて Version も)を指定して、Update-AzureRmVmss で更新します。
更新が終了すると、App Service の Worker Tier ブレードでも image が変更されている事が確認できます。
image.png

VMSS インスタンスの追加と PricingTier の作成

あとは普通に VMSS のインスタンスと App Service の Sku を作成して、ユーザーテナントで利用出来るようにします。

VMSS インスタンスを作成。
image.png

カスタム Worker Tier を指定して Sku を作成。
image.png

Sku を作成すると Pricing Tier が作られます。
image.png

これで準備が整いました。

Web App の作成

ユーザーテナントで Web App を作成します。
App Service Plan を作成する際にカスタムワーカーの Pricing Tier を選択します。
image.png

カスタムワーカーの App Service Plan と Web App が作成されます。
image.png

動作確認

ASP.NET 5

ASP.NET MVC アプリをデプロイして実行します。
Environment.VersionEnvironment.MachineName の値を表示してみます。

index.cshtml
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <div>
        .NET Version: @Environment.Version
    </div>
    <div>
        Machine Name: @Environment.MachineName
    </div>
</div>
AspNet5Mvc.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>

image.png

.NET 5 のランタイムで動作している事が分かります。

ちなみに、通常の Web App にデプロイするとちゃんとこけます。
image.png

Go

以下の記事で紹介されているコードをそのままお借りして動かします。
Azure Web サイトで Go 言語を httpPlatformHandler を使って動かしてみた - しばやん雑記

server.go
package main

import (
  "fmt"
  "net/http"
  "os"
  "runtime"
)

func viewHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hello, World, " + runtime.Version())
}

func main() {
  http.HandleFunc("/", viewHandler)
  http.ListenAndServe(":" + os.Getenv("HTTP_PLATFORM_PORT"), nil)
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpPlatformHandlerMain" modules="httpPlatformHandler" path="*" verb="*" resourceType="Unspecified" />
    </handlers>
    <httpPlatform processPath="C:\Go\bin\go.exe" arguments="run C:\home\site\wwwroot\server.go" startupTimeLimit="60" startupRetryCount="5" />
  </system.webServer>
</configuration>

image.png

動きました!

ちなみに、HttpPlatformHandler は Worker Tier 構築時にインストールされます。
image.png

.NET Framework 2.0 + ODP.NET アンマネージドドライバー

つまりレガシーなアプリケーションです。

WebForm1.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="dotnetfw2ora.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            Runtime Version: <asp:Label runat="server" ID="lblRuntimeVersion" />
        </div>
        <div>
            Oracle Client: <asp:Label runat="server" ID="lblOracleVersion" />
        </div>
        <div>
            <asp:GridView runat="server" ID="grdData" />
        </div>
    </form>
</body>
</html>
WebForm1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    lblRuntimeVersion.Text = Assembly.GetExecutingAssembly().ImageRuntimeVersion;

    var connStr = ConfigurationManager.AppSettings["ConnectionString"];
    var query = "select * from all_tables where owner='SYS'";
    var conn = new OracleConnection(connStr);
    var adapter = new OracleDataAdapter(query, conn);
    var ds = new DataSet();
    adapter.Fill(ds);

    lblOracleVersion.Text = Assembly.GetAssembly(conn.GetType()).FullName;
    grdData.DataSource = ds;
    grdData.DataMember = ds.Tables[0].TableName;

    this.DataBind();
}

image.png

ODP.NET のランタイムが読み込まれ、Oracle データベースでのクエリの実行にも成功しました。

カスタム Worker Tier 削除時の注意

カスタム Worker Tier を削除する場合は、VMSS イメージを「2016-Datacenter」に戻してから削除します。こうしないと VMSS だけが削除され、Worker Tier は残ったままになります。

詳しくはこちらを。

おわりに

かなり強引ではありますが、独自のプラットフォームに対応させた Web App を作る事に成功しました。

最新のプラットフォームでの開発環境などには使えるのではないでしょうか。
また、PaaS 化など望めないようなレガシーな Web アプリケーションであっても、アプリ自体に手を入れる事なく、スケーリングやデプロイスロットといった Web App の恩恵を受ける事が出来るのは大きなメリットだと思います。

まともな方法でサポートされる事を期待したいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0