
Grafana Cloudの一部データソースでIAMロールベースの認証がサポートされたのでやってみた
はじめに
少し前にGrafana CloudでAmazon CloudWatch および Amazon Athena データソース向けにGrafana Assume Roleという機能がGAされていたので試してみます!
何が嬉しい?
名前から推測できる通り、Grafanaとデータソースを接続する際に必要な認証情報としてAWSのIAM ロールが利用できるようになりました!
一言でいうとアクセスキーが不要になりました!やったね!
今まではデータソースとしてCloudWatch や Athenaに接続する際はIAM ユーザーを作成してアクセスキーを発行する必要がありました。
企業のセキュリティルールによっては、アクセスキーの発行自体が難しかったり、申請が必要だったりと面倒なことが多かったかと思います。
また、アクセスキーを利用する場合はキーのローテーションも考える必要がありました。
IAM ロールの場合、一時的な認証情報を利用するため、これらの面倒な管理から解放されることが期待できます。
やってみる
私は普段からデータソースにAthenaを利用することが多いので、今回はAthenaでやってみます。
データソースの作成
まずはGrafana Cloudでデータソースを準備します。
Connections > Data sources > Athenaを選択します。
Authentication ProviderでGrafana Assume Roleを選択します。
すると、画像のようにIAM Roleの作成に必要な情報が表示されます。

以下の2つをメモしておきます
- 2に記載のアカウントID(画像の11111111111の部分)
- 3に記載のexternal ID(画像の234567の部分)
この2つは後ほどIAM ロール作成時に使います。
ちなみにこのexternal IDはGrafanaアカウント毎に固有のIDが割り当てられるようです。
Grafana AWSアカウントは、AWSデータの一時的な認証情報を生成するために、セキュリティトークンサービス(STS)リクエストを送信します。このリクエストには、
externalIDGrafana Cloud アカウントに固有であるため、ユーザーは自分の AWS リソースにのみアクセスできます。
一旦この画面は置いといて、IAM Roleを作成します。
IAM Role作成
AWSにログインして、IAM ロールを作成します。

信頼されたエンティティタイプで「AWSアカウント」を選択して、「別のAWSアカウントID」の部分に先ほどメモしたアカウントIDを入力します。
次にオプションにチェックを入れて、「外部ID」に先ほどメモしたexternal IDを入力します。
あとは適宜必要なポリシーを設定してIAM ロールを作成します。
データソースの作成(続き)
ではGrafanaのデータソース作成画面に戻りまして、
作成したIAM ロールのARNとデータソースとなるAthenaの情報を選択していきます。

データソースとの接続が確認できたらダッシュボードを作成してみます。
特にエラーもなくデータソースにクエリを実行することができました!

最小権限も調査してみた
これで終わるのも味気ないので、可能な範囲で最小権限も調査してみました。
まずは用意したIAM ロールの権限を全て削除してクエリを実行します。

当然エラーが出ますね。
クエリの書き出し権限が無いよ。と怒られているので、必要なポリシーを追加します。
あとはひたすらこれを繰り返すだけです。
また、途中Grafana側だけでは何のポリシーが不足しているのか不明な場合もあったので、CloudTrailのログも確認しつつポリシーを追加しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Access",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<クエリ対象のS3バケット>",
"arn:aws:s3:::<クエリ対象のS3バケット>/*"
]
},
{
"Sid": "S3OutputAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<クエリ結果出力先のS3バケット>",
"arn:aws:s3:::<クエリ結果出力先のS3バケット>/*"
]
},
{
"Sid": "AthenaListActions",
"Effect": "Allow",
"Action": [
"athena:ListDataCatalogs",
"athena:ListWorkGroups"
],
"Resource": "*"
},
{
"Sid": "AthenaDataCatalogAccess",
"Effect": "Allow",
"Action": [
"athena:ListDatabases",
"athena:GetDataCatalog",
"athena:ListTableMetadata",
"athena:GetTableMetadata"
],
"Resource": [
"arn:aws:athena:ap-northeast-1:<account-id>:datacatalog/<datacatalog-name>"
]
},
{
"Sid": "AthenaWorkgroupAccess",
"Effect": "Allow",
"Action": [
"athena:GetQueryExecution",
"athena:GetWorkGroup",
"athena:StartQueryExecution",
"athena:GetQueryResults",
"athena:StopQueryExecution"
],
"Resource": [
"arn:aws:athena:ap-northeast-1:<account-id>:workgroup/<workgroup-name>"
]
},
{
"Sid": "GlueAccess",
"Effect": "Allow",
"Action": [
"glue:GetDatabase",
"glue:GetDatabases",
"glue:GetTable",
"glue:GetTables",
"glue:GetPartitions"
],
"Resource": [
"arn:aws:glue:ap-northeast-1:<account-id>:catalog",
"arn:aws:glue:ap-northeast-1:<account-id>:database/<database-name>",
"arn:aws:glue:ap-northeast-1:<account-id>:table/*"
]
}
]
}
<xxxx>の部分は適宜利用するリソース名に合わせてください。
このポリシーは特定のワークグループやデータベースに絞った権限ですが、このポリシーだとIAM ロールの汎用性が損なわれ利便性が悪くなります。
可能ならResourceで定義するリソースの範囲を広げることも検討してみてください。
仮にデータソースへのアクセスを制限したい場合はIAMポリシーで制限するのではなく、Grafana側のユーザー権限でデータソースへのアクセスを制限するといった運用の方が楽になる可能性はありますので検討してみてください!
まとめ
Grafana CloudがAssume Roleに対応したのでやってみました。
ついにAthenaデータソースを利用する際のアクセスキーから解放されました!
面倒でローテーションせず放置してたアクセスキーはありませんか?この機会にIAM ロールへ置き換えていきましょう!










