Azure Powershell でAzureの課金情報をゲット(Billing API)

ついうっかり使いすぎて月末に泣かないように、日次で課金情報を取ろうと考えました。
自動で取得するとなるといちいちログインの必要のない、Azure REST API経由で取得します。

準備としてAzure Powershellをインストール。2015/11/23現在のバージョンは1.0.1となります。

memobog.azurewebsites.net

どうも1.0.0以上とそれ未満ではコマンドの仕様が違うらしく。
そもそもAzureのGUI管理インターフェイスはAzure管理ポータルとAzure Portal(Perview)の平行運用が続いており、Powershellもそれに合わせてSwitch-AzureModeでどちらのGUIに合わせた操作をするか選択する仕様だった。が、いちいちモードチェンジが必要なのが不評だったらしく、1.0.0からはSwitch-AzureModeは廃止、Azure Portalを操作するコマンドがAzure-RMなんちゃら~と着くようになったらしい。

statemachine.hatenablog.com

課金情報をゲット

結論から言うと、以下のページのコードが非常に使いやすく、コピペコピペでいけてしまう。

yomon.hatenablog.com

自分用に忘れそうな所だけをメモ。

キモとなるのは、認証用ヘッダーの作成と、アクセス先URLの作成。

$requestHeader = @{"Authorization" = $authHeader}
$usageUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$reportedStartTime&reportedEndTime=$reportedEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"

認証用ヘッダー

# REST API実行用パラメータ設定
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Well-known client ID for Azure PowerShell
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Redirect URI for Azure PowerShell
$resourceAppIdURI = "https://management.core.windows.net/" # Resource URI for REST API
$authority = "https://login.windows.net/$adTenant" # Azure AD Tenant Authority
(中略)
# Create Authentication Context tied to Azure AD Tenant
$authContext = New-Object -TypeName "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext"  -ArgumentList $authority
# Acquire Azure AD token
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
# Create Authorization Header
$authHeader = $authResult.CreateAuthorizationHeader()
  • $clientId
  • $redirectUri
  • $resourceAppIdURI

は固定値です。

RESTと言えばGUIから管理画面にログインして秘密鍵っぽい文字列を取得しスクリプトに埋め込む…というやつであるが、Azure REST APIの場合、テナントIDが秘密鍵的存在になるっぽい。なので「俺のテナントID、○○なんだよね~」って言いふらしてはダメです。

テナントIDは以下のコードで取得可能。

$adTenant = (Get-AzureSubscription -SubscriptionId $subscriptionId).TenantId

なのでテナントIDさえ取得しちゃえばコードは固定できる。アクセストークンの期限は1時間(だった?)なので、トークンだけは毎回取り直した方がよいです。

※ これ、サブスクリプションの管理者が複数いる場合、テナントIDは全員で共通なのかな…。一人がヘマしたら全員のリスクなんだが…。さすがに考えられてるとは思うが(僕のやり方がリスクあるだけかも)

アクセス先URL

$usageUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$reportedStartTime&reportedEndTime=$reportedEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"

ここには

  • $subscriptionId
  • $apiVersion

を指定すればよい。
$subscriptionIdはadd-azureaccount後、Get-AzureSubscriptionすれば出てくるし、$apiVersionは”2015-06-01-preview”で固定なので問題なし。

まとめ

上記理解の元、コードをコピペコピペで発行すれば大丈夫。種別の絞り込みとかはpowershellの元々の知識を生かしてがんばる。

気になった点として、個人アカウントで仮想マシンが1つもないサブスクリプションだと「課金レポートを作ってるから5分ほど待ってくれ」って202が返ってきたことかな…。これは仮想マシンがないからそうなるのか、単純に個人のアカウントだから動作が違うのか、そこまでは調べてません。

システム構築時のホスト名の命名方法について

一時期検討したのでメモ。

議題

自由にネーミングルールを決定できる場合、以下の用に名前付けすると効率がよいと思われる。

[システム名][サイト名][サブシステム名][役割][連番]

例:TEMSDB001

TE システム名(TESTシステム)
M/Sサイト名(Mail/Sub)
S ミドルウェア名(SQL)
DB 役割(DBサーバー)
001 連番

検討ポイント

  • 名前を正規化し、スクリプト等で扱いやすくする
  • アルファベット順で並び替えた際、構築対象サーバーがひとまとまりになるようにする
  • 人間がそれなりに呼びやすい名前とする

以下、その他検討したケースとダメな理由をメモ。

まず、どのような要素を”名前”に含めるかどうか。趣味のサーバーでなければ、分かりやすく管理しやすい名前がよい。

(星座の名前とか競走馬の名前は研究室のサーバーで十分)

必須要素

  • サーバーの役割
    • さすがに必須である
  • 連番
    • 同一役割のサーバーを複数台構築するのがほとんどなので必須。
  • システム名
    • エンタープライズシステムの場合、他部署が管理しているシステムと区別するために必要
  • ロケーション名
    • 一昔前なら不要だが、サーバーのサイトを分けて構築するケースが増えてきたので必要と思われる。
  • ミドルウェア
    -サーバー台数が多い場合、システム名+役割+連番では上手く命名できない事が多いので、含めておくと後で助かる場合がある

不要要素

  • OSバージョン
    • 一度構築したサーバーのOSをアップデートして使用するケースは少ないが、サーバーに付与しても何の情報にもならない
  • 製品名
    • 吸収合併の多いIT業界で製品名を付けると、何年後にはサーバー名と製品名称が不一致になっている可能性がある。
      • 悪い例:VERITAS Backup Execなので”V” → Symantec Backup Execになっちゃった…。
      • 良い例:役割がBackupなので”B”
  • プロジェクト名
    • つけがちだが、数年後にサーバー増設プロジェクトが発生した場合、同じ役割のサーバーの命名ルールが分断される。

要素の命名順番

サーバー名をアルファベット順に並び替えた時にどうなるかに着目すると、システム名を一番最初に持ってくるのが良いと思われる。良くあるのがサイト名を最初に持ってくるシステムだが、こうするとGUIでアルファベット順に並び替えた時に同じシステムの同役割のサーバーが分断されてしまい、作業ミスが発生しやすくなる。全部CUIでやるからいい、という人もいるかもしれないが、月次レポートなどでExcelでデータ出力する際に、同じ役割のサーバーが別々で表示されるのでストレスがたまると思う。

プロジェクト終了時の振り返りについて

プロジェクト終了時の振り返りは絶対にやるべきであり、かつ他の改善取り組みに比べて意識的に促進するメリットが大きいと考えます。

プロジェクト振り返りをやるべき理由

  • 3,4か月~半年間の時間をかけて取り組んだ仕事なら、いろいろな経験を得ているはず。
  • その経験の人は忘れます。
  • なので、文章として記録しておく

愚者は経験に学び賢者は歴史に学ぶ、と言いますが、経験から学んじゃダメというのではない。むしろダイレクトに自分の血肉となるので整理して吸収すべき。

プロジェクト振り返りを促進するメリットが大きい理由

  • 他の業務改善案と違い、放っておくと誰もやらないから

例えば、提案活動効率化や構築作業のミス防止などは直接的に業績に影響するので、公式な施策として実施されやすい。一方振り返りを促進してもすぐにメリットが出るわけではないし、出たとしてもメリットが見えにくい。だからこそやる意味があり、やることで0を10や100に出来る。

振り返りの進め方(僕の場合)

プロジェクトが終了した時点でプロジェクト全体の振り返りをする場合。

  • 振り返りシートを用意し、プロジェクトのフェーズ毎に振り返りを行ってもらう
    • プロジェクト終わったタイミングでは直近のフェーズしか覚えていないため
  • フェーズ毎に、良かったこと・悪かったこと・続けたい事を書いてもらう。
  • プロジェクトのイベントやマイルストーンを記載したカレンダーを渡す
    • プロジェクト前半を思い出してもらうきっかけとして
    • このカレンダーには印象深いと思われる事柄は何でも記載する
      • 例:歓迎飲み、他チームのトラブルに巻き込まれる、など

あくまで僕のやり方です。ただ、プロジェクトのカレンダーなどを提示し、思い出す手助けをする必要はあると思います。

忙しければ振り返りシートを書かなくても大丈夫、と伝えています。シートに落とさなくても振り返り会の時に思い出せればそれでいいからです。ただ、シートに書くことで事前に思い出してもらうことができるので、今後どうするかは悩み中です。振り返り、という文化が定着してくれば強制もしやすいのだけど。

振り返り中

コーヒー飲みながら思い出話をするような進め方をしてます。あんなこともあったよね~こうすればよかったね~、みたいな。

振り返り後

  • 振り返り会で出た意見を必ず何かのドキュメントに纏め「結論」として提示する
    • 後から見返す場合、分かりやすい結論がまとまっていた方が見やすい

これが一番重要で、振り返り主催者は振り返り会をやった事で”終わり”と思いがちですが、参加者に「次も振り返り会をやろう」と思ってもらうためには、振り返り会はメリットがあるんだ、と感じてもらわなければいけない。振り返り会でプロジェクトの記憶も蘇っていい点・悪い点を洗い出せたとして、数年後に見返したときに”結局、次はどうすればよかったんだっけ?”となります。

「結論」では必ずしも白黒つけなくていいです。振り返りで意見が分かれた場合、「結論」には”次も大きな問題となる可能性があるため、事前に議論しておく”とかでもいいと思います。とにかく生の振り返りシートだけで結論付けたと思わない。必ず別のシートを作成する。