社内でAzureハンズオン教育を開催した件

みなさま、はじめして。
NECソリューションイノベータで「Azureソリューションセンター」という仮想組織のセンター長を今年度より就任し、当社のみならずNECグループのAzureビジネスを広げていくために日々を精励している櫻井と申します。

アドベントカレンダーに参加するため初投稿を行うのですが、どのようなことを書こうか考えた挙句、今後も投稿していくことも考え少しずつステップアップしていくようなのを書いていけば良いかなと云うことで、新入社員教育のカリキュラムの中で櫻井が講師を務めているクラウド領域のコンテンツに触れ、Azureスキルをどうステップアップしていけば良いかの一案を示そうと思います。

# 教育内容の構成
新入社員教育では基礎教育として、OSやネットワーク、AIなど様々なカリキュラムがあるようですが、そのうちのクラウド領域としてAzureを扱い、それのテキストの作成から講師まで担当しています。
大きく１．座学と、２．実際にAzureを触って構築を行うハンズオンになりますが、マイクロソフト社のドキュメントは非常に豊富で座学のためにテキストを作るまでもなく、[Microsoft Learn](https://learn.microsoft.com/ja-jp/training/browse/ "すべてのコース、ラーニング パス、モジュールを参照する - Training | Microsoft Learn")に沿ってレクチャーが行えるのでとても助かります。

が、やはり座学だけでは眠くなるし、Microsoft Learnの一部ではサンドボックスでAzureの操作はできるものの、机上では覚えづらいのでハンズオンは有効です。生徒も手を動かしているのは楽しいでしょうし。

全体の教育時間に依りますが、座学とハンズオンを織り交ぜると覚えた知識がすぐ実践できて生徒の集中力も続くのではないかと思います。(が、タイムスケジュールを作るのはタイヘンです)

# ハンズオンの内容
さて、具体的なハンズオンの内容ですが、「**Web/DB PaaS構築ハンズオン**」と称して、AzureのWebアプリのPaaSである"App Service"とDatabaseのPaaSである"SQL Database"によって下図のような環境構築を行い、アプリケーションをデプロイし動かす、というものです。
![qiita01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/d93129e1-a320-3a59-f15b-a895cffb2a0d.png)

具体的な手順や教育で使用したアプリケーションは割愛させて頂く点ご容赦いただきたいですが、ハンズオンの内容を考えていくに当たっては、やはり[Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/app-service/tutorial-dotnetcore-sqldb-app?tabs=copilot&pivots=azure-portal "ASP.NET Core および Azure SQL Database アプリを構築する - Azure App Service | Microsoft Learn")を参考に組み立てており、長くAzureに携わっている自分でも初めて触ってみるAzureサービスにおいてはクイックスタートやチュートリアルは今でも有用しています。

# Web/DB PaaS構築ハンズオンの流れ
実際に行ってきたハンズオンの流れと社内教育ならではのポイント、最後にTipsをお伝えできればと思います。
## 1.リソースグループと仮想ネットワークの作成、仮想マシンの作成
1クラス30人程度になりますが、1つのAzureテナントを占有して行います。
ですのでAzureサブスクリプションはクラスでシェアし、生徒それぞれがリソースグループや仮想ネットワークおよびサブネットを初めに作成します。
環境に依りますが、VPNゲートウェイやExpress Routeなど安全にAzureに接続できる準備があれば良いですが、なければAzure Bastionを仮想ネットワークの作成時に合わせて作っておくと良いと思います。
ただAzure Bastionを一緒に作成するとプラス5分程度、仮想ネットワークの作成完了時間が伸びると思うので、各工程の長時間化するタイミングを計っておき休憩などに充てると良いと思います。

## 2.SQL Databaseの作成と設定
SQL Databaseをデプロイし、アプリケーションが使うスキーマの設定を行っていきます。
SQL Databaseのモデルは用途により充実していますが、教育目的であるため既定値のHyperscaleよりもっと安価なものに選択し直していきます。
![qiita02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/a60e1f3d-d467-0934-e643-826975f72800.png)
またアプリケーションやコードを流すだけで、テーブルを作成できてしましますが、敢えてAzure Data Studioと云ったデータベースを操作するツールを使って、手動操作によってテーブルを作り列や主キーを設定します。
SQL Databaseの作成時のポイントとして、前述の構成図にもありますが初めからプライベートエンドポイントのみで作っておくことです。
我々が顧客に対してAzureのSI(システム開発)を行うに当たって、パブリックエンドポイントを使うケースはまずありません。誤った設定次第で誰もが接続できてしまう可能性のあるクラウドに対してセキュリティ意識を持ってもらいつつ、実際のSIの現場の設計をフィードバックしてハンズオンの手順に落とし込んでいます。

## 3.Webアプリの作成と設定
App Serviceをデプロイし、後はアプリケーションをリリースすれば動作できるように設定を行っていきます。
アプリケーションで必要な環境変数やデータベースへ接続するための接続文字列の設定を行います。
データベースをプライベートエンドポイント接続のみにしているため、VNET統合(App Serviceを特定の仮想ネットワークに接続する機能で、非公開セグメントに配置しセキュリティを担保し仮想ネットワーク内へプライベートアクセスができるようになる)を設定します。
![qiita03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/57321743-0a75-c56a-9714-38f4e3b37d34.png)

また既定でAppServiceは不特定多数のアクセスを受けられてしまうため、簡易認証(Easy Auth)によりMicrosoftのIDプロバイダーを設定することでEntra IDによる認証を設けてセキュリティリスクを下げています。

## 4.Webアプリの作成と設定
あとはVisual StudioやVisual Studio Codeからアプリケーションをリリースし、WebブラウザからのApp ServiceのURLにアクセス、設定不備がなく動作確認をするのみです。
とは云え、一定数はうまくアプリケーションが起動せずにエラー画面が表示される結果になってしまいます。
そのような場合でも、KuduのLog streamで出力内容を確認しエラーとなった原因を特定していきます。
~~~エラーログ例
2024-12-14T09:10:01.324907105Z: [INFO]  fail: Microsoft.EntityFrameworkCore.Update[10000]
2024-12-14T09:10:01.324911705Z: [INFO]        An exception occurred in the database while saving changes for context type 'DotNetCoreSqlDb.Data.MyDatabaseContext'.
2024-12-14T09:10:01.331197406Z: [INFO]        Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
2024-12-14T09:10:01.331208107Z: [INFO]         ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'ID', table ‘db-XXXXXXX.dbo.XXXX'; column does not allow nulls. INSERT fails.
~~~

## 5.更なる拡張
ハンズオンの進みが良かった場合に、いくつかの追加タスクを準備しておきます。
* キーコンテナー(Azure Key Vault)によるシークレット(データベースの接続文字列)の管理
* Cache for Redisによるキャッシュの有効化
* ロジックアプリによるデータベース書き込みトリガの通知　など

前項までに実施したシンプルでミニマムなWeb/DB構成からスタートし、少しずつAzureリソースを足していって機能を加えていって、より堅牢で可用性の高いシステムを作っていくとAzureに限らずクラウドのシステム開発に引き込まれていくのではないかと思います。

# ハンズオンを実施する上で気づいたTips

* **作成するリソースの命名規則を決めておく**
リソース名の重複などで引っかからないよう予め一意の名前になるよう決めておきます。細かいですが、苗字にしても生徒同士が同じ苗字と云うのもあるので参加者名簿があると良いです。1テナントでシェアする場合は、Entra IDへ事前に生徒を登録しAzureサブスクリプションの共同作成者を付与しておくとスムーズにハンズオンに入れるので、その点でも名簿が必要となります。

* **ネットワークセグメントを割り当てる**
生徒それぞれが作る仮想ネットワーク同士はピアリングをしませんが、不用意なメッセージで混乱させないよう、例えば第2オクテットの値を一人ひとりに割り振ることで重複しないアドレスレンジを使えるようにします。

* **クォータ引き上げを行う**
あとの手順で作成するデータベースなど数十アカウントが同タイミングで作成するため、利用するモデルと云った特定のクォータに引っかかるものがあれば、教育開催よりもっと前にクォータ引き上げの申請またはSRを行います。
同一テナント1リージョンあたりのApp Serviceプランの作成上限などもあるためワークアラウンドを考慮しておきます。

* **実施させたくない操作に対するガードレールを設定する**
ハンズオンの手順があっても手順にない操作を行ってしまうことがあるため、東日本リージョンにのみしか作成できない、仮想マシンのモデルを固定する、パブリックIPアドレスの付与を禁止する、などセキュリティリスクや想定外の利用料の発生を抑える目的でAzureポリシーを使ってガードレールを施します。

* **Azureを好きになってもらうためのサポート体制**
せっかくハンズオンを行ったのにアプリケーションが実行できず最後までたどり着けなかった結果として、Azure自体に対して嫌悪してしまうのは避けなければなりません。
その解として、人それぞれ進み方が違うので休憩時間を利用したキャッチアップや、困ったらすぐに有識者に対して聞くことができるフォロー体制の調整をしておきます。
今年の開催では講師の他に2人の先輩社員を各クラスのハンズオンで配置していたため、スムーズにハンズオンを行うことができ、ほとんどの生徒がゴールでき、サポーターがすごく付き合ってくれた、親身に教えてくれた、と云う感謝の声が返って来ました。

トレンドに合わせて新しいコンテンツを作りつつ多くのAzure技術者を育成していこうと思います。
とは云え櫻井は教育専門でなく、バリバリのSEなのですけれど。
最後までお読みいただきありがとうございました。