5k-pattern-quicksight-embedding
-
Report Creation - Manual Step
-
Report Deployment Scripts
-
Making artifacts created in step-1 part of code repository
-
Sharing artifacts with cli user
Normally at the structure is in AWS Rewrite projects. The user accounts are connected to adfs. So every dev creates a cli user. If the reports are not shared with the cli user then. You won’t be able to execute commands related to description of the artifacts
-
-
directory structure
quicksight templates analysis-templates report-analysis-1.json dashboards report-dashboard-1.json data-sets data-set-1.json
-
Deployment scripts
-
creating data source
-
copying the data source created
aws quicksight describe-data-source --data-source-id <data-source-id>--aws-account-id <aws-account-id>
-
modifying and creating mustache template
- copy the
response.DataSource
to a separate json file - make the json to match this structure
await this.awsQuicksight.createDataSource({ // AWS_ACCOUNT_ID AwsAccountId: awsAccountId, // Created dtaa source id Ex. <env>_<data_source_name> DataSourceId: dataSourceId, Name: `${stackPrefix} ${context.envType} Reporting DataSource RDS`, Type: 'AURORA', Credentials: { CredentialPair: { // got from stack outputs Username: rdsUsername, // got from stack outputs Password: rdsPassword, }, }, DataSourceParameters: { AuroraParameters: { // got from stackout put Database: dbName, // got from stack outputs Host: stackOutputs[PrefixHandler.handle(context.envType, 'RdsClusterHost')] as string, // got from stack outputs Port: Number(stackOutputs[PrefixHandler.handle(context.envType, 'RdsClusterPort')]), }, }, // superUserArns - just a static list of users this entity should be shared with Permissions: superUserArns.map(arn => ({ Principal: arn, Actions: [ 'quicksight:UpdateDataSourcePermissions', 'quicksight:DescribeDataSource', 'quicksight:DescribeDataSourcePermissions', 'quicksight:PassDataSource', 'quicksight:UpdateDataSource', 'quicksight:DeleteDataSource', ], })), }).promise();
- copy the
-
-
-
Organization / customer creation scripts
Every Template being used below wil be created for every organization
To ensure only the current organization / cutomer can access its own data filtering in done on datasets-
creating data set
-
copying the data set created
aws quicksight describe-data-set --data-set-id <data-set-id> --aws-account-id <aws-account-id>
-
modifying and creating mustache template
- copy the
response.DataSource
to a separate json file - make the json to match this structure
{ "DataSetId": "{{{DataSetId}}}", // created data source id Ex. orgId_<data_set_name> "Name": "{{{DataSetName}}}", // <org_id> <data_set_name> "PhysicalTableMap": { "5cd7ef53-64db-4c67-87b8-ef4667a7f437": { "RelationalTable": { "DataSourceArn": "{{{RedshiftDataSourceArn}}}", // got from stack output "Schema": "public", "Name": "{{{RedshiftReportingViewName}}}", // hardcoded from migrations "InputColumns": // same as in cli response } }, "75fdea21-aca5-49d5-99d8-23cf72ab2adf": { "RelationalTable": { "DataSourceArn": "{{{AuroraDataSourceArn}}}", // got from stack output "Name": "{{{RDSReportingViewName}}}", // hardcoded from migrations "InputColumns": // same as in cli response } } }, "LogicalTableMap": { "75fdea21-aca5-49d5-99d8-23cf72ab2adf": { "Alias": "{{{RDSReportingViewName}}}", // hardcoded from migrations "Source": { "PhysicalTableId": "75fdea21-aca5-49d5-99d8-23cf72ab2adf" } }, "88385f85-1b68-4553-8ae5-23b784adb455": { "Alias": "Intermediate Table", // same as in the cli response - except for shown properties "DataTransforms": [ { "FilterOperation": { // org_id - got uplon adding to the db or created "ConditionExpression": "{org_id}=\"{{{org_id}}}\"" } }, ], "Source": // same as in response "927c8831-1bd7-4ad9-b170-000341987617": { "Alias": "{{{RedshiftReportingViewName}}}", // hardcoded from migrations "DataTransforms": , // same as in reponse "Source": { "PhysicalTableId": "5cd7ef53-64db-4c67-87b8-ef4667a7f437" } } }, "ImportMode": "SPICE" }
- save in
quicksight > templates > data-sets > data-set-1.json
- copy the
-
-
creating analysis template
-
modifying and creating mustache template
- copy paste the following json structure and replace the values
{ "AwsAccountId": "{{{AwsAccountId}}}", "TemplateId": "{{{TemplateId}}}", "Name": "{{{TemplateName}}}", "SourceEntity": { "SourceAnalysis": { // this value will be hardcoded has this is. This is because it points to the repors // created in step 1 "Arn": "arn:aws:quicksight:<AWS_REGION>:<AWS_ACCOUNT_ID>:analysis/<ANALYSIS_ID>", // All the datasets being using will be listed here "DataSetReferences": [ { "DataSetPlaceholder": "DS1", // this value will be hardcoded has this is. This is because it points to the repors // created in step 1 "DataSetArn": "arn:aws:quicksight:<AWS_REGION>:<AWS_ACCOUNT_ID>:dataset/<DATA_SET_ID>" } ] } }, "VersionDescription": "1" }
- save in
quicksight > templates > analysis-templates > report-analysis-1.json
-
-
creating dashboard
-
copying the data source created
-
modifying and creating mustache template
- copy the
response.DataSource
to a separate json file
aws quicksight describe-dashboard --dashboard-id <dashboard-id> --aws-account-id <aws-account-id>
- make the json to match this structure
{ "AwsAccountId": "{{{AwsAccountId}}}", "DashboardId": "{{{DashboardId}}}", // created through script - Ex. <org_id>-report-dashboard-1.json "Name": "{{{DashboardName}}}", "SourceEntity": { "SourceTemplate": { "DataSetReferences": [ { "DataSetPlaceholder": "DS1", // name of the data-set file created "DataSetArn": "{{{data-set-1}}}" } ], // name of the analysis file created "Arn": "{{{report-analysis-1}}}" } }, "VersionDescription": "1", "DashboardPublishOptions": { "AdHocFilteringOption": { "AvailabilityStatus": "DISABLED" }, "ExportToCSVOption": { "AvailabilityStatus": "ENABLED" }, "SheetControlsOption": { "VisibilityState": "EXPANDED" } } }
- save in
quicksight > templates > dashboards > report-dashboard-1.json
- copy the
-
-
deployment scripts
The related scripts and cliQuicksight scripts is present at
https://gist.github.com/parvaurea/23e9403c353c2c22ef4c2151d9f5362fThe basic flow of deployment scripts is as follows - this is a subset of create customer / organization
console.log('[*] creating quicksight group'); const group = await this.cliQuicksight.createGroup(orgId); console.log('[*] created quicksight group'); console.log('[*] getting super user arns'); const superUserArns = await this.cliQuicksight.getUserArns(this.config.organization.superUsers); console.log('[*] got super user arns'); console.log('[*] creating quicksight reporting data sets'); await this.cliQuicksight.createDatasets( env, envType, orgId, pinpointApp.Id, group, superUserArns, tagsArray, ); console.log('[*] created quicksight reporting data sets'); console.log('[*] creating quicksight reporting templates'); await this.cliQuicksight.createTemplates(orgId, group, superUserArns); console.log('[*] created quicksight reporting templates'); console.log('[*] creating quicksight dashboards'); const dashboards = await this.cliQuicksight.createDashboards(pinpointApp.Id, group, superUserArns, orgId); console.log('[*] created quicksight dashboards'); console.log('[*] creating quicksight dashboards access role'); const generateReportLambdaRoleArn = await this.cliLambda.getLambdaRoleArn('generateReportUrl'); const quicksightAccessRole = await this.cliQuicksight.createDashboardAccessRole( pinpointApp.Id, dashboards, generateReportLambdaRoleArn, tagsArray, ); console.log(`[*] created quicksight dashboards access role : ${quicksightAccessRole.Arn}`); console.log('[*] creating quicksight user'); const quicksightUser = await this.cliQuicksight.createUser(user.email, quicksightAccessRole.Arn); console.log('[*] created quicksight user'); const username = quicksightUser?.UserName || `${quicksightAccessRole.RoleName}/${user.email}`; console.log('[*] adding quicksight user to group'); await this.cliQuicksight.addUserToGroup(username, group.GroupName as string); console.log('[*] added quicksight user to group');
-
-
-
Report Frontend Embedding
- Angular service
import { DOCUMENT } from '@angular/common'; import { Inject, Injectable } from '@angular/core'; import * as QuicksightEmbedding from 'amazon-quicksight-embedding-sdk'; import { Apollo } from 'apollo-angular'; import gql from 'graphql-tag'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root', }) export class ReportsService { public readonly allParamValue = '[ALL]'; constructor( private readonly apollo: Apollo, @Inject(DOCUMENT) private readonly document: Document, @Inject(Window) private readonly window: Window, ) { } public generateReportUrl(dashboardId: string): Observable<string> { return this.apollo .mutate<{ generateReportUrl: string }>({ mutation: gql` mutation generateReportUrl($dashboardId: String!) { generateReportUrl(DashboardId: $dashboardId) } `, variables: { dashboardId, }, }) .pipe(map(res => res.data.generateReportUrl)); } public renderReport(dashboardId: string, elementContainerId: string, params?: any): Observable<void> { return this.generateReportUrl(dashboardId).pipe( map(url => { const container = this.document.getElementById(elementContainerId); container.innerHTML = ''; const dashboard = QuicksightEmbedding.embedDashboard({ url, container, ...this.reportsConfig.default, ...params || {}, parameters: { baseUrl: `${this.window.location.hostname}:${this.window.location.port}`, ...params?.parameters || {}, } }); dashboard.on('error', () => console.log('error rendering report')); }), ); } }
Comments
0 comments
Please sign in to leave a comment.