in lib/chime_sdk_pstn_cdk-stack.ts [54:263]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const deadLetterQueue = new sqs.Queue(this, 'deadLetterQueue');
// create a bucket for the recorded wave files and set the right policies
const wavFiles = new s3.Bucket(this, 'wavFiles', {
publicReadAccess: false,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true
});
const wavFileBucketPolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
's3:GetObject',
's3:PutObject',
's3:PutObjectAcl'
],
resources: [
wavFiles.bucketArn,
`${wavFiles.bucketArn}/*`
],
sid: 'SIPMediaApplicationRead',
});
wavFileBucketPolicy.addServicePrincipal('voiceconnector.chime.amazonaws.com');
wavFiles.addToResourcePolicy(wavFileBucketPolicy);
const smaLambdaRole = new iam.Role(this, 'smaLambdaRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
smaLambdaRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"));
const pollyRole = new iam.Role(this, 'pollyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
const pollyPolicyDoc = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
//actions: ["polly:StartSpeechSynthesisTask","polly:ListSpeechSynthesisTasks","polly:GetSpeechSynthesisTask"],
actions: ["polly:SynthesizeSpeech"],
resources: ["*"],
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["s3:PutObject", "s3:ListObject"],
resources: [`${wavFiles.bucketArn}/*`],
}),/*
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["sns:Publish"],
resources: ["*"],
}),*/
],
});
const pollyPollicy = new iam.Policy(this, 'pollyPollicy', {
document: pollyPolicyDoc
});
smaLambdaRole.attachInlinePolicy(pollyPollicy);
// create the lambda layer to hold routine libraries
const lambdaLayer = new lambda.LayerVersion(this, 'appLambdaLayer', {
code: lambda.Code.fromAsset(path.join(appLayerFolder)),
compatibleRuntimes: [lambda.Runtime.NODEJS_14_X],
description: 'App Lambda Layer',
});
// create the lambda function that does the call handling
const chimeSdkPstn = new lambda.Function(this, 'ChimeSdkPstnLambda', {
code: lambda.Code.fromAsset(chimeSdkPstnLambdaDir, { exclude: ["README.md", "*.ts", "*.json", "Makefile", "layer"] }),
handler: ChimeSdkPstnLambdaHandler,
runtime: lambda.Runtime.NODEJS_14_X,
environment: {
WAVFILE_BUCKET: wavFiles.bucketName,
},
role: smaLambdaRole,
layers: [lambdaLayer],
timeout: cdk.Duration.seconds(60),
});
const chimeCreateRole = new iam.Role(this, 'createChimeLambdaRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
inlinePolicies: {
['chimePolicy']: new iam.PolicyDocument({
statements: [new iam.PolicyStatement({
resources: ['*'],
actions: ['chime:*',
'lambda:GetPolicy',
'lambda:AddPermission',
'cloudformation:DescribeStacks',
'cloudformation:DescribeStackEvents',
'cloudformation:DescribeStackResource',
'cloudformation:DescribeStackResources',]
})]
})
},
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")]
});
// create the lambda layer to hold routine libraries for the Custom Provider
const providerLayer = new lambda.LayerVersion(this, 'providerLambdaLayer', {
code: lambda.Code.fromAsset(path.join(providerLayerFolder,)),
compatibleRuntimes: [lambda.Runtime.NODEJS_14_X],
description: 'Provider Lambda Layer',
});
// create the lambda for CDK custom resource to deploy SMA, etc.
const chimeProviderLamba = new lambda.Function(this, 'chimeSdkPstnProviderLamba-', {
code: lambda.Code.fromAsset(chimeSdkPstnProviderDir, { exclude: ["README.md", "*.ts"] }),
handler: ChimeSdkPstnProviderHandler,
runtime: lambda.Runtime.NODEJS_14_X,
role: chimeCreateRole,
layers: [providerLayer],
timeout: cdk.Duration.seconds(180),
});
const chimeProvider = new custom.Provider(this, 'chimeProvider', {
onEventHandler: chimeProviderLamba,
});
const chimeProviderProperties = {
lambdaArn: chimeSdkPstn.functionArn,
region: this.region,
smaName: this.stackName,
sipRuleName: this.stackName,
sipTriggerType: 'ToPhoneNumber',
phoneNumberRequired: true,
phoneAreaCode: '505',
phoneState: '',
phoneCountry: '',
phoneNumberType: 'SipMediaApplicationDialIn',
phoneNumberTollFreePrefix: '',
}
console.log(chimeProviderProperties);
console.log(chimeProvider.serviceToken);
const inboundSMA = new cdk.CustomResource(this, 'inboundSMA', {
serviceToken: chimeProvider.serviceToken,
properties: chimeProviderProperties,
});
// create the DynamoDB database
const callInfoTable = new ddb.Table(this, 'callInfo', {
partitionKey: {
name: 'phoneNumber',
type: ddb.AttributeType.STRING
},
removalPolicy: cdk.RemovalPolicy.DESTROY,
billingMode: ddb.BillingMode.PAY_PER_REQUEST,
stream: ddb.StreamViewType.NEW_IMAGE
});
// enable the Lambda function to access the DynamoDB table (using IAM)
callInfoTable.grantFullAccess(chimeSdkPstn)
// put the table name in the lambda environment
chimeSdkPstn.addEnvironment('CALLINFO_TABLE_NAME', callInfoTable.tableName);
// these are the attributes returned from the custom resource!
const inboundPhoneNumber = inboundSMA.getAttString('phoneNumber');
const smaID = inboundSMA.getAttString("smaID");
const sipRuleID = inboundSMA.getAttString("sipRuleID");
const phoneID = inboundSMA.getAttString("phoneID");
// Write the Telephony Handling Data to the output
new cdk.CfnOutput(this, 'inboundPhoneNumber', {
value: inboundPhoneNumber,
exportName: this.stackName + '-inboundPhoneNumber',
});
new cdk.CfnOutput(this, 'chimeProviderLog', {
value: chimeProviderLamba.logGroup.logGroupName,
exportName: this.stackName + '-chimeProviderLog'
});
new cdk.CfnOutput(this, 'lambdaLog', {
value: chimeSdkPstn.logGroup.logGroupName,
exportName: this.stackName + '-lambdaLog',
});
new cdk.CfnOutput(this, 'region', {
value: this.region,
exportName: this.stackName + '-region',
});
new cdk.CfnOutput(this, 'lambdaARN', {
value: chimeSdkPstn.functionArn,
exportName: this.stackName + '-lambdaARN'
});
new cdk.CfnOutput(this, "smaID", {
value: smaID,
exportName: this.stackName + '-smaID',
});
new cdk.CfnOutput(this, "phoneID", {
value: phoneID,
exportName: this.stackName + '-phoneID'
});
new cdk.CfnOutput(this, "sipRuleID", {
value: sipRuleID,
exportName: this.stackName + '-sipRuleID',
});
new cdk.CfnOutput(this, "sipRuleName", {
value: chimeProviderProperties.sipRuleName,
exportName: this.stackName + '-sipRuleName',
});
new cdk.CfnOutput(this, "lambdaLayerArn", {
value: lambdaLayer.layerVersionArn,
exportName: this.stackName + '-lambdaLayerArn',
});
new cdk.CfnOutput(this, 'chimeSdkPstnInfoTable', { value: callInfoTable.tableName });
}