2026年3月29日日曜日

Azure DevOpsの無料枠「5人の壁」とは?知人のリーダーが悩んでいたコストと権限の話

 


1. 導入(設定の提示)

先日、別会社でチームリーダーをしている知人のエンジニアから相談を受けました。

『Azure DevOpsを使ってReposでソース管理を始めようとしたら、インフラ担当から開発メンバーは5人まで、管理者は1人という制限を言い渡された。これってAzureの仕様なの?それともうちの会社のケチなルール?』

という内容です。

2. 「5人制限」の正体は、Azure DevOpsのBasicプラン

結論から言うと、これは会社のケチなルールではなく、Azure DevOpsの標準的なライセンス仕様(Basicプラン)によるものです。

• 5人まで: Basicユーザーは5人まで無料。

• 6人目から: 月額料金(約$6〜/人)が発生。

知人のチームも、最初は『無料の範囲内でスモールスタートしたい』というインフラ側の意向があったようです。

こちらに詳しく書かられていました。

Azure DevOps の料金


3. 「管理者は1人」という運用の背景

さらに彼を悩ませていたのが『管理者は1人』という制約。

これはシステム上の制限というより、ガバナンス(統制)の側面が強いとアドバイスしました。

• Organization Ownerは1人。

• マスターへのマージやデプロイ権限を絞ることで、事故を防ぐ運用。

• ただし、リーダーとしてコード管理をスムーズにしたいなら、権限(Project Administratorsなど)を適切に切り分けてもらう交渉が必要かもしれません。

4. 解決策として提示したアドバイス

相談に来た彼には、以下の3つのチェックポイントを伝えました。

1. Stakeholder(ステークホルダー)の活用: コードを見ないメンバー(進捗確認のみのPMなど)は、無料枠の5人にカウントされず無制限に招待できる。

2. Visual Studio サブスクリプションの確認: もし既にVSのライセンスを持っていれば、その人は5人の枠を使わずにBasic機能が使える。

3. 役割の明確化: 誰がマージ権限を持ち、誰がリリースを承認するか。人数を増やす前に、この『交通整理』をインフラチームと握っておくことが重要。

5. まとめ

クラウドサービスは便利ですが、こうした『人数の壁』が突然現れます。

実体験(相談)を通じて感じたのは、開発効率とライセンス費用のバランスを、リーダーがいかに把握しておくかという大切さでした。


2026年3月22日日曜日

【Azure】Azure App ServiceやDBを夜間停止してコスト削減!Azure AutomationとPython SDKで自動化する方法


 個人開発や検証環境でAzureを使っていると、気になるのが「コスト」ですよね。

特に Application Gateway (Agw) や App Service、PostgreSQL は、動かしっぱなしにすると地味に費用が嵩みます。

これまでは「使う時だけポータルから手動で起動・停止」していましたが、ついつい消し忘れて翌朝絶望することも…。そこで、Azure Automation を使って、これらをスマートに自動管理する仕組みを調べて実装してみました。

1. なぜ「手動」から「自動化」へ?

手動運用の課題は、単に「面倒」なだけではありません。

• 消し忘れリスク: 24時間稼働による無駄な課金。

• 依存関係の複雑さ: App Serviceだけ起動しても、Agwが止まっているとサイトにアクセスできないといった「起動順序」のミス。

• デプロイ時の手間: 開発のたびにポータルを開くスイッチ作業のロス。

これらを解決するのが Azure Automation です。

2. Azure Automationによる自動化の仕組み

今回採用したのは、Azure Automationの 「Runbook」 機能です。

PythonのSDKを使用して、複数のリソースを一括でコントロールします。

構成のポイント

• Managed Identity: Automationアカウントに権限を付与し、パスワードレスで操作。

• Automation 変数: サブスクリプションIDやリソースグループ名をコードに直書きせず、変数として管理。

3. 【実践】Python SDKでリソースを制御するコード

実際のコードの肝となる部分を解説します。

GetAutomationVariable を使い、動的にリソースを特定して操作する流れです。



# イメージとしてのコード例

from azure.mgmt.web import WebSiteManagementClient

from azure.mgmt.rdbms.postgresql_flexibleservers import PostgreSQLManagementClient

# (中略) 認証処理など


# Automation変数から情報を取得

rg_name = get_automation_variable("ResourceGroupName")


# App Serviceの起動例

for app in web_client.web_apps.list_by_resource_group(rg_name):

    if app.name == "対象のサービス名":

        web_client.web_apps.start(rg_name, app.name)

        print(f"{app.name} を起動しました。")



このように、xxxManagementClient を使って、リソースを探索し、start() や stop() を呼び出すだけでOKです。


4. ハマったポイント:サイトにアクセスできない!?

自動化を実装した際、App ServiceとDBを起動したのに「このサイトにアクセスできません」となることがありました。原因は Application Gateway (Agw)。

Agwはポータルに停止ボタンがないため見落としがちですが、SDK経由で停止されている場合、ここも明示的に start させる必要があります。



5. まとめと今後の展望

Azure Automationを設定すれば、スケジュール機能(Schedule)を使って「平日の夜間だけ止める」といった運用が数クリックで実現します。

• メリット: 確実なコスト削減と、ポータル操作からの解放。

• 次の一歩: 今後は「デプロイ時だけ一時的に起動し、終わったら自動で閉じる」といったGitHub Actionsとの連携も試してみたいと思います。


2026年3月8日日曜日

【2026年最新】AZ-900合格体験記!Udemyの的中率は?初見問題3割を突破した最短攻略法

 


■ はじめに

本日、Microsoft Azure Fundamentals(AZ-900)に無事合格しました!




実務でAzureに触れる機会が増えたため受験しましたが、効率的な学習のおかげで短期間でパスすることができました。今回は私が活用した教材と、本番で焦らないための対策を共有します。

■ 使用した教材:Udemy「これだけで合格!AZ-900 模擬試験問題集」

私が活用したのは、Udemyの人気講座です。

講座リンク

この問題集のおかげで、基本的な知識の土台を固めることができました。特におすすめしたいポイントは以下の2点です。

1. 更新日時が新しく、2026年最新版に対応

Azureはアップデートが激しいですが、この講座は2026年1月更新と非常に新しいため、安心して取り組めました。

2. 「高度な模擬試験」が2回分付いている

基本レベルだけでなく、少しひねった「高度な模擬試験」が2回分含まれています。これが本番の「初見問題」への対応力を養ってくれました。

■ 本番のリアル:3割は見たことのない問題!?

正直に言うと、模擬試験を完璧にしても、本番では約3割ほど「見たことがない問題」が出て焦りました。

しかし、この問題集の解説を読み込み、「なぜこれが正解なのか」「似たサービスとの境界線はどこか」という本質を理解していたため、消去法や論理的思考で正解を導き出すことができました。

■ 私が実践した「直前仕上げ」のコツ

試験直前、完成度を一気に高めたのはこの方法です。

「模擬試験で間違えた問題だけを、繰り返し見直す」

正解した問題に時間をかけず、不正解だった選択肢の「なぜ間違えたか」の解説を読み込む。これを徹底することで、自分の弱点を完全に潰した状態で本番に挑めました。

■ まとめ

AZ-900は、しっかりとした土台があれば怖くありません。これから受験される方は、ぜひ最新の情報を反映したこのUdemy教材を活用してみてください!

【最短合格を狙うならこちら





2026年3月5日木曜日

Azure DevOps障害に翻弄された月曜日

 



■ はじめに

知り合い数人と進めている共同開発プロジェクト。3月に入った途端、メンバーの一人から「Gitのpushで認証エラーが出るようになった」と連絡が。

「あぁ、またPAT(アクセストークン)の期限切れか、月替わりの認証情報の更新かな」なんて、この時はまだ高を括っていた。

■ 迷走の始まり:自分だけ「成功」するという罠

まずは状況の切り分け。

「こっちでは普通にpullもpushもできるよ」

この一言が、原因特定を遅らせる最大のフラグになった。

自分ができる以上、プロジェクトの設定やAzure側の障害ではないはず。メンバーのローカル環境の問題だと断定し、以下の指示を飛ばした。

• 資格情報マネージャーの古い情報を消してみて

• git config --global credential.useHttpPath true を試して

• ブラウザのキャッシュをクリアして……

しかし、返ってくるのは「全部ダメだった」という絶望のレスポンス。

■ エラーメッセージとの格闘

送られてきた画面には、無慈悲なメッセージ。

TF10216: Azure DevOps services are currently unavailable.

Activity Id: 35b9da34...

Activity IDまで出ているのに、Azure DevOpsのStatus Portal(稼働状況)は「All Green」。アジアリージョンも正常。

「Activity IDまで出てるんだから、そっち(Azure)のせいだろう」と思いつつも、公式が「正常」と言い張る以上、こちら側の設定(認証ポリシーの変更など)を疑わざるを得ない。

■ 衝撃の結末

数時間が経過し、再度Status Portalをリロードしてみると……。

さっきまで鮮やかな緑色だった「Asia」のアイコンが、真っ赤な「Unhealthy」に変わっていた。

結局、Microsoft側の認証基盤の障害。

私がpushできていたのは、たまたま認証セッションが有効なサーバーに繋がっていたか、キャッシュが生きていただけだった。時間が経てば、いずれ私の環境でもエラーが出ていたはず。

■ 今回の教訓:ステータスサイトは「後出しジャンケン」

今回の件で学んだ教訓は3つ。

1. 「自分だけ動く」は環境が正常な証拠にはならない。(運がいいだけの場合がある)

2. 公式ステータスの「All Green」は、リアルタイムとは限らない。(反映にラグがある)

3. Activity IDが出たら、それはもう自分たちの範疇を超えている。

特に月替わりのタイミングは「自分のミス」を疑いがちだが、メンバー全員で一斉に起きた時は、公式ステータスが緑でも「コーヒーを飲んで1時間待つ」のが、精神衛生上もっとも正しいエンジニアの振る舞いかもしれない。

締めの一言

「Activity IDを必死にググっていたあの時間を返してほしい……(笑)」

2026年3月2日月曜日

Azure Database for PostgreSQLで突然の504。ログから遅延SQLを特定して改善するまで



 はじめに


自習環境でPDF出力機能を検証していたときのことです。

ある日、突然処理が終わらなくなりました。


しばらく待っていると、画面には 504 Gateway Timeout。


「メモリが足りないのか?」


最初はそう思いました。


メモリを疑う


Azure App Service のメトリクスを確認。

メモリ使用率はおよそ45%。


上限に張り付いているわけではありません。


念のため、コンテナ内でも確認しました。


cat /sys/fs/cgroup/memory/memory.limit_in_bytes


表示された値は、実質無制限に近い数字。


少なくとも、メモリ制限で落ちているわけではなさそうでした。


ではなぜ504が出るのか。


「タイムアウトかもしれない」


処理時間を見直す


ログを丁寧に追っていくと、リクエストが300秒以上かかっていることが分かりました。


これなら504になってもおかしくありません。


問題はメモリではなく、単純に「遅い」ということでした。


SQLを疑う


PDF出力処理では、データを取得してループしながら帳票を組み立てています。


もしかして、特定のSQLが遅いのでは?


そう思ってAzure Database for PostgreSQLを確認しました。


しかし、Query Storeは無効。


さらにサーバーパラメータを見ると、


log_min_duration_statement = -1


遅いSQLは一切ログに出力されていませんでした。


見えないものは、直せない。


まずは可視化から


log_min_duration_statement を 1000 に変更しました。


これで1秒以上かかったSQLがログに出ます。


その状態で、問題のPDF出力をもう一度実行。


Azureポータルのログを開き、息を詰めて確認しました。


出てきました。


duration: xxxx ms


同じSELECT文が何度も並んでいます。


そして、1回あたりも決して軽くない。


ようやく、ボトルネックが見えました。


インデックス不足


検索条件に使っているいくつかの列があります。


しかし、それらをまとめてカバーするインデックスはありませんでした。


複合インデックスを追加しました。


ロック影響を避けるため CONCURRENTLY を使用。


そして再度実行。


結果は


約10秒 → 約2秒。


はっきり分かる改善でした。


学び


今回の一件で感じたことがあります。


最初にメモリを疑ったのは、完全に思い込みでした。


504が出ると「リソース不足」と考えてしまう。

でも実際は、単純なインデックス不足。


そして何より大きかったのは、


推測ではなく、ログで確認したこと。


log_min_duration_statement が -1 のままだと、何も見えません。


見えないまま議論しても前に進みません。


まずは可視化。


そこからボトルネックを特定し、最小限の対処をする。


遠回りに見えて、それが一番早いと感じました。


おわりに


今回の問題はインデックスで改善しました。


ただし、ループ内でのクエリ実行は構造的な負荷を生みやすい部分でもあります。

N+1の可能性も含め、設計レベルでの見直しも今後の課題です。


それでも、504の正体を一つずつ剥がしていく過程は、とても良い学びになりました。


エラーの裏には、必ず理由がある。

焦らず、数字を見て、順番に潰す。


改めてその大切さを実感した出来事でした。