From a1db6398ad36c8c4a97219c44092036ec9f0fd81 Mon Sep 17 00:00:00 2001 From: Troy Parrett Date: Wed, 30 Oct 2024 11:23:57 -0400 Subject: [PATCH 1/3] Initial commit --- typescript/connect-cdk/.gitignore | 8 + typescript/connect-cdk/.npmignore | 6 + typescript/connect-cdk/README.md | 49 ++++++ typescript/connect-cdk/bin/connect_cdk.ts | 12 ++ .../connect-cdk/callFlows/MainFlow.json | 151 ++++++++++++++++++ typescript/connect-cdk/cdk.json | 72 +++++++++ .../hellolambda/lambda_function.py | 20 +++ typescript/connect-cdk/jest.config.js | 8 + .../connect-cdk/lib/connect_cdk-stack.ts | 88 ++++++++++ typescript/connect-cdk/package.json | 28 ++++ .../test/connect_cdk_simple.test.ts | 17 ++ typescript/connect-cdk/tsconfig.json | 31 ++++ 12 files changed, 490 insertions(+) create mode 100644 typescript/connect-cdk/.gitignore create mode 100644 typescript/connect-cdk/.npmignore create mode 100644 typescript/connect-cdk/README.md create mode 100644 typescript/connect-cdk/bin/connect_cdk.ts create mode 100644 typescript/connect-cdk/callFlows/MainFlow.json create mode 100644 typescript/connect-cdk/cdk.json create mode 100644 typescript/connect-cdk/hellolambda/lambda_function.py create mode 100644 typescript/connect-cdk/jest.config.js create mode 100644 typescript/connect-cdk/lib/connect_cdk-stack.ts create mode 100644 typescript/connect-cdk/package.json create mode 100644 typescript/connect-cdk/test/connect_cdk_simple.test.ts create mode 100644 typescript/connect-cdk/tsconfig.json diff --git a/typescript/connect-cdk/.gitignore b/typescript/connect-cdk/.gitignore new file mode 100644 index 0000000000..f60797b6a9 --- /dev/null +++ b/typescript/connect-cdk/.gitignore @@ -0,0 +1,8 @@ +*.js +!jest.config.js +*.d.ts +node_modules + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/connect-cdk/.npmignore b/typescript/connect-cdk/.npmignore new file mode 100644 index 0000000000..c1d6d45dcf --- /dev/null +++ b/typescript/connect-cdk/.npmignore @@ -0,0 +1,6 @@ +*.ts +!*.d.ts + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/connect-cdk/README.md b/typescript/connect-cdk/README.md new file mode 100644 index 0000000000..8a0d787c7e --- /dev/null +++ b/typescript/connect-cdk/README.md @@ -0,0 +1,49 @@ +# Amazon Connect fully deployed with CDK + + +--- + +![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge) + +> **This is a stable example. It should successfully build out of the box** +> +> This example is built on Construct Libraries marked "Stable" and does not have any infrastructure prerequisites to build. +--- + + +## Overview + +A fully infrastructure-as-code Amazon Connect solution that includes a simple call flow itegrated with Lambda. + +## Solution + +Some of the key services in use: +* Amazon Connect +* AWS Lambda + +### Connect Call Flows +The following Connect flows/modules are found in the `callFlows`: +* `MainFlow.json` -- the main flow + +***Modifying the json can be performed via the Connect user interface, followed by an export operation. Note that string replacements are performed prior to loading the json flows into the resource, they will need to be reset after exporting. This is responsible for ARN and other dependency resolution and is contained to the contact attributes parameters.*** + +## Tagging +The follow tag is set for all taggable resources in `bin/connect_cdk_simple.ts`: +* `application: 'Github Location'` + +## Deploying + +This project contains a Lambda function that use the CDK to deploy. It is written in Python, but des not require any further building or packaging. + +This project uses the Cloud Development Kit (CDK) in Typescript. + +```bash +cdk deploy +``` + +## Cleanup +To cleanup this solution or avoid further or on-going charges + +```bash +cdk destroy +``` \ No newline at end of file diff --git a/typescript/connect-cdk/bin/connect_cdk.ts b/typescript/connect-cdk/bin/connect_cdk.ts new file mode 100644 index 0000000000..eb9b1c17a7 --- /dev/null +++ b/typescript/connect-cdk/bin/connect_cdk.ts @@ -0,0 +1,12 @@ +#!/usr/bin/env node +import 'source-map-support/register'; +import * as cdk from 'aws-cdk-lib'; +import { ConnectCdkStack as ConnectCdkStack } from '../lib/connect_cdk-stack'; + +const app = new cdk.App(); + +new ConnectCdkStack(app, 'ConnectCdkStack', { + tags: { + application: 'https://github.com/aws-samples/aws-cdk-examples/typescript/ConnectCdk' + }, +}); \ No newline at end of file diff --git a/typescript/connect-cdk/callFlows/MainFlow.json b/typescript/connect-cdk/callFlows/MainFlow.json new file mode 100644 index 0000000000..f3136d94d3 --- /dev/null +++ b/typescript/connect-cdk/callFlows/MainFlow.json @@ -0,0 +1,151 @@ +{ + "Version": "2019-10-30", + "StartAction": "d3f90ab2-eb2a-467f-a349-323422ad8bec", + "Metadata": { + "entryPointPosition": { + "x": -10.4, + "y": -28 + }, + "ActionMetadata": { + "51bffcc2-8bda-46a4-8b29-6c327c109cfe": { + "position": { + "x": 271.2, + "y": -29.6 + } + }, + "d3f90ab2-eb2a-467f-a349-323422ad8bec": { + "position": { + "x": 80, + "y": 188.8 + } + }, + "52f73b71-7081-4cf0-b6f6-4202cfba2863": { + "position": { + "x": 512, + "y": 12.8 + } + }, + "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3": { + "position": { + "x": 1228.8, + "y": 196.8 + } + }, + "049fca85-b0bd-49d6-8517-2943c248cdc3": { + "position": { + "x": 734.4, + "y": -100.8 + }, + "parameters": { + "LambdaFunctionARN": { + "useDynamic": true + } + }, + "dynamicMetadata": {}, + "useDynamic": true + }, + "3e5551e7-b4b8-4051-a438-019dfe5b760b": { + "position": { + "x": 1025.6, + "y": -50.4 + } + } + }, + "Annotations": [], + "name": "MainFlow", + "description": "", + "type": "contactFlow", + "status": "published", + "hash": {} + }, + "Actions": [ + { + "Parameters": { + "FlowAttributes": { + "HelloLambdaArn": { + "Value": "HelloLambdaArnValue" + } + } + }, + "Identifier": "51bffcc2-8bda-46a4-8b29-6c327c109cfe", + "Type": "UpdateFlowAttributes", + "Transitions": { + "NextAction": "52f73b71-7081-4cf0-b6f6-4202cfba2863", + "Errors": [ + { + "NextAction": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "ErrorType": "NoMatchingError" + } + ] + } + }, + { + "Parameters": { + "FlowLoggingBehavior": "Enabled" + }, + "Identifier": "d3f90ab2-eb2a-467f-a349-323422ad8bec", + "Type": "UpdateFlowLoggingBehavior", + "Transitions": { + "NextAction": "51bffcc2-8bda-46a4-8b29-6c327c109cfe" + } + }, + { + "Parameters": { + "Text": "Hello" + }, + "Identifier": "52f73b71-7081-4cf0-b6f6-4202cfba2863", + "Type": "MessageParticipant", + "Transitions": { + "NextAction": "049fca85-b0bd-49d6-8517-2943c248cdc3", + "Errors": [ + { + "NextAction": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "ErrorType": "NoMatchingError" + } + ] + } + }, + { + "Parameters": {}, + "Identifier": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "Type": "DisconnectParticipant", + "Transitions": {} + }, + { + "Parameters": { + "LambdaFunctionARN": "$.FlowAttributes.HelloLambdaArn", + "InvocationTimeLimitSeconds": "3", + "ResponseValidation": { + "ResponseType": "JSON" + } + }, + "Identifier": "049fca85-b0bd-49d6-8517-2943c248cdc3", + "Type": "InvokeLambdaFunction", + "Transitions": { + "NextAction": "3e5551e7-b4b8-4051-a438-019dfe5b760b", + "Errors": [ + { + "NextAction": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "ErrorType": "NoMatchingError" + } + ] + } + }, + { + "Parameters": { + "SSML": " $.External.body.response " + }, + "Identifier": "3e5551e7-b4b8-4051-a438-019dfe5b760b", + "Type": "MessageParticipant", + "Transitions": { + "NextAction": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "Errors": [ + { + "NextAction": "6a6556e1-b596-4f5b-b0c1-c5ac5ab965a3", + "ErrorType": "NoMatchingError" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/typescript/connect-cdk/cdk.json b/typescript/connect-cdk/cdk.json new file mode 100644 index 0000000000..a5b9c27429 --- /dev/null +++ b/typescript/connect-cdk/cdk.json @@ -0,0 +1,72 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/connect_cdk.ts", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false + } +} diff --git a/typescript/connect-cdk/hellolambda/lambda_function.py b/typescript/connect-cdk/hellolambda/lambda_function.py new file mode 100644 index 0000000000..883daca06d --- /dev/null +++ b/typescript/connect-cdk/hellolambda/lambda_function.py @@ -0,0 +1,20 @@ +import boto3 +from datetime import datetime, timedelta +import logging + +# Establish logging configuration +logger = logging.getLogger() + +def lambda_handler(event, context): + + response = { + + 'response': "the current date is " + datetime.now().strftime("%m-%d-%Y") + } + + logger.info(response) + + return { + 'statusCode': 200, + 'body': response + } \ No newline at end of file diff --git a/typescript/connect-cdk/jest.config.js b/typescript/connect-cdk/jest.config.js new file mode 100644 index 0000000000..08263b8954 --- /dev/null +++ b/typescript/connect-cdk/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + testEnvironment: 'node', + roots: ['/test'], + testMatch: ['**/*.test.ts'], + transform: { + '^.+\\.tsx?$': 'ts-jest' + } +}; diff --git a/typescript/connect-cdk/lib/connect_cdk-stack.ts b/typescript/connect-cdk/lib/connect_cdk-stack.ts new file mode 100644 index 0000000000..e3abf8382a --- /dev/null +++ b/typescript/connect-cdk/lib/connect_cdk-stack.ts @@ -0,0 +1,88 @@ +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as fs from 'fs'; +import * as cr from 'aws-cdk-lib/custom-resources'; + +export class ConnectCdkStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + //generate an aliasID + const connectInstanceName = this.account + cdk.Names.uniqueResourceName(this, { + maxLength: 50 + }); + + // Create an Amazon Connect instance + const connectInstance = new cdk.aws_connect.CfnInstance(this, 'ConnectInstance', { + instanceAlias: connectInstanceName, + identityManagementType: 'CONNECT_MANAGED', + attributes: { + inboundCalls: true, + outboundCalls: false, + contactflowLogs: true + }, + }); + + // Lambda function + const helloLambda = new cdk.aws_lambda.Function(this, 'HelloLambda', { + runtime: cdk.aws_lambda.Runtime.PYTHON_3_12, + handler: 'lambda_function.lambda_handler', + code: cdk.aws_lambda.Code.fromAsset('./hellolambda'), + }); + + // main flow + const connectContactFlow = new cdk.aws_connect.CfnContactFlow(this, 'ConnectPagerContactFlow', { + instanceArn: connectInstance.attrArn, + name: "MainFlow", + type: "CONTACT_FLOW", + content: fs.readFileSync('./callFlows/MainFlow.json', 'utf-8').toString() + .replace("HelloLambdaArnValue", helloLambda.functionArn) + }); + + + // map lambda to connect flows + const connectInstanceFlowLambda = new cdk.aws_connect.CfnIntegrationAssociation(this, 'ConnectInstanceFlowLambda', { + instanceId: connectInstance.attrArn, + integrationArn: helloLambda.functionArn, + integrationType: 'LAMBDA_FUNCTION' + }); + + // claim a number + const connectNumber = new cdk.aws_connect.CfnPhoneNumber(this, 'ConnectPagerPhoneNumber', { + targetArn: connectInstance.attrArn, + countryCode: 'US', + type: 'DID' + }); + + // associate the number using AwsCustomResource, doesn't appear to be any other way + const associateNumber = new cr.AwsCustomResource(this, 'AssociateConnectNumber', { + onUpdate: { + service: 'Connect', + action: 'AssociatePhoneNumberContactFlowCommand', + parameters: { + InstanceId: connectInstance.attrArn, + ContactFlowId: connectContactFlow.attrContactFlowArn, + PhoneNumberId: connectNumber.attrPhoneNumberArn, + }, + physicalResourceId: cr.PhysicalResourceId.of(connectNumber.attrAddress) + }, + onDelete: { + service: 'Connect', + action: 'DisassociatePhoneNumberContactFlowCommand', + parameters: { + InstanceId: connectInstance.attrArn, + ContactFlowId: connectContactFlow.attrContactFlowArn, + PhoneNumberId: connectNumber.attrPhoneNumberArn, + }, + physicalResourceId: cr.PhysicalResourceId.of(connectNumber.attrAddress) + }, + policy: cr.AwsCustomResourcePolicy.fromSdkCalls({ + resources: [connectContactFlow.attrContactFlowArn, connectNumber.attrPhoneNumberArn] + }) + }); + + new cdk.CfnOutput(this, 'connectPhoneNumberOutput', { + value: connectNumber.attrAddress + }); + } +} diff --git a/typescript/connect-cdk/package.json b/typescript/connect-cdk/package.json new file mode 100644 index 0000000000..27da02d6c1 --- /dev/null +++ b/typescript/connect-cdk/package.json @@ -0,0 +1,28 @@ +{ + "name": "connect_cdk_simple", + "version": "0.1.0", + "bin": { + "connect_cdk_simple": "bin/connect_cdk_simple.js" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "test": "jest", + "cdk": "cdk" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "20.14.9", + "aws-cdk": "2.157.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.5", + "ts-node": "^10.9.2", + "typescript": "~5.5.3" + }, + "dependencies": { + "aws-cdk-lib": "2.157.0", + "cdk-nag": "^2.30.0", + "constructs": "^10.0.0", + "source-map-support": "^0.5.21" + } +} diff --git a/typescript/connect-cdk/test/connect_cdk_simple.test.ts b/typescript/connect-cdk/test/connect_cdk_simple.test.ts new file mode 100644 index 0000000000..3a71d5a258 --- /dev/null +++ b/typescript/connect-cdk/test/connect_cdk_simple.test.ts @@ -0,0 +1,17 @@ +// import * as cdk from 'aws-cdk-lib'; +// import { Template } from 'aws-cdk-lib/assertions'; +// import * as ConnectCdkSimple from '../lib/connect_cdk_simple-stack'; + +// example test. To run these tests, uncomment this file along with the +// example resource in lib/connect_cdk_simple-stack.ts +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// // WHEN +// const stack = new ConnectCdkSimple.ConnectCdkSimpleStack(app, 'MyTestStack'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); +}); diff --git a/typescript/connect-cdk/tsconfig.json b/typescript/connect-cdk/tsconfig.json new file mode 100644 index 0000000000..aaa7dc510f --- /dev/null +++ b/typescript/connect-cdk/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": [ + "es2020", + "dom" + ], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": [ + "./node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "cdk.out" + ] +} From 8bc04548fa25feeaf0944990f6cebe862c0f67e1 Mon Sep 17 00:00:00 2001 From: Troy Parrett Date: Wed, 30 Oct 2024 15:05:29 -0400 Subject: [PATCH 2/3] Simple test --- .../test/connect_cdk_simple.test.ts | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/typescript/connect-cdk/test/connect_cdk_simple.test.ts b/typescript/connect-cdk/test/connect_cdk_simple.test.ts index 3a71d5a258..b16499b63c 100644 --- a/typescript/connect-cdk/test/connect_cdk_simple.test.ts +++ b/typescript/connect-cdk/test/connect_cdk_simple.test.ts @@ -1,17 +1,23 @@ -// import * as cdk from 'aws-cdk-lib'; -// import { Template } from 'aws-cdk-lib/assertions'; -// import * as ConnectCdkSimple from '../lib/connect_cdk_simple-stack'; +import * as cdk from 'aws-cdk-lib'; +import { Template } from 'aws-cdk-lib/assertions'; +import * as ConnectCdk from '../lib/connect_cdk-stack'; -// example test. To run these tests, uncomment this file along with the -// example resource in lib/connect_cdk_simple-stack.ts -test('SQS Queue Created', () => { -// const app = new cdk.App(); -// // WHEN -// const stack = new ConnectCdkSimple.ConnectCdkSimpleStack(app, 'MyTestStack'); -// // THEN -// const template = Template.fromStack(stack); -// template.hasResourceProperties('AWS::SQS::Queue', { -// VisibilityTimeout: 300 -// }); +test('Connect Instance and Lambda Function Created', () => { + const app = new cdk.App(); + // WHEN + const stack = new ConnectCdk.ConnectCdkStack(app, 'MyTestStack'); + // THEN + const template = Template.fromStack(stack); + + // Check that Connect instance is created + template.hasResourceProperties('AWS::Connect::Instance', { + IdentityManagementType: 'CONNECT_MANAGED' + }); + + // Check that a Lambda function is created + template.hasResourceProperties('AWS::Lambda::Function', { + Runtime: 'python3.12', + Handler: 'lambda_function.lambda_handler' + }); }); From 88fbd91b79f6f97e9c89e7b409ee7732ad71a931 Mon Sep 17 00:00:00 2001 From: Michael Kaiser Date: Sat, 2 Nov 2024 09:12:02 -0500 Subject: [PATCH 3/3] Update connect_cdk.ts tag url was incorrect. Just removed instead of trying to keep it up to date. --- typescript/connect-cdk/bin/connect_cdk.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/typescript/connect-cdk/bin/connect_cdk.ts b/typescript/connect-cdk/bin/connect_cdk.ts index eb9b1c17a7..7c0c275b95 100644 --- a/typescript/connect-cdk/bin/connect_cdk.ts +++ b/typescript/connect-cdk/bin/connect_cdk.ts @@ -5,8 +5,4 @@ import { ConnectCdkStack as ConnectCdkStack } from '../lib/connect_cdk-stack'; const app = new cdk.App(); -new ConnectCdkStack(app, 'ConnectCdkStack', { - tags: { - application: 'https://github.com/aws-samples/aws-cdk-examples/typescript/ConnectCdk' - }, -}); \ No newline at end of file +new ConnectCdkStack(app, 'ConnectCdkStack');