Amazon Managed Grafana ワークスペースの作成と SAML の構成を AWS CDK で行ってみた
こんにちは、CX 事業本部 Delivery 部の若槻です。
Amazon Managed Grafana は、オープンソース分析プラットフォームである Grafana のフルマネージドサービスです。
Amazon Managed Grafana を使用する場合には、ワークスペースの作成および認証(SAML または IAM Identity Center)の構成を行う必要があるのですが、せっかくなので IaC で管理したいですね。
そこで今回は、Amazon Managed Grafana ワークスペースの作成および SAML の構成を AWS CDK で行ってみました。
やってみた
今回はワークスペースの認証を SAML で構成しますが、その場合は CDK デプロイを 2 回に分けて行う必要があります。
IAM ロール、Grafana ワークスペースの作成
まず、1 回目のデプロイではワークスペースが AsusumeRole をするための IAM ロール、および Grafana ワークスペースの作成を行います。Grafana は現在は L1 Construct のみの提供となります。
import {
aws_grafana,
aws_iam,
Stack,
StackProps,
CfnOutput,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkSampleStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
// Grafana Workspace 用の IAM Role を作成
const principal = new aws_iam.ServicePrincipal(
'grafana.amazonaws.com'
).withConditions({
StringEquals: {
'aws:SourceAccount': this.account,
},
StringLike: {
'aws:SourceArn': `arn:aws:grafana:${this.region}:${this.account}:/workspaces/*`,
},
});
const grafanaRole = new aws_iam.Role(this, 'GrafanaRole', {
assumedBy: principal,
});
// Grafana Workspace を作成
const cfnWorkspace = new aws_grafana.CfnWorkspace(this, 'Workspace', {
accountAccessType: 'CURRENT_ACCOUNT',
authenticationProviders: ['SAML'],
permissionType: 'SERVICE_MANAGED',
roleArn: grafanaRole.roleArn,
});
const workspaceId = cfnWorkspace.ref;
// Service provider identifier (Entity ID) の出力
new CfnOutput(this, 'WorkspaceServiceProviderIdentifier', {
value: `https://${workspaceId}.grafana-workspace.${this.region}.amazonaws.com/saml/metadata`,
});
// Service provider reply URL (Assertion consumer service URL) の出力
new CfnOutput(this, 'WorkspaceServiceProviderReplyUrl', {
value: `https://${workspaceId}.grafana-workspace.${this.region}.amazonaws.com/saml/acs`,
});
}
}
ロールの作成部分については、マネジメントコンソールからのワークスペース作成時に自動作成されるロールと同等の Condition を設定したかったので、以下を参考に設定しています。
また、SAML の構成時に指定が必要な Service provider identifier および Service provider reply URL を出力しています。
SAML の構成(IdP 側)
下記を参考に Grafana ワークスペースと、IdP となる Auth0 との SAML 連携を構成します。
Auth0 で作成した Web App の SAML 設定で、Application Callback URL に Service provider reply URL (/acs
で終わる方)を、また Settings に Service provider reply URL (/acs
で終わる方) および Service provider identifier (/metadata
で終わる方)を記載した下記の JSON を設定します。
{
"audience": "<Service provider identifier (/metadata で終わる方)>",
"destination": "<Service provider reply URL (/acs で終わる方)>",
"mappings": {
"email": "email",
"nickname": "nickname"
},
"createUpnClaim": false,
"passthroughClaimsWithNoMapping": false,
"mapUnknownClaimsAsIs": false
}
そして Identity Provider Metadata の URL を(ダウンロードではなく)コピーします。https://<TenantName>.jp.auth0.com/samlp/metadata/<ID>
のような URL になります。
SAML の構成(Grafana ワークスペース側)
そして、2 回目の CDK デプロイでは samlConfiguration を構成しますが、ここで先ほどの Identity Provider Metadata の URL を Grafana ワークスペースに設定します。
import {
aws_grafana,
aws_iam,
Stack,
StackProps,
CfnOutput,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
interface CdkSampleStackProps extends StackProps {
readonly grafanaWorkspaceSamlAdminRoles: string[];
readonly grafanaWorkspaceSamlEditorRoles: string[];
readonly grafanaWorkspaceSamlIdpMetadataUrl: string;
}
export class CdkSampleStack extends Stack {
constructor(scope: Construct, id: string, props: CdkSampleStackProps) {
super(scope, id, props);
// Grafana Workspace 用の IAM Role を作成
const principal = new aws_iam.ServicePrincipal(
'grafana.amazonaws.com'
).withConditions({
StringEquals: {
'aws:SourceAccount': this.account,
},
StringLike: {
'aws:SourceArn': `arn:aws:grafana:${this.region}:${this.account}:/workspaces/*`,
},
});
const grafanaRole = new aws_iam.Role(this, 'GrafanaRole', {
assumedBy: principal,
});
// Grafana Workspace を作成
const cfnWorkspace = new aws_grafana.CfnWorkspace(this, 'Workspace', {
accountAccessType: 'CURRENT_ACCOUNT',
authenticationProviders: ['SAML'],
permissionType: 'SERVICE_MANAGED',
roleArn: grafanaRole.roleArn,
samlConfiguration: {
assertionAttributes: {
name: 'nickname',
login: 'email',
email: 'email',
role: 'email', // どの SAML 属性をロールのアサーションに使用するか(Assertion attribute role)を指定
},
loginValidityDuration: 1440,
roleValues: {
admin: props.grafanaWorkspaceSamlAdminRoles,
editor: props.grafanaWorkspaceSamlEditorRoles,
},
idpMetadata: {
url: props.grafanaWorkspaceSamlIdpMetadataUrl,
},
},
});
const workspaceId = cfnWorkspace.ref;
// Grafana workspace URL の出力
new CfnOutput(this, 'WorkspaceServiceProviderIdentifier', {
value: `https://${workspaceId}.grafana-workspace.${this.region}.amazonaws.com`,
});
}
}
動作確認
出力された Grafana workspace URL からワークスペースにアクセスしてみます。
samlConfiguration.roleValues.admin
で指定した管理者ユーザーでログインすると、管理者権限のメニューにアクセスできるようになっています。
ユーザー一覧を見ると、samlConfiguration
のroleValues
で指定した管理者権限と編集者権限のユーザーが確認できます。
またプロファイルを見ると、samlConfiguration.assertionAttributes
で指定したアサーション属性がマッピングされていることが確認できます。
おわりに
Amazon Managed Grafana ワークスペースの作成と SAML の構成を AWS CDK で行ってみました。
どなたかの参考になれば幸いです。
参考
以上