Embedded Quicksigth Dashboards

January 2025
Embedded Quicksigth Dashboards

Learn to embed Amazon QuickSight dashboards into your web application using a Cloud first Serverless AWS Stack providing a flexible and powerful BI tool.

What is Amazon QuickSight?

Amazon QuickSight is a powerful business intelligence service that allows you to create interactive dashboards. Embedding QuickSight dashboards into your applications enables users to seamlessly interact with data visualizations without leaving the application.

This architecture demonstrates how to enable secure access to QuickSight dashboards using the following AWS services:

  • API Gateway: Acts as an entry point for client requests.
  • Cognito: Provides user authentication and token-based security.
  • AWS Lambda: Manages custom logic for user migration and generating QuickSight embedded dashboard URLs.
  • Secrets Manager: Securely stores database credentials for integration with RDS.
  • RDS: Serves as the source database for QuickSight.

Key Components for Embedding QuickSight

Cognito:

  • Users log in via Amazon Cognito User Pools.
  • Cognito issues JWT tokens to authenticated users.
  • Tokens are validated by the API Gateway before allowing access to the backend services.

API Gateway:

  • Serves as the front door to the backend services.
  • Handles requests for user migration and QuickSight embedded dashboard URLs.
  • Verifies tokens using a Cognito Authorizer.

Lambda Functions:

  • UserMigration:
    • Migrates users to the application and retrieves credentials from Secrets Manager to interact with the database.
  • QuickSightEmbedded:
    • Generates signed URLs for embedding QuickSight dashboards.

Secrets Manager:

  • Stores and retrieves RDS credentials securely.

RDS:

  • Provides the underlying data source for QuickSight dashboards.

QuickSight:

  • Hosts dashboards and provides the ability to embed them securely.

Step-by-Step Guide to Embedding QuickSight

Step 1: Set Up Cognito User Pool

  1. Create a Cognito User Pool for user authentication.
  2. Enable App Clients to integrate with your web application.
  3. Configure custom attributes (if needed) to manage user-specific settings.

Step 2: Configure API Gateway

  1. Create an HTTP API in API Gateway.
  2. Set up a Cognito JWT Authorizer to validate tokens.
  3. Define routes for:
    • /login β†’ Invokes the UserMigration Lambda function.
    • /embedded-url β†’ Invokes the QuickSightEmbedded Lambda function.

Step 3: Build Lambda Functions

UserMigration Function (/login)

  • Authenticates users by validating credentials.
  • Retrieves RDS credentials from Secrets Manager.
  • Checks or updates the user database.

Here’s an example implementation:

import boto3
import json
import pymysql

secrets_client = boto3.client('secretsmanager')

def lambda_handler(event, context):
    # Retrieve credentials from Secrets Manager
    secret = secrets_client.get_secret_value(SecretId="rds/credentials")
    credentials = json.loads(secret['SecretString'])
    
    connection = pymysql.connect(
        host=credentials['host'],
        user=credentials['username'],
        password=credentials['password'],
        database=credentials['database']
    )
    
    # Process user migration logic here
    body = json.loads(event['body'])
    username = body['username']
    password = body['password']
    
    # Example SQL to check users
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
        user = cursor.fetchone()
        if user:
            return {"statusCode": 200, "body": json.dumps({"message": "User exists"})}
        else:
            return {"statusCode": 401, "body": json.dumps({"message": "User not found"})}

QuickSightEmbedded Function (/embedded-url)

Generates a signed QuickSight URL for embedding a dashboard. Accepts user-specific parameters to filter dashboard content.

import boto3
import json

quicksight_client = boto3.client('quicksight')

def lambda_handler(event, context):
    # Extract user ID and dashboard details from the request
    body = json.loads(event['body'])
    user_arn = body['user_arn']
    dashboard_id = body['dashboard_id']
    
    # Generate QuickSight Embed URL
    response = quicksight_client.get_dashboard_embed_url(
        AwsAccountId="YOUR_ACCOUNT_ID",
        DashboardId=dashboard_id,
        IdentityType="QUICKSIGHT",
        UserArn=user_arn,
        SessionLifetimeInMinutes=600
    )
    
    return {
        "statusCode": 200,
        "body": json.dumps({"embed_url": response['EmbedUrl']})
    }

Step 4: Integrate QuickSight with RDS

  1. Connect Amazon QuickSight to your RDS instance.
  2. Create datasets and dashboards using the connected data source.
  3. Ensure that IAM roles and permissions for Lambda and QuickSight are correctly configured.

Adding Security Layers

  • Use AWS Certificate Manager to enable HTTPS on your API Gateway.
  • Store sensitive credentials in Secrets Manager and avoid hardcoding them in your Lambda functions.
  • Use IAM roles with least-privilege access to interact with QuickSight and RDS.

Embedding QuickSight Dashboards for Anonymous Users

Amazon QuickSight provides the capability to embed BI dashboards for anonymous (unregistered) users, enabling broader access without necessitating individual QuickSight accounts. This feature is particularly useful for public websites or applications where user authentication is managed externally.

Prerequisites

  • Amazon QuickSight Enterprise Edition: Anonymous embedding is available only in the Enterprise Edition.
  • Session Capacity Pricing: Ensure your AWS account has session capacity pricing enabled to support anonymous sessions.
  • IAM Role with Appropriate Permissions: Create an IAM role that grants the necessary permissions for generating embed URLs.

Step 1: Create and Deploy Your Infrastructure CDK Stack

Create and deploy an AWS CDK stack that sets up the necessary IAM roles and permissions for anonymous embedding. This stack will configure:

  1. IAM roles with appropriate QuickSight permissions
  2. Lambda function for generating embed URLs
  3. API Gateway for frontend access

Here's an example CDK implementation:

from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigateway,
    aws_iam as iam,
    Stack,
    CfnOutput,
    Aws,
    Duration
)

from constructs import Construct


class QuicksigthShareDashboardsStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # IAM Role for Lambda to interact with QuickSight
        quicksight_lambda_role = iam.Role(
            self, "QuickSightLambdaRole",
            assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
            managed_policies=[
                iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaBasicExecutionRole"),
            ]
        )

        quicksight_lambda_role.attach_inline_policy(
            iam.Policy(
                self, "QuickSightLambdaPolicy",
                statements=[
                    iam.PolicyStatement(
                        actions=[
                            "quicksight:GenerateEmbedUrlForAnonymousUser",
                        ],
                        resources=[
                            "arn:aws:quicksight:us-east-1:123456789012:dashboard/DashboardId",
                            "arn:aws:quicksight:us-east-1:123456789012:namespace/default"
                        ]
                    )
                ]
            )
        
        )

        # Lambda function
        lambda_function = _lambda.Function(
            self, "QuickSightEmbedLambda",
            runtime=_lambda.Runtime.PYTHON_3_12,
            handler="share_dashboards.lambda_handler",
            code=_lambda.Code.from_asset("lambda/embeded-dashboard"),
            environment={
                "AWS_ACCOUNT_ID": Aws.ACCOUNT_ID,
                "QUICKSIGHT_NAMESPACE": "default"  # Update if needed
            },
            role=quicksight_lambda_role
        )

        # API Gateway
        api = apigateway.LambdaRestApi(
            self, "QuickSightEmbedAPI",
            handler=lambda_function,
            proxy=False,
            default_cors_preflight_options=apigateway.CorsOptions(
                allow_origins=['https://yourdomain.com'],  # In production, replace with specific origins
                allow_methods=['GET', 'POST', 'OPTIONS'],
                allow_headers=['Content-Type', 'Authorization'],
                allow_credentials=True,
                max_age=Duration.minutes(60)  # Optional: cache preflight results for 60 minutes
            )
        )

        # API resource and method
        embed_resource = api.root.add_resource("embedded-url")
        embed_resource.add_method("GET")

        CfnOutput(self, "APIEndpoint", value=api.url)


Replace DashboardId with your actual dashboard ID and yourdomain.com with the domain where the dashboard will be embedded.

Step 2: Generate Embed URL

Use the GenerateEmbedUrlForAnonymousUser API to create a signed URL for embedding. This operation should be performed server-side to maintain security. Here's an example using Python and Boto3:

import boto3

client = boto3.client('quicksight')

session_tags = [
    {
        'Key': 'company_id',
        'Value': company_id
    },
    {
        'Key': 'branch_id',
        'Value': branch_id
    },
]

# Call QuickSight API to generate embed URL for anonymous users
response = quicksight.generate_embed_url_for_anonymous_user(
    AwsAccountId=AWS_ACCOUNT_ID,
    Namespace=NAMESPACE,
    ExperienceConfiguration={
        "Dashboard": {
            "InitialDashboardId": dashboard_id
        }
    },
    AuthorizedResourceArns=[
        f"arn:aws:quicksight:{AWS_REGION}:{AWS_ACCOUNT_ID}:dashboard/{dashboard_id}"
    ],
    SessionTags=session_tags,
    SessionLifetimeInMinutes=600
)

embed_url = response['EmbedUrl']

Ensure that the AuthorizedResourceArns includes the ARN of the dashboard you intend to embed. The session tags can be use to restrict data visibility on dashboards.

Step 3: Embed Dashboard in Application

In your web application, use the Amazon QuickSight Embedding SDK to embed the dashboard using the generated URL. Here's a basic example:

<!DOCTYPE html>
<html>
<head>
  <title>Embedded QuickSight Dashboard</title>
  <script src="https://unpkg.com/amazon-quicksight-embedding-sdk@2.0.0/dist/quicksight-embedding-js-sdk.min.js"></script>
</head>
<body>
  <div id="dashboardContainer" style="height:700px;width:1000px;"></div>
  <script type="text/javascript">
    const containerDiv = document.getElementById("dashboardContainer");
    const options = {
      url: "https://yourdomain.com/embedded-dashboard-url",
      container: containerDiv,
      scrolling: "no",
      height: "700px",
      width: "1000px"
    };
    const dashboard = QuickSightEmbedding.embedDashboard(options);
  </script>
</body>
</html>

Replace "https://yourdomain.com/embedded-dashboard-url" with the actual embed URL obtained from the previous step.


By following these steps, you can successfully embed Amazon QuickSight dashboards for anonymous users, providing seamless access to data visualizations without requiring individual QuickSight accounts.

For more detailed information, refer to the official AWS documentation: Embedding QuickSight dashboards for anonymous users.

Conclusion

With this architecture, you can securely embed Amazon QuickSight dashboards into your web application using two different approaches:

  1. For Registered Users: The combination of API Gateway, Lambda, and Cognito provides a robust authentication system that ensures only properly authenticated users can access personalized dashboards while maintaining security.
  2. For Anonymous Users: When broader access is needed without user registration, QuickSight's anonymous embedding capability (available in Enterprise Edition) enables you to share dashboards publicly while maintaining control through session capacity pricing.

Both approaches offer flexibility and scalability, allowing you to choose the right embedding strategy based on your application's specific audience and security requirements.

For detailed documentation, refer to the Amazon QuickSight Embedding Guide.

Related Articles

For deeper insights and to extend this solution, check out these related posts: