はじめに
みなさま、Amazon CloudWatch ダッシュボード 使ってますか?
私はバリバリ使っています。
なぜ、CloudWatch ダッシュボード を使うかというと、New Relic や Datadog のお金を払えないからです!!笑
とはいえ、実は CloudWatch ダッシュボードは色々な機能があります。
例えば、以下のようなことができます。
- 複数のリージョンやアカウントに跨ってメトリクスやログ、トレースを集約できる
- ダッシュボード変数を使って、複数のウィジェットでさまざまなコンテンツをすばやく切り替えられる
- ライブデータ を使ってリアルタイムで分析できる
- グラフ、メトリクス、線、数値、ゲージ、テキスト、アラームテーブル、リンクといったさまざまなウィジェットが用意されている
- AWS アカウントに直接アクセスできないユーザーと共有できる
- その他、CloudWatch 外のデータをメトリクス化して表示したり(たとえば Prometheus や RDS など)、カスタムウィジェットを使って(Lambdaをつかって)表示を自由にカスタマイズしたりすることも可能
より詳しく CloudWatch ダッシュボード の機能を知りたい場合は AWSが用意している One Observability Workshop をご覧頂くとイメージがつきやすいです。
やりたいこと
さて、ここから本題ですが、CloudWatch ダッシュボードをAWSアカウントへのアクセス権のない人にも使わせたいということはないでしょうか。
例えば、SREだけでなくアプリ側のエンジニアとダッシュボードを共有したい。むしろ、ビジネス側とSLOやエラーバジェットを共有したい。そもそも、AWSアカウントへのログインがめんどくさい。といったことがあると思います。
CloudWatch ダッシュボードを共有する場合、3つの選択肢があります。1つはリンクを知っている人全ての共有する方法。もう一つはユーザー/パスワードをCloudWatchに登録してその認証でログイン共有する方法。最後に、SSOを利用して共有する方法です。
これらを考えたときに、1つ目の方法はセキュリティ上、好ましくありません。2つ目の方法は利用者のパスワード管理が増えてしまい、あまりやりたくありません。そのため、SSO認証を利用して管理したいと考えました。ただし、私の場合は外部のSSOプロバイダーを利用しておらず、かつ Google Workspace ユーザーと共に(業務委託などで)個別にユーザーID/パスワードを発行する2つのユーザー管理を使う必要がありました。そのため、要望を満たせる Cognito を使おうと思いました。
今回、Cognito User pool は2つ必要です。
1つは CloudWatch Dashbord が自動で生成される 「CloudWatchDashboardSharing」です。もう1つは 「CloudWatchDashboardSharing」 の Identity provider として利用する 「CloudWatchIdentityProvider」です。
いやいや、そもそも「CloudWatchDashboardSharing」でユーザー管理まですれば良いじゃないかと思われるかもしれません。私は初めそう思いました。しかし、CloudWatch ダッシュボード共有で SSO プロバイダーとして認識するのは「CloudWatchDashboardSharing」に登録した「Identity provider」のみであり、必ず「Identity provider」を追加しなければなりません。そのため、「Identity provider」として Cognito User pool をもう1つ作成しなければなりませんでした。
なお、Cognito User pool の Identity provider として Cognito を利用する方法は、こちらの記事を参考にさせていただきました。
やってみた
Cognito User pool「CloudWatchIdentityProvider」を作成する
-
「Application type」を「Traditional web application」、「Name your application」に「CloudWatchIdentityProvider」を入力します。
-
「Options for sign-in identifiers」は「Email」を選択し、「Required attributes for sign-up」は「email」を選択します。
-
「Add a return URL」は入力せずに、「Create」を選択します。
-
「Set up your application」は何もする必要はないため、下までスクロールして「Go to overview」をクリックします。
-
「Overview: User pool - xxxx」ページが開きます。「User pool ID」は後で利用するため、コピーしておきます。また、分かりやすいように名前をつけておきます。「Rename」をクリックします。
-
「User pool name」に「CloudWatchIdentityProvider」を入力し、「Save changes」を選択します。
-
これで名前が変わりました。次に、App client を確認します。左メニューの「App clients」を選択します。
次に、Cognito User pool「CloudWatchDashboardSharing」を作成します。ただし、再度「App client: CloudWatchIdentityProvider」ページに戻りますので後続は別のタブを開いて作業します。
Cognito User pool「CloudWatchDashboardSharing」を作成する
「CloudWatchDashboardSharing」は CloudWatchダッシュボードから作成します。
-
マネジメントコンソールで CloudWatch ダッシュボード を開き、「Actions > Share dashbord」 をクリックします。
-
「Go to CloudWatch setting」をクリックし、CloudWatch 設定の Dashboard sharing を開きます。
-
「Available SSO providers」の選択肢がないことを確認し、「Manage SSO providers」をクリックして Amazon Cognito User pools を開きます。
-
「CloudWatchDashboardSharing」という User pools が追加されていますので、選択します。
-
「OpenID Connect (OIDC)」を選択します。
なお、ドキュメントには以下のような情報が書かれています。
今回は SSOプロバイダーに Cognito を利用しているため問題なしと判断しました。もし、この方法を利用する場合はご注意ください。 -
「Client ID」と「Client secret」に User pool 「CloudWatchIdentityProvider」の App client でコピーした「Client ID」と「Client secret」を入力します。
-
「Authorized scopes」に「openid email aws.cognito.signin.user.admin」を入力します。
-
「Issuer URL には 「https://cognito-idp.us-east-1.amazonaws.com/[UserPoolID]」 を入力します。[UserPoolID] は User pool 「CloudWatchIdentityProvider」の「User pool ID」です。
次に、Cognito User pool「CloudWatchDashboardSharing」の「App client」を作成します。
Cognito User pool「CloudWatchDashboardSharing」の「App client」を作成する
Cognito User pool「CloudWatchDashboardSharing」の「App client」は CloudWatch が自動で作成します。
-
先ほど開いていた「Dashboard sharing」を再度表示します。「Available SSO providers」に「CloudWatchIdentityProvider」が選択できるようになっているので選択します。「Save changes」を選択します。
-
次に、 Cognito User pool の 「CloudWatchDashboardSharing」の画面を開き、「App clients」を選択します。すると、「CloudWatchDashboardSharingFederated」が追加されていることが確認できます。「CloudWatchDashboardSharingFederated」を選択します。
Cognito User pool 「CloudWatchIdentityProvider」の「App client」を更新する
-
次に、「CloudWatchIdentityProvider」の「App client」を設定します。先ほど残していた「CloudWatchIdentityProvider」の「App clients」タブを再度開きます。App client の「CloudWatchIdentityProvider」を選択します。
-
「Allowed callback URLs」に先ほどコピーした User pool「CloudWatchDashboardSharing」の「Domain」の url を利用し、末尾に「/oauth2/idpresponse」を追加します。
-
「OpenID Connect scopes」で「Phone」を削除し、「aws.cognito.signin.user.admin」を追加します。
-
「Save changes」を選択します。これで、「App client: CloudWatchIdentityProvider」の更新は完了です。
Cognito User pool 「CloudWatchIdentityProvider」にユーザーを追加する
これで設定は完了です。それでは動作を確認します。
動作を確認する
これで、CloudWatch ダッシュボードを Cognito 認証を使って共有できました!!
最後に
今回、CloudWatch ダッシュボードの共有に Cognito User Pool のみを利用して行なってみました。
通常は SAML に対応したIdP プロバイダーを使うところCognito のみで完結させることで、AWSに閉じた世界でかつ、AWSアカウントにアクセス権を付与せずに共有できました。
同じようなことをやろうと思った方の助けになればと思います。
あとがき
実際にやってみると色々エラーになり躓きましたので、それについても書いておきます。
「"Client is not enabled for OAuth2.0 flows"」エラーが発生した。
「App clients」の「Allowed callback URLs」「大文字」を使っていたのが問題でした。「Branding > Domain」をみるとわかる通り、全て小文字である必要があります。
「CloudWatchDashboardSharing」に 「App client」を追加が別のURLにリダイレクトされた
「Dashboard sharing」でSSO Providers を選択すると、 App Clinet に「CloudWatchDashboardSharingFederated」が自動で追加され、これが使われていました。
Cognito のログイン画面で「Create an account」を非表示にする
上記で作成した User pool 「CloudWatchIdentityProvider」はセルフサインアップを許可されています。そのため、誰でもユーザーを作れる状態です。そのため、セルフサインアップを禁止する必要があります。