Edited at

【重要】従来型(古い)Watsonインスタンスをお使いの方は来年(2019)の10/30までに新しい環境に移行しないと、たぶん死にます(またはWatsonのRC/IAM移行のお話)

:triangular_flag_on_post: 当記事の本質は「ベンダー告知の周知」なので、本来はQiitaに投稿するのが不適な点、重々承知しております。とはいえWatson関連の情報収集でQiitaを見ていただいている方も多いようですので、広くお知らせすべきと考え個人的に投稿させていただきます。当記事は個人レベルで調査したことをまとめたものであり、ベンダーからの公式の情報ではございません

:warning: (2018/11/01) 当記事は今後も更新あるかと思いますので末尾に改定履歴を付けておきます。初版からの変更箇所は:bulb:にて。


はじめに

こんにちわ!石田です。大切な話題なのでちょっと危機感を煽る/刺激的なタイトルをつけました。すいません。でもお伝えしたいのはそういうことで、要は「注意喚起」をさせていただきます。

皆様、以下のブログ記事をご覧になられましたでしょうか。

:flag_us:IBM Watson AI Services Enabling IAM and Resource Groups

:flag_jp:IBM Watson AI のサービスについて、IAM およびリソースグループが有効に

このタイトルだけだと「あっ、そ。有効になったの、よかったね。(でもIAMなんて使ってねーし。そもそも何、それ)」てな感じかと思いますが、実は既存のWatson APIをお使いの皆様に影響のあるかもしれない、大切なお知らせを含んでいます。原文を読んでいただくのがベストですが、要は下記です。


要は:(TL;DR)




  • WatsonAPIのサービス群は、ロケーション単位で新しいRC(Resource Controller)/IAMベースのインスタンスへ順次、移行を実施中です

  • 現時点では同一のサービス(例えばWatson Assistant)に対しCFベース/RCベースの2種類が提供されています1


  • 来年の2019/10/30に従来のCF(CloudFoundry)ベースのWatsonインスタンスは停止させていただきます

  • ついてはご迷惑をおかけしまして恐縮ですが、CFベースのインスタンスをお使いのお客様は2019/10/30までに新しいRCベースの環境(インスタンス)への移行作業をお願いします


    • 放置したまま期限をすぎ、CFのインスタンスが停止されるとWatsonのサービスが使えなくなります(ご自身がどちらのインスタンスを使用しているかの見分け方は後述します)

    • 移行は ①インスタンス自体の移行 ②アプリ側の認証方式の変更 の2つの要素があります 




:books: 文献(ドキュメント)

まずは参考になりそうな文献リストを先にお示しします。

:pencil: 当件について先達である@makaishi2さんの記事「IBM Cloud IAM対応のためのtips

:blue_book: IBM Cloudドキュメント: リソースおよびサービスの処理

:blue_book: Watsonドキュメント: Authenticating with IAM tokensからの一連のIAM関連の説明群

:orange_book: Watson API Reference(サービス毎)のAuthenticationの箇所

:orange_book: Github: Watson SDK Repos


全体のサマリー


何がどう変わるのか?

比較軸
旧(従来)

時期
旧Bluemix時代~
2017年~

基盤
CF(Cloud Foundry)
ベース
RC(コンテナ)
ベース)

認証
Credential
UID/PWDベース
Credential
apikey(Token)ベース

-
(旧から移行した場合のみ)
UID/PWDも利用可

今回の移行の要因は大きくは以下の2点です

① Watsonサービス群が稼動する基盤

② Watsonサービスを使用する際の認証の機構

①についてはBluemix時代のCloud Foundryベースの環境からコンテナ(Kube?)ベースの環境2にロケーション単位で順次移行しています。

②については従来のユーザー名/パスワードによるものからIAMベース(apikey)のものに移行しています。

今回はサービス提供側のWatsonサイドの移行の完了目処を2019/10/30にセットしたわけですが、ビッグバン的に一気に移行せず、お客様側の環境の移行は個々のお客様に実施を委ねる方式としたため、一年以内の移行対応をお願いすることになったものです。


ロケーション別の対応状況

:bulb: 2018/11/19時点では全ロケーションが新環境になっています。UK以外は新環境の提供を開始しています。

ロケーション
旧(現)のみ
新環境提供中

US South
-
3

Sydney
-

Germany
-
3

US East
-

:bulb: Tokyo
-


Watsonインスタンスの移行


サービス提供(Watson)側から見た旧→新環境への移行の方針・考え方



  • :bulb: 2018/11/19時点ではWatsonが利用できる全ロケーションが新環境提供を開始しています。



  • 新環境を未提供のロケーション(=UK)は当然すべて旧環境(CFベースの環境)です。新規にインスタンスを作ると従来のCFベースのものになります。 :bulb: 11月初旬の段階では新環境を未提供のロケーション(具体的にはUK)がありましたが、現時点ではなくなっています。

  • 新環境を提供済みのロケーション(=UK以外)ではすでに新環境に移行されたお客様と未移行のお客様が混在していますので、個々のサービスインスタンスをみると新旧入り混じっている状況です。

  • 新環境を提供しているロケーションでインスタンスを「新規作成」した場合は新しいRCベースのインスタンスがデプロイされます。従来型のCFベースのインスタンスを新規作成することはできません

  • 新環境を提供しているロケーションでも、利用者が意図して移行操作を行わないかぎり、従来型のCFベースのインスタンスは稼動し続けています。新環境の提供を開始したからといって、そのロケーション上の全インスタンスを一方的/一斉に移行してしまうわけではありません。今後一年の間に、適切なタイミングでお客様リードで個別に移行していただくことになります。

  • 2019/10/30には全ロケーションのCFインスタンスが停止されます。万が一お客様が2019/10/30までに移行を行わなかった場合、アプリは当該サービスにアクセスできなくなります。(:warning: 本番の場合、業務に影響が出ます!)


CFインスタンスとRCインスタンスの見分け方

既存のお客様は「自分の使ってるの、新旧のどっちかな」と思われると思います。以下のように作成時やダッシュボードで見たときに違いがあります。


ダッシュボード

従来の環境(CFベース)は「Cloud Foundry Services」の下に列挙されます←:warning: これが移行の対象インスタンスです

新しい環境(RCべース)は「Services」の下に列挙されます


インスタンス作成時

ロケーションにより新旧どちらの環境で作られるかが決まる=利用者が選べるものではありませんが、

従来の環境(CFベース)で作る場合は組織(Org)とスペース(Space)があります

新しい環境(RCべース)で作る場合は「リソースグループ」4のみがあります


インスタンス移行の考慮点


  • 新しい環境(RCべース)は管理制御の単位が「リソースグループ」になります。従来の環境(CFベース)での「組織(Org)」や「スペース(Space)」という概念がありません。よって、もし従来「スペース」を活用して「開発(dev)」「テスト(test)」「本番(prod)」などの環境を区別・管理していた場合、同様の構造を「リソースグループ」で実装するように意味上のマッピング/設計をする必要があります

  • IBM Cloudのドキュメント「リソース・グループへの Cloud Foundry サービス・インスタンスおよびアプリのマイグレーション」にあるように、ダッシュボード上で移行推奨マークが出たら移行を開始してください(っても私自身は見たこと無いんですけど。。)釈迦説ですが、この表示が出るまで移行を待つ必要はもちろんありません。早めの対応が吉、です。


認証方式の変更(IAMへの移行)


新旧の認証方式の違い

従来のCFインスタンスでは認証の際は「サービス資格情報(Credential)」のusernameとpasswordを使っていました。新しいRCインスタンスでIAMを用いて認証する場合は「サービス資格情報(Credential)」は同じですがセットされている内容が違っています。具体的には認証のためにapikeyを使います。

:warning: 実はIBM Cloudではapikeyは3種類ありますが、Watson サービスが使うのは3.のサービス固有のAPIキーです。

#
名称
ご説明

1
プラットフォーム API キー
全体で1つ. MQはこれを使っている

2
インフラストラクチャー API キー
IaaSで使うもの

3
サービス固有の API キー 
Watsonで使うもの

メニューの下記にプラットフォーム API キーがありますが、Watsonが使うのはこちらではありませんので混同されないようご注意ください。


そもそもIAMって何?何がいいの?

IBM Cloud IAM=Identification & Access Managementの略です。細かい話はややこしくなるので避けますが、要は


  • IBM Cloud全体に新たに導入された認証・認可の仕組み(Watson以外も利用)

  • ログオンさせる/させないという認証(Authentication)だけでなく、どのリソースを誰にどのようなロールで使わせるか、という認可(Autorization)の設定も可能

  • apikeyで入手できるトークンに期限5を設け、一定期間で失効/再取得させることにより単純なusername/passwordよりセキュリティが強固になる

などの利点があるので、WatsonもIAMに移行しているわけです。AmazonさんにもIAMという機能があるので、あれをご存知の方は「同じようなもの」と思っておいてください。

参考文献:

:newspaper: ドキュメント「IAMとは?

:newspaper: A beginners guide to IAM in the IBM Cloud


インスタンスと認証の関係

新(RC)インスタンスを提供中のロケーションでは、「新(RC)インスタンスをどのように作ったか」で許容される認証方式が変わります。

#
インスタンスの種類
作成方法
従来型
(USERNAME/
PASSWORD)
IAM
(apikey/token)
2019/10/30以降

1
旧(CF)
未移行

-
停止

2
新(RC)
新規作成
-

継続

3
新(RC)
UI上で移行操作
?

継続


  • 新(RC)インスタンスを新規作成した場合は新しい認証方式であるIAMしか使えません

  • 旧CFインスタンスをUI上で移行した結果できた新(RC)インスタンスは引き続きUSERNAME/PASSWORD型の認証と新しいIAMの両方が使える(?)6


    • ドキュメント「Authenticating with IAM tokens」にこう書いてあるので、そう理解しましたが、、
      >Note: If you have migrated a service to Resource Controller, continue to use your existing authentication mechanism until you create and begin to use a new set of credentials.



まあ仮に自分が担当者だとして、運用中のWatsonシステムの現実的な移行シナリオを考えると、(特に本番)環境を移行する際にUI上でのぶっつけ移行となる#3のパターンはありえず、新規にインスタンスを作成して(設定やデータも移行して)十分にテストしたうえでアプリ側と同期を取って切り替える=#2のパターンになると思います。となると今後はIAMの利用はいずれにせよ必須と思われます。


IAM認証の基本的な(=一番下の層での)処理方式

以下に簡単にWatsonでのIAM認証の基本的な処理方式を説明します。ドキュメント「Authenticating with IAM tokens」に書いてあることを絵にしたものです。curlの場合などWatson APIをREST/自力/素で触る場合=一番下の層での動きであって、SDK利用時はSDK側がこれらの処理を代行してくれるのでアプリ対応はもっと楽で済みます。ご安心ください。(殆どの方はSDKをご利用かと思うので関係ありません=以下の話は「教養編」ともいえます)

:one: 認証には「サービス資格情報」にあるapikeyを使います。サービス資格情報は複数作成でき、各々に認可など設定することもできます。ドキュメント「APIキー管理のベストプラクティス」によれば、セキュリティ強化のためにサービス資格情報は定期的に更新(追加/削除)することが望ましいとされています

:two: ここでのクライアントとはWatsonサービスに要求を出す「誰か」です。いちおうcurlを想定していますが、Watson SDKのロジックかもしれませんし、場合によってはユーザーアプリかもしれません

:three: クライアントはapikeyを指定して認証を要求します。結果、①access_token ②refresh_tokenの2種類のトークンが返ります。

ご参考) 要はこんなのが返ります


:four: 前項で入手した①access_tokenを指定してWatsonの個別サービスのAPIを叩き、サービスの結果(レスポンス)を入手します

:five: 必要に応じ、同様にWatson APIを使います

:six: トークンの期限(TTL. デフォは3600s)が切れるとExpireして401(Unauthorized)でAPIの認証が失敗します

:seven: 期限が切れたら②refresh_tokenを指定してトークンの更新を要求し、新しいトークンを入手したうえで処理を継続します

上記のようにIAMへの移行対応に際し、自分でREST APIを直接たたく=一番下の層で実装するなら従来のUSERNAME/PASSWORDのように「決まったものを毎回指定しておけばいい」のではなく、トークンのリフレッシュを意識したつくりこみが必要になりますのでご注意ください。(繰り返しますがSDKを使っていればややこしいとこは吸収してくれるのでご安心あれ)

:triangular_flag_on_post: トークン・リフレッシュ時のべーシック認証について、ニッチですが末尾に書いておきます。


Watson SDKを使う場合

WatsonはJava/Python/Node.jsなど各種言語別にSDK('watson-developer-cloud')を提供しています。Liberty, Node.js, Flaskなどアプリケーション・サーバー環境でプログラミング言語を使っているお客様は殆どのケースでSDKをお使い7かと思います。Watson SDKはIAMに対応しており、SDKを使うと前項で述べたようなややこしい処理(※)の殆どをSDKにお任せできますので、アプリケーション側は「本来やりたいこと」であるWatson APIの利用に集中できます。

※ややこしい処理の例


  • apikeyを指定した独立した認証の要求と入手したtokenの保持

  • WatsonサービスのREST APIの発行とHTTP戻りの確認、レスポンスの取得

  • tokenのExpireとRefresh処理

SDKの提供する機能は言語により多少異なっていますので詳しくは各言語のSDKのドキュメントを確認されることをおススメしますが、ざっくり全体としては以下のような感じで使えます。


  • apikeyを用いた認証呼び出しのプロセスは不要。Watson APIの要求時にコンストラクターでapikeyを一緒に渡すだけでいい

  • VCAP_SERVICESがある環境(「接続」が定義されている環境)ではapikey自体も渡さなくてもいい(自動的にVCAP_SERVICESから抜いてセットしてくれる=セキュリティレベルの向上/変更に強くなる)

  • トークンの期限切れとリフレッシュの処理もSDKにお任せできるのでアプリは意識不要

  • (必要性があって/どうしてもやりたいなら)RESTを使って自分でapikeyからトークンを入手しておき、各Watson APIの要求時に(apikeyではなく)トークンを渡すことで、自分でトークンの期限管理を行うことも可能

以下はPythonでAssistant/IAMを利用した例ですが、SDKを使うとほとんど「お任せ」モードで実装できるのがおわかりいただけると思います。

PythonでAssistant/IAM利用


Assistant/IAM利用例

import json

from watson_developer_cloud import AssistantV1

# If service instance provides API key authentication
assistant = AssistantV1(
version='2018-09-20',
## url is optional, and defaults to the URL below. Use the correct URL for your region.
url='https://gateway-syd.watsonplatform.net/assistant/api',
iam_apikey= 'u2blg4Nw_MUFwKov40QXXXXXXXXXXXXXXXXXXXX'
)

def message(text):
# message
response = assistant.message(
workspace_id='77d05182-XXXX-4d85-9c40-XXXXXXXXXXXX',
input={
'text': text
},
context={
'metadata': {
'deployment': 'myDeployment'
}
}).get_result()
print(json.dumps(response['output']['text'][0], indent=2))
return response['output']['text'][0]

message('')
message('Hello')
message('What time do you open ?')



:warning: WatsonのSDKはBluemix時代のWatsonサービス=かなり以前から提供されていましたが、IAMはIBM Cloudになって後から出てきたものです。よってお使いのWatson SDKのバージョンは新しいものに更新しておいてください。(えらく古いとIAM対応のロジックが入ってないでしょう)


クライアントのパターン(サマリー)

Watsonに要求を出すクライアントは上図のように様々なパターンがあります。

:one::two:はクライアントがどこにあろうが自分で何らかの方法によりHTTPでREST APIをたたくので、前述のとおりapikeyの扱い含めすべて自力で実装します。8

:three:の場合はクライアントがIBM Cloud上ですのでWatsonサービスと「接続」が可能です。「接続」を定義するとクライアントにVCAP_SERVICES変数が提供されますが、SDKはVCAP_SERVICES変数があれば、そこの定義を使ってくれますので、アプリはapikeyをSDKに渡す必要はなくなります。(意図的に明示的に渡せばそちらが優先)

:four:の場合はIBM Cloud上ではなく「接続」が使えませんので基本的にapikeyを明示的に渡すことになります9

<<参考>>



アプリケーションのランタイムに「接続」を定義すると、ランタイムに対して環境変数 VCAP_SERVICESが提供されます。

上記をサマリーしてフローチャートにしました。Node.jsのSDKだけ、他の言語と違って独自の環境変数の取り扱いが追加されていた10ので、特殊ですが追記してあります。要は「アプリから明示的にキーを渡せばそれが最優先、渡さなくてもVCAP_SERVICESがあればよしなにしてくれる(そのほうがアプリの保守性もあがるし楽だしセキュリティも向上するし、でいいんじゃない)」という感じです。


:paperclip: ご参考) VCAP_SERVICESの指定を使う時

アプリでapikeyを渡さずVCAP_SERVICESの設定で進める場合のアプリのコンストラクターは以下のような感じになります。アプリ内に認証情報を持たず/SDKに渡さずに済むので保守が楽になりますね。


Node.jsの場合

var AssistantV1 = require('watson-developer-cloud/assistant/v1');

var assistant = new AssistantV1({
version: '2018-09-20'
});


Pythonの場合

from watson_developer_cloud import AssistantV1

...
assistant = AssistantV1(
version='2018-09-20'
)


Node-REDは?

Node-REDでのIAMの指定ですが要はNode-REDのパネルでapikeyを入力できるようになってます。具体的には前述の@makaishi2さんの記事「IBM Cloud IAM対応のためのtips - Node-REDから使う場合はどうしたらいいかおよび(おまけ) Node-RED設定との関係をご参照ください。


(参考情報) トークン・リフレッシュ時のべーシック認証について

えらくニッチな話題ですが、同じように悩まれる方がおられるかもしれないので書いておきます。

【疑問点】

ドキュメント「Getting an IAM token by using a Watson service API key」には「トークンを生成する際はベーシック認証もしたほうがいいよ」(ベーシック認証は推奨=オプション)と書いてあります。

また「Refreshing a token」では「トークンをリフレッシュする場合は、そもそも作るときに使ったものと同じベーシック認証の指定が必須(でないとリフレッシュできない)とあります。

ベーシック認証ってことはUSERNAME/PASSWORDのペアでしょうが、

IAMの場合のサービス資格情報にはそんなものはありません。IBM Cloudのユーザー/パスワードでもなさそうです。いったい何を指定すればいいのでしょうか。。

【答え】

この回答は@makaishi2さんに教えてもらいました。あざす!

結論から言うと、これは「決めうち」「固定値」です。暗号化された形ならこのままAuthorization: Basic Yng6Yng=でよく、暗号化前ならbx / bxを指定しておけばよかったようです。

IAM アクセス・トークンのリフレッシュと新しいリフレッシュ・トークンの取得

確かにpostmanでbx/px指定してaccess_token取れました。

こんなんでいいの?意味あるの?:weary:という気もしますが、まあいいです。

以上、長文失礼しました。


改定履歴

本文の更新した箇所は :new: をつけておきますね。

#
更新日
更新内容

1
2018/11/01
初版

2
2018/11/19
東京センター追加に伴い記載をアップデート





  1. compare_and_comply(ベータ)など、例外的に新しいRCのインスタンスのみ提供しているものもありますが、枝葉なので今は忘れてください 



  2. 様々なWatsonサービスがコンテナ化されKubernetes上で動くようになったのでWatson_Assistant_On_ICPなどのオンプレ・ソリューションも可能になったのかと想像しています 



  3. 2018/10/30~ 



  4. リソースグループは(無理やりたとえるなら)CFの場合の「スペース」に該当する概念です。RCベースの環境には「組織」の概念はありません。 



  5. WatsonのIAMではデフォルト3600秒でトークンは失効します。 



  6. このパターンのインスタンスが2019/10/30以降にどうなるのか(認証をIAMに移行する必要があるのか)、は現在問い合わせ中ですが、おそらくIAMへの移行が必要だろうと見ています。 



  7. 蛇足ですがもちろんそれらの言語で自分でWatson_APIをRESTで叩くことも可能です。その場合は前述のcurlと同じことをしていることになりますので同じ考慮が必要になります。 



  8. APサーバー環境で「接続」していたとしても、アプリでSDKを使っておらず、自分でHTTP/REST要求をだしている場合は「ややこしい処理を代行してくれるもの(SDK)」がありませんので:one::two:と同じ扱いになります 



  9. アプリケーションがローカル環境であっても、何らかの方法で自分で独自に環境変数VCAP_SERVICESを定義すればSDKの振る舞いは:three:と同じになりますが、その辺は「創意工夫/Tips」としてご自由にどうぞ。 



  10. ドキュメントの「Usage-Credentials_are_checked_for_in_the_following_orderの箇所をご参照ください