CentOSからAzureをREST-APIで操作したい
最近ARM templateの記事ばかりですので、たまには少し違う目線で記事を書いてみます。
Azure Portalをご利用されている方は多いと思いますが、Linuxな人は基本的にCUIから全て操作したい(古臭いですかね)、という方が多いと思います。かくいう私もその一人ではありますが、Azureを操作する上でCUIから全ての操作をするのは意外に大変な部分もあります。
そんな多くの方が最初にアプローチするのはAzure CLIでしょうかね。そのAzure CLIでは最初に認証の設定をします。「azure login」から認証する際に必要なコード(ランダムな文字列)とURLが表示されますので、そのURLをブラウザで開き、アカウントとパスワードでログインした後このコードを入力して認証します。
プロンプトが返ってきますので、その後「azure account list」から、Subscription idを表示させ、最後に「azure account set <subscription id>」とすることで、次回からOSへログインすると自動的にこれが設定された状態でログインすることができます。つまりログイン後すぐにazureコマンドが打てるようになります。
(これはARMのモードでの話です。「azure config mode arm」)
※見るとわかりますがホームディレクトリ配下に「.azure」という隠しディレクトリ
が作成されており、暗号化して記憶されています。
こうやってAzure CLIを触っていくわけですが、利用したいサービスや機能が全て揃っているわけではないため、歯がゆい気持ちになる時もあります。
利用できるサービスのカバレッジで言えば(C#やPowershellを除いて)SDK Javaをダウンロードしてきてライブラリからメソッドを呼んで操作する、ということもできますが、もっと単純にHTTP(S)リクエストを投げて操作できないものか、と思います。
ということで、今回の記事は「だったらAzureのREST-APIをcurlで直接叩けないんかな」ということを少し紹介します。
まず押さえておくサイトとしてはAzureのAPI referenceです。
https://docs.microsoft.com/en-us/rest/api/index
左ペインに各サービス毎にアクセスするためのHTTP request/header/bodyの仕様が記載されています。
ただし全てに共有して必要なものがあり、それがAPI認証です。HTTPリクエストの実態を見るとこんなリクエストをかけているようです。
GET /subscriptions?api-version=2014-04-01-preview HTTP/1.1
Authorization: Bearer <bearer-token>
Host: management.azure.com<body>
既にAWSのAPIを利用したことがある方はピンとくると思いますが、間違いなく「Authorization: Bearer <bearer-token>」 という行の<bearer-token>にしか目にいかないですよね、ワクワク(笑)
はい、ご察しの通りAWSで言うところの以下の行に当てはまります。予想通り、「直接実装するとあのクソだるいやつかー」です。
「Authorization: AWS AWSAccessKeyId
:Signature」
※もちろん言語で隠蔽されたcredentialライブラリでしか組み立てたことがない方は
このダルさは共有できないので、スルーしてください。
AWSではDIGEST認証と呼ばれる認証方式を採用されていますが、AzureではBearerトークンを採用しています。これはOauth 2.0の認証機構に準じているようです。(RFC6750)
なぜOauth 2.0なのか。Microsoftの認証基盤はActive Directoryなのは有名な話ですね。そしてAzure Active Directory(AAD)はOpenID Connect 以外にもOauth 2.0の業界標準プロトコルにも対応しているから、でしょうか。
ということは、Oauth 2.0の通信に必要なトークンを生成するためには、AADからキー情報をもってこないといけないんだろうな、という想像がつきます。はい、Active Directoryという言葉を聞いただけで脳内がフリーズするLinuxな人は多いと思いますが、最初少しだけ我慢しましょうか。
では、早速AADでキー情報を持ってくるための設定をAzure Portalでやってみましょう。
左側のアイコンでAzure Active Directoryをクリックし、「アプリの登録」から「追加」でアプリを登録します。
アプリ名はなんでもよいです。WEBアプリ/APIを選択し、サインオンURLもhttp://localhostと適当に入れておきましょう。
作成したアプリの表示名(アプリ名)とアプリケーションIDをどこかにメモしておきましょう。後で使います。(画面の赤丸でかこった部分)
次に作成したアプリの「キー」から、適当な名前のキー名と有効期限を設定します。1年か2年か無期限っとオトコな設定ですがとりあえず無期限で。
保存するとキーIDが表示されますので、それを同じくメモっておきます。
ちなみにキーIDは保存した時に出力されるだけで、以降は取得できなくなる機密性の高いモノになりますので、ここで確実にメモっておく必要がありそうです。
最後にAADのディレクトリIDを持ってきます。
このディレクトリID(テナントIDとも呼ばれている!?)もメモっておきます。
ここまでがAADの操作です。
次に先ほど作成したAADのアプリを、どこかのリソースに権限を付与して紐づけなければいけません。ここではリソースグループに紐づけてみます。(単一VMにも紐づけ可能です)
適用したいリソースグループから 「アクセス制御IAM}を選び「追加」から、どの役割(ロールですよね)を追加するかを選びます。いろんなAPIを触りたいので共同作成者にしておきましょう。(VMの操作だけなら、仮想マシン作成協力者がよいと思います)
次は「ユーザーの追加」にて先ほどAADに作ったアプリ名を検索して選択しましょう。最後にOKボタンをクリックしてポータルからの操作は終わりです。
以下のcrulコマンドを打ちましょう。
★印に先ほどメモったものをあてはめます。全て1行です。
curl -X POST -H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=client_credentials"
-d "resource=https://management.azure.com/"
-d "client_id=★メモったアプリケーションID★"
--data-urlencode "client_secret=★アプリケーションのキーID★" https
://login.windows.net/★ディレクトリID★/oauth2/token?api-version=1.0
実行するとaccess_token(こいつがbearer token)が手に入ります。
とても長いトークンですが、最後にこれをメモっておきます。
では簡単な例として、冒頭で紹介したAzure REST API referenceに戻り、Conpute->Virutual MachinesのページにあるRestartを見てみましょう。
仮想マシンを再起動するリクエストフォーマットが書かれていますね。
curlで組み立てるとこんな感じです。
curl -v -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer ★コピーしたaccess_token★"
-H "Host: management.azure.com"
-d "" https://management.azure.com/subscriptions/
★Subscription ID★/resourceGroups/★権限付与したResrouceGroup名★/providers/Microsoft.Compute/virtualMachines/★VM名★/restart?api-version=2016-03-30
※Subscription IDは冒頭で紹介したAzure CLIの「azure account list」から取得してください。
打つと同時にターミナルが落ちましたが、再度ログインしてwho -rすると再起動されたことがわかると思います。