RUM AppMonitor L2 Construct
See original GitHub issueDescription
I am delighted to be able to create a RUM Monitor with CloudFormation.
However, RUM AppMonitor L1 Construct doesn’t provide code snippet and AppMonitorID, so
to embed client code user must access management console or run AWS CLI for get AppMonitorID after created RUM AppMonitor by RUM AppMonitor L1 Construct. This is a bit far from full automation, so I propose an L2 construct that can solve these problems…
Overview
Define AppMonitor
Define AppMonitor
to your stack:
const appMonitor = new AppMonitor(this, 'AppMonitor', {
domain: 'my-website.com'
});
Authorizer
To use CloudWatch RUM, your application must have authorization.
You have three options to set up authorization:
- Let CloudWatch RUM create a new Amazon Cognito identity pool for the application. This method requires the least effort to set up. It’s the default option. The identity pool will contain an unauthenticated identity. This allows the CloudWatch RUM web client to send data to CloudWatch RUM without authenticating the user of the application. The Amazon Cognito identity pool has an attached IAM role. The Amazon Cognito unauthenticated identity allows the web client to assume the IAM role that is authorized to send data to CloudWatch RUM.
- Use an existing Amazon Cognito identity pool. In this case, you must pass the IAM role as well that is attached to the identity pool.
- Use authentication from an existing identity provider that you have already set up. In this case, you must get credentials from the identity provider and your application must forward these credentials to the RUM web client.
Creates a new Amazon Cognito identity pool
By default, AppMonitor creates a new Amazon Cognito identity pool. This is the simplest option to set up, and if you choose this no further setup steps are required. You must have administrative permissions to use this option. For more information, see IAM policies to use CloudWatch RUM.
const appMonitor = new AppMonitor(this, 'AppMonitor', {
domain: 'my-website.com'
});
Use an existing Amazon Cognito identity pool
If you want to use an existing Amazon Cognito identity pool,
you need to pass the identityPool
and the role
that associated with your identity pool.
import * as identitypool from '@aws-cdk/aws-cognito-identitypool';
import * as iam from '@aws-cdk/aws-iam';
const identityPool = identitypool.IdentityPool.fromIdentityPoolId(this, 'IdentityPool', 'us-east-1:dj2823ryiwuhef937');
const role = iam.Role.fromRoleName(this, 'Role', 'UnauthenticatedRole');
const appMonitor = new AppMonitor(this, 'AppMonitor', {
domain: 'my-website.com',
identityPool,
role
});
Use Third-party provider
If you want to use third-party authenticator, you can only pass a role
that associated with your identity pool.
import * as iam from '@aws-cdk/aws-iam';
declare const role: iam.IRole;
const appMonitor = new AppMonitor(this, 'AppMonitor', {
domain: 'my-website.com',
role
});
Add the following to your application to have it pass the credentials from your provider to CloudWatch RUM. Insert the line so that it runs after a user has signed in to your application and the application has received the credentials to use to access AWS.
cwr('setAwsCredentials', {/* Credentials or CredentialProvider */});
For more information, see Amazon Amazon CloudWatch User Guide for to use Third-party provider.
Code Snippet
AppMonitor generates code snippet as you would create them on the management console, except that there are no <script>
tags.
The reason there is no <script>
tag in the code snippet is that it is intended to be loaded as a regular JavaScript file from your HTML document.
This allows you to seamlessly embed RUM into your application without having to rewrite your HTML document when deploying.
The code snippet is integrated with aws-s3-deployment, so you can deploy directly to any S3 bucket using BucketDeployment.
An example of deploying a static website and code snippet to S3 is shown below.
import * as s3 from '@aws-cdk/aws-s3';
import * as s3deployment from '@aws-cdk/aws-s3-deployment';
declare const myWebSiteBucket: s3.Bucket;
const website = s3deployment.Source.asset(path.join(__dirname, 'my-website'));
const appMonitor = new AppMonitor(this, 'AppMonitor', {
domain: 'my-website.com'
});
new s3deployment.BucketDeployment(this, 'BucketDeployment', {
sources: [website, appMonitor.codeSnippet],
destinationBucket: myWebSiteBucket
});
Your website must load the code snippet with the object key (default: rum.js
).
<html>
<head>
<!-- add next line -->
<script src="/rum.js" async="true"></script>
</head>
<body>Hello RUM</body>
</html>
If you want to use another name for will generates code snippet, then you can pass the objectKey
to addCodeSnippet
argument.
declare const appMonitor: AppMonitor;
const codeSnippet = appMonitor.addCodeSnippet('CodeSnippet', {
objectKey: 'my-rum.js'
});
RUM web client configuration
If you want to use RUM web client configuration (e.g pageIdFormat), you can pass options to addCodeSnippet
argument.
const codeSnippet = appMonitor.addCodeSnippet('CodeSnippet', {
applicationVersion: '1.1.0',
pageIdFormat: PageIdFormat.HASH,
});
Class Diagram
classDiagram
IAppMonitor <|.. AppMonitorBase
AppMonitorBase <|-- AppMonitor
ISource <|.. CodeSnippet
IAppMonitor -- CodeSnippet
class IAppMonitor{
<<interface>>
+string appMonitorId*
+string appMonitorArn*
+string appMonitorName*
+CodeSnippet codeSnippet*
+CodeSnippet addCodeSnippet()*
}
class AppMonitorBase{
<<abstract>>
+string appMonitorId
+string appMonitorArn
+string appMonitorName
+CodeSnippet codeSnippet
+CodeSnippet addCodeSnippet()
}
class AppMonitor{
}
class CodeSnippet{
+string value
+SourceConfig bind()
}
Implementation
RUM AppMonitor L1 Construct doesn’t provide an AppMonitorID so we need to use custom resource for rum:GetAppMonitor. And generate code snippet also needs custom resource because to avoid XSS.
- I may be able to implement this feature request
- This feature might incur a breaking change
Roles
Role | User |
---|---|
Proposed by | @WinterYukky |
Author(s) | @alias, @alias, @alias |
API Bar Raiser | @madeline-k |
Stakeholders | @alias, @alias, @alias |
See RFC Process for details
Workflow
- Tracking issue created (label:
status/proposed
) - API bar raiser assigned (ping us at #aws-cdk-rfcs if needed)
- Kick off meeting
- RFC pull request submitted (label:
status/review
) - Community reach out (via Slack and/or Twitter)
- API signed-off (label
api-approved
applied to pull request) - Final comments period (label:
status/final-comments-period
) - Approved and merged (label:
status/approved
) - Execution plan submitted (label:
status/planning
) - Plan approved and merged (label:
status/implementing
) - Implementation complete (label:
status/done
)
Author is responsible to progress the RFC according to this checklist, and apply the relevant labels to this issue so that the RFC table in README gets updated.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:6
- Comments:10 (8 by maintainers)
Top GitHub Comments
whats the status here? I am refactoring something and would have been the time to remove a double deploy step from my cdn stack. #sadface
We’d love to see this. Any update?