Microsoftアカウントと組織アカウントの違いについて

MSのアカウント管理はややこしいなーと思うのでメモです。

AzureやらOffice365やらを使う時に「あなたのアカウントはMicrosoftアカウントですか?それとも組織アカウントですか?」と聞かれる。

Microsoftアカウントとは?

一般市民がGmailYahoo!メールで登録できる、普通のアカウント。私的なアカウントというか。Googleで言うと、そのまんま"アカウント"となる。

組織アカウントとは?

Microsoftクラウドサービスを利用している会社が発行するメールアドレスで、登録したアカウント。

例えば、株式会社TESTがOffice365を使用するとして、xxx@test.comというドメインでOffice365を利用したとする。この時、当然Microsoftは@test.comのドメインで登録されたメールアドレスはMicrosoftのサービスを利用しているということを知っている。なので、@test.comを持つメールアドレスは、組織アカウントとして登録する権利を持つ。

一方、@gmail.comや@yahoo.comというドメインのメールアドレスは、Microsoftの辞書にない。あるいは、Unixベースのメールシステムを使用している@oracle.comというドメインも(有名ではあるが)Microsoftの辞書にないため、組織アカウントとして登録することが出来ない(※1)

Microsoftが"組織アカウント"と"Microsoftアカウント"に分けている理由、もうちょい言えば"組織アカウント"なる定義を作っている理由だが、例えばMicrosoftのゴールドバートナーの会社に特典を付与する場合、その会社の組織アカウントでMSのサイトにアクセスする必要がある、などMicrosoftの管理上の問題といえる。つまりMSの都合。

使う側にとっては、必ずしも組織アカウントで登録する方がいい、とはいえず、Microsoftアカウントでしか出来ないようなアクションもある。とはいえ、MSのゴールドパートナークラスの会社なら、同じAzureを使うにしても組織アカウントで使っといたほうが何かといい(この会社の従業員はMSにお布施してくれてるな、というのが分かる)ような気がする。

ちなみに

  1. とある会社はMicrosoftのサービスを使っていない
  2. 従業員がその会社のメールアドレスをMicrosoftアカウントとして使用
  3. とある会社がMicrosoftのサービスを使用開始し、メールアドレスが組織アカウントして登録可能になる

このケースの場合、2で会社のメールアドレスをMicrosoftアカウントとして登録してしまった人はどうなるかというと、そのアカウントは一生Microsoftアカウントとなり、組織アカウントには登録できなくなる。それが私なのだが、救済策として、表示上はMicrosoftアカウントだが、特典などは組織アカウントと同等に受けられるようになる。

ややこしいのは、ドメイン自体は組織アカウントなので、「あなたのアカウントはMicrosoftアカウントですか?それとも組織アカウントですか?」と聞かれて組織アカウントを選択した場合、そもそもアカウント自体が存在しない扱いのため一生ログインできないというハメに合う。そのハメに合ったため、この記事を書いている。

自分用メモ

  1. イニシャル@xxx.com 組織アカウント。O365にログインして各種サービスを使えるのはこれ。
  2. イニシャル@xxx.co.jp Microsoftアカウントだが実質組織アカウントでいろんな権限が付与されている。パスワードは大文字7桁+1(どうやら同盟の組織アカウントも存在していることになるらしい?)
  3. 名.姓@xxx.com 1のエイリアスであるが、Azure利用上は1と違うアカウントになるぽくてよく分からない。Microsoftアカウントぽい。
  4. xxx@gmail.com クリーンなMicrosoftアカウント

※1 正確に言うと、AzureADにドメインを登録していれば、Microsoftに課金していなくても組織アカウントとして認められそうだが、ここらへんは試していないのでよくわかりません。

Office365のIMAP移行を試す話

Postfix + Devecot環境のメールシステムからOffice365への移行をすることになった。Office365のIMAP移行というのはよー分からん、ということで、試しにGmailのテストアカウントからOffice365への移行を行うことにした。

prius.hateblo.jp

環境

Office365の新規テナント契約

  • exoadmin@tokyoppp01.onmicrosoft.com
  • よく使われる8文字

テスト用Gmailアカウントの取得

  • tokyoppp01@gmail.com
  • よく使われる8文字 + 自分用7文字の5~大文字

IMAP移行バッチの作成

以下のマニュアルを参考に、移行バッチの作成を行う。

注意点は以下。

  • 2016/7/19時点では、新管理ポータルはプレビュー版なので、GUIからやる時は旧ポータルを使用する
  • おそらく、一度移行エンドポイントを作成後(今回の場合、GmailへのIMAP接続)は、2回目移行の利用でそれを利用できるので手順が異なる
  • 移行バッチには最大同期数の制限(100?)があるらしいので、抵触しないようにする
  • とはいえ、100以上のユーザーを同時に同期状態にするとネットワーク負荷が高くなりそうなので、順次移行を検討するのがよい。
  • 例:ユーザー数1,000人の場合、50人単位で移行バッチを実行し、同期が終了したら元メールシステムに転送設定を入れ、IMAP移行バッチ自体は解除する、など。
  • その他、移行できるアイテム数と1アイテムあたりの容量に制限があるので注意

結果

ほとんど空っぽなテストユーザーのデータが3分ほどで同期状態となった。この後は、24時間に1回くらいの頻度で差分同期が走るらしい。 つまり、これは大事なことなのだが常に元のメールシステムのデータが正であるということ。

実際の現場では

  1. 同期バッチ完了
  2. 元メールシステム→新メールシステムへの転送開始
  3. 24時間後の同期完了
  4. 同期状態解除

の順番でないとと、漏れるメールが発生する。3が終わってから4するのが大事。

こう考えると、移行バッチはユーザー1名1名単位で実装るのがよいか。1バッチ中の人数が多ければ細かい転送設定制御ができず、ネットワークトラフィックに無理が出てしまう…。

コマンドライン

以下の様なものが用意されているらしい。

  • Complete-MigrationBatch
  • Get-MigrationBatch
  • Get-MigrationConfig
  • Get-MigrationEndpoint
  • Get-MigrationStatistics
  • Get-MigrationUser
  • Get-MigrationUserStatistics
  • New-MigrationBatch
  • New-MigrationEndpoint
  • Remove-MigrationBatch
  • Remove-MigrationEndpoint
  • Remove-MigrationUser
  • Set-MigrationBatch
  • Set-MigrationEndpoint
  • Start-MigrationBatch
  • Stop-MigrationBatch
  • Test-MigrationServerAvailability

New,Remove,Set,Start,Stopは手動でやるとして、Get系はエビデンスを取得するために使えそう。あとはTestか。

追加検証

GB単位のGmailアカウントはどれくらいで移行できるんだろう?と興味があったので今やってます。

適当にAzureサービス使ったら4万円課金された話。

この前の記事には背景がありまして。

prius.hateblo.jp

背景

半年前くらい、少し時間が出来たのでAzureサービスをいろいろ触ってみてました。その中の一つの「メディアサービス」というのがあり、何やら自分が作った動画をUPしてAzureCDN経由でインターネットユーザーに提供できるとのこと。こいつぁ夢の技術だわ!ってことでメディア関係のアカウントを作成しキャストをONにし動画をUP。Internetに公開し「Azureってエンタメ関係も強いんだ!すげー!」となったのですが…。これやるならyoutubeでよくね?という事に気づき、動画の公開を停止したのでした。

その1か月後。ふとAzureの請求を見てみると4万円とのこと。どうも、メディア関係のアカウントをいろいろいじっていた時に「ストリーミング」をONにしたまた放置していた様子。ストリーミングという名前から想像できるよう、時間当たりの課金額はすさまじく、1か月たらずで4万円の課金になったのでした。1か月の間、真っ暗な画面をストリーミングしていただけで…。

ネット上ではアカウントハック起因の救済措置のレポートも上がっていましたが、僕はれっきと自分でAzureサービスを使っての課金なので、授業料として4万円払いましたとさ。

まとめ

結局悪いのは、当時のAzureで課金アラートが設定できなかったことでした。通常Azureの使用量が月に5000円程度なので、例えば1週間で5000円使っていれば明らかに怪しい。その後課金アラートが設定され、とりあえずの対応はできるようになったのですが。

クラウド運用で課金管理ってのは最も重要な運用要素の1つだと思います。 というのは、理論上、リソースが無限に作れちゃうので、課金管理が唯一無二のリソース管理ポイントなんですよね。 もちろん、何らかの仕組みで「各部署につき、A2クラスの仮想マシンを10個まで作ってよい!それ以上は制限する!」と入口で管理することもできますが(多分)、クラウド時代においてはナンセンスであり「各部署につき、1月10000円まで自由に使ってよい」と、スマートに出口=課金で管理したい。

そのためには、前述のbillingAPI使ったり、もうちょい便利なサードパーティ製品(CloudCruiserなど)を使ってもいいと思います。特に会社でやる時はね!

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に出来る。

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

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

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

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

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

振り返り中

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

振り返り後

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

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

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

powershellからyammerにアクセス(yammer REST API)

そんなわけではてなブログに技術メモを書きます。

Wordpressで慣れているので、記法はmarkdownを選択。

あとpowershellシンタックスハイライト効かないので、以下記事を参照にする。

ちょっと用事でyammerのデータを取得する必要があったので調査。yammerはAPIを提供してくれているのでそれ使えばよい。

developer.yammer.com

RESTでのアクセスとなる。

昔、rubyfacebooktwitterのデータを取得していたがそれはrubyの便利ライブラリを使ってのことであって、REST APIを生で使うのは初めてであるので'yammer rest api powershell'で調べた結果がこちら。

blog.kloud.com.au

結論から言うとこの記事の通りにやってデータを取得することができた。

…という記事だけだと寂しすぎるので、少し解説。

1. yammerアプリケーション登録

プログラム以前の問題として、yammerにアプリケーション登録し、クライアントIDと秘密鍵を発行してもらわないといけない。

  • (本人)yammerにアプリ登録
  • (yammer)クライアントIDと秘密鍵を発行
  • (本人)REST API経由でアクセス(クライアントIDと秘密鍵でトークンを作成)
  • (yammer)クライアントIDと秘密鍵(実際はトークン)を照合し、正しいリクエストであることを確認してデータを返す

なんでこんな事するかってーと、REST API経由でのアクセスをyammer側で管理するため。例えば1秒間に100回リクエストを送ってくるクライアントIDは一時的にアクセス不可にするとか。同等の仕組みはfacebooktwitterにもあります(よくAPI制限がどうたら~ってのはこの事)

アプリケーションの登録はこちらから↓

https://www.yammer.com/client_applications

'アプリ'といっても実際WebアプリやiPhoneアプリを作るわけではないが、REST界隈ではそういう言い方をします。名前は適当に作ってclientIDと秘密鍵をゲット。アプリの名前などを変えたければ新規アプリを登録して、そちらのclientIDと秘密鍵を使えばいい。

2. 認証コードの取得

clientIDを使って認証コードをゲット。

以下のようなURLにアクセスすれば認証コードをゲットできる。

https://www.yammer.com/dialog/oauth?client_id=$clientID&redirect_uri=$RedirURL

powershellでやる場合はこちら。

$clientID = "xxxxx"
$clientsecret = "xxxxx"
$RedirURL = "https://www.yammer.com/xxxxx.com"
 
$ie = New-Object -ComObject internetexplorer.application
$ie.Visible = $true
$ie.Navigate2("https://www.yammer.com/dialog/oauth?client_id=$clientID&redirect_uri=$RedirURL")

# この時点で秘密鍵は不要

そうすると、

http://www.xxxxx.com/?code=xxxxxxxxxxxxxxxxxx

みたいなページに飛ぶ。ここのcode=xxxxxxxxxxxxxxxxxxが認証コードになります。

3. 認証トークンの取得

認証コードが分かったら

の3点セットがそろうので、以下のページにアクセスして認証トークンをゲット。

https://www.yammer.com/oauth2/access_token.json?client_id=$clientID&client_secret=$clientsecret&code=$Authcode

powershellで書くならこちら。

$ie = New-Object -ComObject internetexplorer.application
$ie.Visible = $true
$ie.Navigate2("https://www.yammer.com/oauth2/access_token.json?client_id=$clientID&client_secret=$clientsecret&code=$Authcode")

4. APIにアクセス

適当な場所にダウンロードしたトークンをパースして、認証ヘッダーに含めてAPIにアクセスします。

$Openjson = $(Get-Content 'C:\Tokens\access_token.json' ) -join "`n" | ConvertFrom-Json
$token = $Openjson.access_token.token

$uri = "https://www.yammer.com/api/v1/messages.json"
$uri = "https://www.yammer.com/api/v1/search.json"
     
$Payloadjson = '{
"search": "test"
}'
 
$Headers = @{
"Accept" = "*/*"
"Authorization" = "Bearer "+$token
"accept-encoding" = "gzip"
"content-type"="application/json"
}
 
Invoke-RestMethod -Method Post -Uri $uri -Header $Headers -Body $Payloadjson