diff --git a/framework/.projen/tasks.json b/framework/.projen/tasks.json index a04d55813..22a3a4627 100644 --- a/framework/.projen/tasks.json +++ b/framework/.projen/tasks.json @@ -75,6 +75,9 @@ { "exec": "rsync -avr --exclude '*.ts' --exclude '*.js' src/consumption/lib/redshift/resources lib/consumption/lib/redshift" }, + { + "exec": "rsync -avr --exclude '*.ts' --exclude '*.js' src/consumption/lib/quicksight/resources lib/consumption/lib/quicksight" + }, { "exec": "rsync -avr --exclude '*.ts' --exclude '*.js' src/consumption/lib/opensearch/resources lib/consumption/lib/opensearch" } diff --git a/framework/API.md b/framework/API.md index 4ff630071..694292087 100644 --- a/framework/API.md +++ b/framework/API.md @@ -4441,6 +4441,374 @@ public readonly DSF_TRACKING_CODE: string; --- +### QuickSightSubscription + +Creates an asynchronous custom resource that handles the creation of a QuickSight subscription. + +*Example* + +```typescript +const subscription = new dsf.consumption.QuickSightSubscription(this, 'RedshiftNamespace', { + name: "default", + dbName: 'defaultdb', +}); +``` + + +#### Initializers + +```typescript +import { consumption } from '@cdklabs/aws-data-solutions-framework' + +new consumption.QuickSightSubscription(scope: Construct, id: string, props: QuickSightSubscriptionProps) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| scope | constructs.Construct | *No description.* | +| id | string | *No description.* | +| props | @cdklabs/aws-data-solutions-framework.consumption.QuickSightSubscriptionProps | *No description.* | + +--- + +##### `scope`Required + +- *Type:* constructs.Construct + +--- + +##### `id`Required + +- *Type:* string + +--- + +##### `props`Required + +- *Type:* @cdklabs/aws-data-solutions-framework.consumption.QuickSightSubscriptionProps + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toString | Returns a string representation of this construct. | +| createQuickSightSubscription | *No description.* | +| retrieveVersion | Retrieve DSF package.json version. | + +--- + +##### `toString` + +```typescript +public toString(): string +``` + +Returns a string representation of this construct. + +##### `createQuickSightSubscription` + +```typescript +public createQuickSightSubscription(): CustomResource +``` + +##### `retrieveVersion` + +```typescript +public retrieveVersion(): any +``` + +Retrieve DSF package.json version. + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| isConstruct | Checks if `x` is a construct. | + +--- + +##### `isConstruct` + +```typescript +import { consumption } from '@cdklabs/aws-data-solutions-framework' + +consumption.QuickSightSubscription.isConstruct(x: any) +``` + +Checks if `x` is a construct. + +Use this method instead of `instanceof` to properly detect `Construct` +instances, even when the construct library is symlinked. + +Explanation: in JavaScript, multiple copies of the `constructs` library on +disk are seen as independent, completely different libraries. As a +consequence, the class `Construct` in each copy of the `constructs` library +is seen as a different class, and an instance of one class will not test as +`instanceof` the other class. `npm install` will not create installations +like this, but users may manually symlink construct libraries together or +use a monorepo tool: in those cases, multiple copies of the `constructs` +library can be accidentally installed, and `instanceof` will behave +unpredictably. It is safest to avoid using `instanceof`, and using +this type-testing method instead. + +###### `x`Required + +- *Type:* any + +Any object. + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| accountName | string | The name of your Amazon QuickSight account. | +| adminGroup | string[] | The admin group associated with your Active Directory or IAM Identity Center account. | +| authorGroup | string[] | The author group associated with your IAM Identity Center account. | +| executionRole | aws-cdk-lib.aws_iam.IRole | The IAM Role for the QuickSight account subscription execution. | +| identityRegion | string | The region to use as main QuickSight region (used to store configuration and identities info). | +| notificationEmail | string | The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. | +| readerGroup | string[] | The reader group associated with your IAM Identity Center account. | +| statusFunction | aws-cdk-lib.aws_lambda.IFunction | The Lambda Function for the QuickSight account subscription status checks. | +| statusLogGroup | aws-cdk-lib.aws_logs.ILogGroup | The CloudWatch Log Group for the QuickSight account subscription status checks. | +| submitFunction | aws-cdk-lib.aws_lambda.IFunction | The Lambda Function for the the Redshift Data submission. | +| submitLogGroup | aws-cdk-lib.aws_logs.ILogGroup | The CloudWatch Log Group for the QuickSight account subscription submission. | +| cleanUpFunction | aws-cdk-lib.aws_lambda.IFunction | The Lambda function for the QuickSight account subscription cleaning up lambda. | +| cleanUpLogGroup | aws-cdk-lib.aws_logs.ILogGroup | The CloudWatch Log Group for the QuickSight account subscription cleaning up lambda. | +| cleanUpRole | aws-cdk-lib.aws_iam.IRole | The IAM Role for the the QuickSight account subscription cleaning up lambda. | + +--- + +##### `node`Required + +```typescript +public readonly node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `accountName`Required + +```typescript +public readonly accountName: string; +``` + +- *Type:* string + +The name of your Amazon QuickSight account. + +This name is unique over all of Amazon Web Services, and it appears only when users sign in. +You can't change AccountName value after the Amazon QuickSight account is created. + +--- + +##### `adminGroup`Required + +```typescript +public readonly adminGroup: string[]; +``` + +- *Type:* string[] + +The admin group associated with your Active Directory or IAM Identity Center account. + +This field is required as IAM_IDENTITY_CENTER is +the only supported authentication method of the new Amazon QuickSight account + +--- + +##### `authorGroup`Required + +```typescript +public readonly authorGroup: string[]; +``` + +- *Type:* string[] + +The author group associated with your IAM Identity Center account. + +--- + +##### `executionRole`Required + +```typescript +public readonly executionRole: IRole; +``` + +- *Type:* aws-cdk-lib.aws_iam.IRole + +The IAM Role for the QuickSight account subscription execution. + +--- + +##### `identityRegion`Required + +```typescript +public readonly identityRegion: string; +``` + +- *Type:* string + +The region to use as main QuickSight region (used to store configuration and identities info). + +--- + +##### `notificationEmail`Required + +```typescript +public readonly notificationEmail: string; +``` + +- *Type:* string + +The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. + +--- + +##### `readerGroup`Required + +```typescript +public readonly readerGroup: string[]; +``` + +- *Type:* string[] + +The reader group associated with your IAM Identity Center account. + +--- + +##### `statusFunction`Required + +```typescript +public readonly statusFunction: IFunction; +``` + +- *Type:* aws-cdk-lib.aws_lambda.IFunction + +The Lambda Function for the QuickSight account subscription status checks. + +--- + +##### `statusLogGroup`Required + +```typescript +public readonly statusLogGroup: ILogGroup; +``` + +- *Type:* aws-cdk-lib.aws_logs.ILogGroup + +The CloudWatch Log Group for the QuickSight account subscription status checks. + +--- + +##### `submitFunction`Required + +```typescript +public readonly submitFunction: IFunction; +``` + +- *Type:* aws-cdk-lib.aws_lambda.IFunction + +The Lambda Function for the the Redshift Data submission. + +--- + +##### `submitLogGroup`Required + +```typescript +public readonly submitLogGroup: ILogGroup; +``` + +- *Type:* aws-cdk-lib.aws_logs.ILogGroup + +The CloudWatch Log Group for the QuickSight account subscription submission. + +--- + +##### `cleanUpFunction`Optional + +```typescript +public readonly cleanUpFunction: IFunction; +``` + +- *Type:* aws-cdk-lib.aws_lambda.IFunction + +The Lambda function for the QuickSight account subscription cleaning up lambda. + +--- + +##### `cleanUpLogGroup`Optional + +```typescript +public readonly cleanUpLogGroup: ILogGroup; +``` + +- *Type:* aws-cdk-lib.aws_logs.ILogGroup + +The CloudWatch Log Group for the QuickSight account subscription cleaning up lambda. + +--- + +##### `cleanUpRole`Optional + +```typescript +public readonly cleanUpRole: IRole; +``` + +- *Type:* aws-cdk-lib.aws_iam.IRole + +The IAM Role for the the QuickSight account subscription cleaning up lambda. + +--- + +#### Constants + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| DSF_OWNED_TAG | string | *No description.* | +| DSF_TRACKING_CODE | string | *No description.* | +| RESOURCE_TYPE | string | *No description.* | + +--- + +##### `DSF_OWNED_TAG`Required + +```typescript +public readonly DSF_OWNED_TAG: string; +``` + +- *Type:* string + +--- + +##### `DSF_TRACKING_CODE`Required + +```typescript +public readonly DSF_TRACKING_CODE: string; +``` + +- *Type:* string + +--- + +##### `RESOURCE_TYPE`Required + +```typescript +public readonly RESOURCE_TYPE: string; +``` + +- *Type:* string + +--- + ### RedshiftData Creates an asynchronous custom resource that handles the execution of SQL using Redshift's Data API. @@ -10345,6 +10713,184 @@ This is the output path used in the `venv-pack -o` command in your Dockerfile. --- +### QuickSightSubscriptionProps + +The properties for the `QuickSightSubscription` construct. + +#### Initializer + +```typescript +import { consumption } from '@cdklabs/aws-data-solutions-framework' + +const quickSightSubscriptionProps: consumption.QuickSightSubscriptionProps = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| accountName | string | The name of your Amazon QuickSight account. | +| adminGroup | string[] | The admin group associated with your Active Directory or IAM Identity Center account. | +| authenticationMethod | @cdklabs/aws-data-solutions-framework.consumption.QuickSightAuthenticationMethod | The method that you want to use to authenticate your Amazon QuickSight account. | +| authorGroup | string[] | The author group associated with your IAM Identity Center account. | +| awsAccountId | string | The Amazon Web Services account ID of the account that you're using to create your Amazon QuickSight account. | +| edition | @cdklabs/aws-data-solutions-framework.consumption.QuickSightEdition | The edition of Amazon QuickSight that you want your account to have. | +| identityRegion | string | The region to use as main QuickSight region (used to store configuration and identities info). | +| notificationEmail | string | The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. | +| readerGroup | string[] | The reader group associated with your IAM Identity Center account. | +| executionTimeout | aws-cdk-lib.Duration | The timeout for the QuickSight account subscription. | +| removalPolicy | aws-cdk-lib.RemovalPolicy | The removal policy when deleting the CDK resource. | + +--- + +##### `accountName`Required + +```typescript +public readonly accountName: string; +``` + +- *Type:* string + +The name of your Amazon QuickSight account. + +This name is unique over all of Amazon Web Services, and it appears only when users sign in. +You can't change AccountName value after the Amazon QuickSight account is created. + +--- + +##### `adminGroup`Required + +```typescript +public readonly adminGroup: string[]; +``` + +- *Type:* string[] + +The admin group associated with your Active Directory or IAM Identity Center account. + +This field is required as IAM_IDENTITY_CENTER is +the only supported authentication method of the new Amazon QuickSight account + +--- + +##### `authenticationMethod`Required + +```typescript +public readonly authenticationMethod: QuickSightAuthenticationMethod; +``` + +- *Type:* @cdklabs/aws-data-solutions-framework.consumption.QuickSightAuthenticationMethod + +The method that you want to use to authenticate your Amazon QuickSight account. + +Only IAM_IDENTITY_CENTER, IAM_AND_QUICKSIGHT and IAM_ONLY are supported + +--- + +##### `authorGroup`Required + +```typescript +public readonly authorGroup: string[]; +``` + +- *Type:* string[] + +The author group associated with your IAM Identity Center account. + +--- + +##### `awsAccountId`Required + +```typescript +public readonly awsAccountId: string; +``` + +- *Type:* string + +The Amazon Web Services account ID of the account that you're using to create your Amazon QuickSight account. + +--- + +##### `edition`Required + +```typescript +public readonly edition: QuickSightEdition; +``` + +- *Type:* @cdklabs/aws-data-solutions-framework.consumption.QuickSightEdition +- *Default:* ENTERPRISE is used as default. + +The edition of Amazon QuickSight that you want your account to have. + +Currently, you can choose from ENTERPRISE or ENTERPRISE_AND_Q . + +--- + +##### `identityRegion`Required + +```typescript +public readonly identityRegion: string; +``` + +- *Type:* string + +The region to use as main QuickSight region (used to store configuration and identities info). + +--- + +##### `notificationEmail`Required + +```typescript +public readonly notificationEmail: string; +``` + +- *Type:* string + +The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. + +--- + +##### `readerGroup`Required + +```typescript +public readonly readerGroup: string[]; +``` + +- *Type:* string[] + +The reader group associated with your IAM Identity Center account. + +--- + +##### `executionTimeout`Optional + +```typescript +public readonly executionTimeout: Duration; +``` + +- *Type:* aws-cdk-lib.Duration +- *Default:* 5mins + +The timeout for the QuickSight account subscription. + +--- + +##### `removalPolicy`Optional + +```typescript +public readonly removalPolicy: RemovalPolicy; +``` + +- *Type:* aws-cdk-lib.RemovalPolicy +- *Default:* The resources are not deleted (`RemovalPolicy.RETAIN`). + +The removal policy when deleting the CDK resource. + +If DESTROY is selected, context value `@data-solutions-framework-on-aws/removeDataOnDestroy` needs to be set to true. +Otherwise, the removalPolicy is reverted to RETAIN. + +--- + ### RedshiftDataProps The properties for the `RedshiftData` construct. @@ -13150,6 +13696,48 @@ Default Node Instances for OpenSearch cluster. --- +### QuickSightAuthenticationMethod + +#### Members + +| **Name** | **Description** | +| --- | --- | +| IAM_IDENTITY_CENTER | *No description.* | +| IAM_AND_QUICKSIGHT | *No description.* | +| IAM_ONLY | *No description.* | + +--- + +##### `IAM_IDENTITY_CENTER` + +--- + + +##### `IAM_AND_QUICKSIGHT` + +--- + + +##### `IAM_ONLY` + +--- + + +### QuickSightEdition + +#### Members + +| **Name** | **Description** | +| --- | --- | +| ENTERPRISE | *No description.* | + +--- + +##### `ENTERPRISE` + +--- + + ### RedshiftServerlessNamespaceLogExport Namespace log export types. diff --git a/framework/src/consumption/lib/index.ts b/framework/src/consumption/lib/index.ts index 81417237b..eafae641c 100644 --- a/framework/src/consumption/lib/index.ts +++ b/framework/src/consumption/lib/index.ts @@ -4,3 +4,4 @@ export * from './redshift'; export * from './athena'; export * from './opensearch'; +export * from './quicksight'; diff --git a/framework/src/consumption/lib/quicksight/index.ts b/framework/src/consumption/lib/quicksight/index.ts new file mode 100644 index 000000000..5f56f977c --- /dev/null +++ b/framework/src/consumption/lib/quicksight/index.ts @@ -0,0 +1,5 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +export * from './quicksight-subscription'; +export * from './quicksight-subscription-props'; \ No newline at end of file diff --git a/framework/src/consumption/lib/quicksight/quicksight-subscription-props.ts b/framework/src/consumption/lib/quicksight/quicksight-subscription-props.ts new file mode 100644 index 000000000..fbc3bd71c --- /dev/null +++ b/framework/src/consumption/lib/quicksight/quicksight-subscription-props.ts @@ -0,0 +1,91 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { Duration, RemovalPolicy } from 'aws-cdk-lib'; + + +/** + * The properties for the `QuickSightSubscription` construct + */ + +export interface QuickSightSubscriptionProps { + + /** + * The name of your Amazon QuickSight account. + * This name is unique over all of Amazon Web Services, and it appears only when users sign in. + * You can't change AccountName value after the Amazon QuickSight account is created. + */ + readonly accountName: string; + + /** + * The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. + */ + readonly notificationEmail: string; + + /** + * The edition of Amazon QuickSight that you want your account to have. Currently, you can choose from ENTERPRISE or ENTERPRISE_AND_Q . + * @default - ENTERPRISE is used as default. + */ + readonly edition: QuickSightEdition; + + /** + * The Amazon Web Services account ID of the account that you're using to create your Amazon QuickSight account. + */ + readonly awsAccountId: string; + + + /** + * The method that you want to use to authenticate your Amazon QuickSight account. + * Only IAM_IDENTITY_CENTER, IAM_AND_QUICKSIGHT and IAM_ONLY are supported + * @default + */ + readonly authenticationMethod: QuickSightAuthenticationMethod; + + + /** + * The admin group associated with your Active Directory or IAM Identity Center account. This field is required as IAM_IDENTITY_CENTER is + * the only supported authentication method of the new Amazon QuickSight account + */ + readonly adminGroup: string[]; + + + /** + * The author group associated with your IAM Identity Center account. + */ + readonly authorGroup: string[]; + + /** + * The reader group associated with your IAM Identity Center account. + */ + readonly readerGroup: string[]; + + /** + * The region to use as main QuickSight region (used to store configuration and identities info) + */ + readonly identityRegion: string; + + /** + * The timeout for the QuickSight account subscription. + * @default - 5mins + */ + readonly executionTimeout?: Duration; + + /** + * The removal policy when deleting the CDK resource. + * If DESTROY is selected, context value `@data-solutions-framework-on-aws/removeDataOnDestroy` needs to be set to true. + * Otherwise, the removalPolicy is reverted to RETAIN. + * @default - The resources are not deleted (`RemovalPolicy.RETAIN`). + */ + readonly removalPolicy?: RemovalPolicy; + +} + +export enum QuickSightAuthenticationMethod { + IAM_IDENTITY_CENTER = 'IAM_IDENTITY_CENTER', + IAM_AND_QUICKSIGHT = 'IAM_AND_QUICKSIGHT', + IAM_ONLY = 'IAM_ONLY' +} + +export enum QuickSightEdition { + ENTERPRISE = 'ENTERPRISE', +} \ No newline at end of file diff --git a/framework/src/consumption/lib/quicksight/quicksight-subscription.ts b/framework/src/consumption/lib/quicksight/quicksight-subscription.ts new file mode 100644 index 000000000..a252360e3 --- /dev/null +++ b/framework/src/consumption/lib/quicksight/quicksight-subscription.ts @@ -0,0 +1,229 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { CustomResource, Duration, RemovalPolicy } from 'aws-cdk-lib'; +import { IRole, PolicyDocument, Role, ServicePrincipal, PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam'; +import { IFunction } from 'aws-cdk-lib/aws-lambda'; +import { ILogGroup } from 'aws-cdk-lib/aws-logs'; +import { Construct } from 'constructs'; +import { QuickSightSubscriptionProps, QuickSightAuthenticationMethod } from './quicksight-subscription-props'; +import { Context, TrackedConstruct, TrackedConstructProps } from '../../../utils'; +import { DsfProvider } from '../../../utils/lib/dsf-provider'; + + +/** + * Creates an asynchronous custom resource that handles the creation of a QuickSight subscription + * + * @example + * const subscription = new dsf.consumption.QuickSightSubscription(this, 'RedshiftNamespace', { + * name: "default", + * dbName: 'defaultdb', + * }); + * + */ + +export class QuickSightSubscription extends TrackedConstruct { + + /** + * + */ + public static readonly RESOURCE_TYPE = 'Custom::QuickSightSubscription'; + + /** + * The CloudWatch Log Group for the QuickSight account subscription submission + */ + public readonly submitLogGroup: ILogGroup; + /** + * The Lambda Function for the the Redshift Data submission + */ + public readonly submitFunction: IFunction; + /** + * The IAM Role for the QuickSight account subscription execution + */ + public readonly executionRole: IRole; + + /** + * The CloudWatch Log Group for the QuickSight account subscription status checks + */ + public readonly statusLogGroup: ILogGroup; + /** + * The Lambda Function for the QuickSight account subscription status checks + */ + public readonly statusFunction: IFunction; + + /** + * The CloudWatch Log Group for the QuickSight account subscription cleaning up lambda + */ + public readonly cleanUpLogGroup?: ILogGroup; + /** + * The Lambda function for the QuickSight account subscription cleaning up lambda + */ + public readonly cleanUpFunction?: IFunction; + /** + * The IAM Role for the the QuickSight account subscription cleaning up lambda + */ + public readonly cleanUpRole?: IRole; + + /** + * The name of your Amazon QuickSight account. This name is unique over all of Amazon Web Services, and it appears only when users sign in. + * You can't change AccountName value after the Amazon QuickSight account is created. + */ + public readonly accountName: string; + + /** + * The email address that you want Amazon QuickSight to send notifications to regarding your Amazon QuickSight account or Amazon QuickSight subscription. + */ + readonly notificationEmail: string; + + /** + * The admin group associated with your Active Directory or IAM Identity Center account. This field is required as IAM_IDENTITY_CENTER is + * the only supported authentication method of the new Amazon QuickSight account + */ + readonly adminGroup: string[]; + + /** + * The author group associated with your IAM Identity Center account. + */ + readonly authorGroup: string[]; + + /** + * The reader group associated with your IAM Identity Center account. + */ + readonly readerGroup: string[]; + + /** + * The region to use as main QuickSight region (used to store configuration and identities info) + */ + readonly identityRegion: string; + + private readonly removalPolicy: RemovalPolicy; + + private readonly serviceToken: string; + private readonly policyActions: string[]; + + constructor (scope: Construct, id: string, props: QuickSightSubscriptionProps) { + const trackedConstructProps: TrackedConstructProps = { + trackingTag: QuickSightSubscription.name, + }; + super(scope, id, trackedConstructProps); + + this.removalPolicy = Context.revertRemovalPolicy(scope, props.removalPolicy); + this.accountName = props.accountName; + this.notificationEmail = props.notificationEmail; + this.adminGroup = props.adminGroup; + this.authorGroup = props.authorGroup; + this.readerGroup = props.readerGroup; + this.identityRegion = props.identityRegion; + + this.policyActions = [ + 'quicksight:Subscribe', + 'quicksight:UpdateAccountSettings', + 'quicksight:Create*', + 'quicksight:Unsubscribe', + 'quicksight:DescribeAccountSubscription', + 'sso:GetManagedApplicationInstance', + 'sso:CreateManagedApplicationInstance', + 'sso:GetManagedApplicationInstance', + 'sso:DeleteManagedApplicationInstance', + 'sso:GetManagedApplicationInstance', + 'sso:DescribeGroup', + 'sso:SearchGroups', + 'sso:GetProfile', + 'sso:AssociateProfile', + 'sso:DisassociateProfile', + 'sso:ListProfiles', + 'sso:ListDirectoryAssociations', + 'sso:DescribeRegisteredRegions', + ]; + + if (props.authenticationMethod != QuickSightAuthenticationMethod.IAM_IDENTITY_CENTER) { + this.policyActions = this.policyActions.concat( + [ + 'ds:AuthorizeApplication', + 'ds:UnauthorizeApplication', + 'ds:CheckAlias', + 'ds:CreateAlias', + 'ds:DescribeDirectories', + 'ds:DescribeTrusts', + 'ds:DeleteDirectory', + 'ds:CreateIdentityPoolDirectory', + ], + ); + } + + this.executionRole = new Role(this, 'Role', { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + inlinePolicies: { + QuickSightSubscription: new PolicyDocument({ + statements: [ + new PolicyStatement({ + effect: Effect.ALLOW, + actions: this.policyActions, + resources: ['*'], + }), + ], + }), + }, + }); + + const timeout = props.executionTimeout ?? Duration.minutes(5); + + const provider = new DsfProvider(this, 'CrProvider', { + providerName: 'QuickSightSubscriptionProvider', + onEventHandlerDefinition: { + depsLockFilePath: __dirname+'/resources/QuickSightSubscription/package-lock.json', + entryFile: __dirname+'/resources/QuickSightSubscription/index.mjs', + handler: 'index.onEventHandler', + environment: { + AUTHENTICATION_METHOD: props.authenticationMethod, + AWS_ACCOUNT_ID: props.awsAccountId, + EDITION: props.edition, + IDENTITY_REGION: props.identityRegion, + }, + iamRole: this.executionRole, + timeout, + }, + isCompleteHandlerDefinition: { + iamRole: this.executionRole, + handler: 'index.isCompleteHandler', + depsLockFilePath: __dirname+'/resources/QuickSightSubscription/package-lock.json', + entryFile: __dirname+'/resources/QuickSightSubscription/index.mjs', + timeout, + environment: { + AUTHENTICATION_METHOD: props.authenticationMethod, + AWS_ACCOUNT_ID: props.awsAccountId, + EDITION: props.edition, + IDENTITY_REGION: props.identityRegion, + }, + }, + queryInterval: Duration.seconds(10), + removalPolicy: this.removalPolicy, + }); + + this.serviceToken = provider.serviceToken; + this.submitLogGroup = provider.onEventHandlerLogGroup; + this.statusLogGroup = provider.isCompleteHandlerLog!; + this.cleanUpLogGroup = provider.cleanUpLogGroup; + this.submitFunction = provider.onEventHandlerFunction; + this.statusFunction = provider.isCompleteHandlerFunction!; + this.cleanUpFunction = provider.cleanUpFunction; + this.cleanUpRole = provider.cleanUpRole; + + } + + + public createQuickSightSubscription() { + return new CustomResource(this, 'QuickSightSubscription', { + resourceType: QuickSightSubscription.RESOURCE_TYPE, + serviceToken: this.serviceToken, + properties: { + accountName: this.accountName, + notificationEmail: this.notificationEmail, + readerGroup: this.readerGroup, + authorGroup: this.authorGroup, + adminGroup: this.adminGroup, + }, + removalPolicy: this.removalPolicy, + }); + } +} \ No newline at end of file diff --git a/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/index.mjs b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/index.mjs new file mode 100644 index 000000000..7e05991db --- /dev/null +++ b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/index.mjs @@ -0,0 +1,93 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import {QuickSightClient, CreateAccountSubscriptionCommand, DescribeAccountSubscriptionCommand, UpdateAccountSettingsCommand, DeleteAccountSubscriptionCommand } from "@aws-sdk/client-quicksight" + + +const AuthenticationMethod = process.env.AUTHENTICATION_METHOD +const AwsAccountId = process.env.AWS_ACCOUNT_ID +const Edition = process.env.EDITION +const config = { region: process.env.IDENTITY_REGION } +const client = new QuickSightClient(config) + +export const onEventHandler = async(event) => { + const accountName = event["ResourceProperties"]["accountName"] + const notificationEmail = event["ResourceProperties"]["notificationEmail"] + const authorGroup = event["ResourceProperties"]["authorGroup"] + const adminGroup = event["ResourceProperties"]["adminGroup"] + const readerGroup = event["ResourceProperties"]["readerGroup"] + + if (event["RequestType"] === "Create") { + + const input = { // CreateAccountSubscriptionRequest + Edition: Edition, + AuthenticationMethod: AuthenticationMethod, // required + AwsAccountId: AwsAccountId, // required + AccountName: accountName, // required + NotificationEmail: notificationEmail // required + }; + + if (AuthenticationMethod === "IAM_IDENTITY_CENTER") { + input.AdminGroup = adminGroup + input.AuthorGroup = authorGroup + input.ReaderGroup = readerGroup + } + const execResult = await client.send(new CreateAccountSubscriptionCommand(input)) + + return { + "Data": { + "status": execResult.Status, + "requestId": execResult.RequestId + } + } + } else if (event["RequestType"] === "Delete") { + const execResult = await client.send(new UpdateAccountSettingsCommand({AwsAccountId: AwsAccountId, TerminationProtectionEnabled: false})) + + if (execResult.Status >= 400) { + throw new Error(`Failed to disable termination protection for account ${AwsAccountId}`) + } + const responseDelete = await client.send(new DeleteAccountSubscriptionCommand({AwsAccountId: AwsAccountId})) + + return { + "Data": { + "status": responseDelete.Status, + "requestId": responseDelete.RequestId + } + } + } + + +} + +export const isCompleteHandler = async(event) => { + let isComplete = false + + + + const resp = await client.send(new DescribeAccountSubscriptionCommand({AwsAccountId: AwsAccountId})) + const subscriptionStatus = resp.AccountInfo.AccountSubscriptionStatus + const status = resp.Status + + if (event["RequestType"] === "Create"){ + if (status >= 400) { + throw new Error(`Account subscription failed with status ${subscriptionStatus}`) + } else if (status > 300 && status < 400){ + isComplete = false + } + + isComplete = (status === 200 && subscriptionStatus === "ACCOUNT_CREATED") + } else if (event["RequestType"] === "Delete") { + if (status >= 400) { + throw new Error(`Account deletion failed with status ${subscriptionStatus}`) + } else if (status > 300 && status < 400){ + isComplete = false + } + isComplete = (status === 200 && subscriptionStatus === "UNSUBSCRIBED") + } + + + + return { + "IsComplete": isComplete + } +} \ No newline at end of file diff --git a/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package-lock.json b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package-lock.json new file mode 100644 index 000000000..f58420be6 --- /dev/null +++ b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "quicksight-subscription", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "quicksight-subscription", + "version": "0.1.0" + } + } +} diff --git a/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package.json b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package.json new file mode 100644 index 000000000..cb7ee782f --- /dev/null +++ b/framework/src/consumption/lib/quicksight/resources/QuickSightSubscription/package.json @@ -0,0 +1,4 @@ +{ + "name": "quicksight-subscription", + "version": "0.1.0" +} \ No newline at end of file