Skip to content

Commit d04edc9

Browse files
authored
Merge branch 'main' into osi-cwlogs-ingest-impl
2 parents 34636fa + a104dbd commit d04edc9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1736
-75
lines changed

.github/workflows/build-pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
# Get the list of changed files, excluding Markdown files
3434
- name: Get changed files
3535
id: changed-files
36-
uses: tj-actions/changed-files@v45
36+
uses: tj-actions/changed-files@c3a1bb2c992d77180ae65be6ae6c166cf40f857c
3737
with:
3838
files: ${{ matrix.language }}/**
3939
files_ignore: '**/*.md'

python/amazon-connect/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Amazon Connect
2+
3+
<!--BEGIN STABILITY BANNER-->
4+
---
5+
6+
![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge)
7+
8+
> **This is a stable example. It should successfully build out of the box**
9+
>
10+
> This example is built on Construct Libraries marked "Stable" and does not have any infrastructure prerequisites to build.
11+
---
12+
<!--END STABILITY BANNER-->
13+
14+
## Overview
15+
16+
This is an example CDK application that deploys an Amazon Connect instance.
17+
18+
**Use Case**: a customer wants to be able to provision and configure Amazon Connect instances using CDK in Python.
19+
20+
## Solution
21+
22+
The solution deploys an Amazon Connect instance along with S3 buckets for call recordings and scheduled reports.
23+
Moreover, a Firehose Delivery Stream is deployed for Contact Trace Records.
24+
25+
The instance is then assigned a phone number and the hours of operation for the contact centre are configured.
26+
27+
## CDK Toolkit
28+
29+
The `cdk.json` file tells the CDK Toolkit how to execute your app.
30+
31+
This project is set up like a standard Python project. The initialization
32+
process also creates a virtualenv within this project, stored under the `.venv`
33+
directory. To create the virtualenv it assumes that there is a `python3`
34+
(or `python` for Windows) executable in your path with access to the `venv`
35+
package. If for any reason the automatic creation of the virtualenv fails,
36+
you can create the virtualenv manually.
37+
38+
To manually create a virtualenv on MacOS and Linux:
39+
40+
```
41+
$ python3 -m venv .venv
42+
```
43+
44+
After the init process completes and the virtualenv is created, you can use the following
45+
step to activate your virtualenv.
46+
47+
```
48+
$ source .venv/bin/activate
49+
```
50+
51+
If you are a Windows platform, you would activate the virtualenv like this:
52+
53+
```
54+
% .venv\Scripts\activate.bat
55+
```
56+
57+
Once the virtualenv is activated, you can install the required dependencies.
58+
59+
```
60+
$ pip install -r requirements.txt
61+
```
62+
63+
At this point you can now synthesize the CloudFormation template for this code.
64+
65+
```
66+
$ cdk synth
67+
```
68+
69+
To add additional dependencies, for example other CDK libraries, just add
70+
them to your `setup.py` file and rerun the `pip install -r requirements.txt`
71+
command.
72+
73+
74+
## Deploying the solution
75+
76+
To deploy the solution, use the following command:
77+
78+
```shell
79+
$ cdk deploy --all
80+
```
81+
82+
## Destroying the deployment
83+
84+
To destroy the provisioned infrastructure, you can simply run the following command:
85+
86+
```shell
87+
$ cdk destroy --all
88+
```

python/amazon-connect/amazon_connect/__init__.py

Whitespace-only changes.
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
from aws_cdk import (
2+
Aspects,
3+
Duration,
4+
Stack,
5+
RemovalPolicy,
6+
aws_connect as connect,
7+
aws_iam as iam,
8+
aws_kinesisfirehose as firehose,
9+
aws_kms as kms,
10+
aws_s3 as s3
11+
)
12+
from cdk_nag import AwsSolutionsChecks
13+
from constructs import Construct
14+
15+
16+
class AmazonConnectStack(Stack):
17+
18+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
19+
super().__init__(scope, construct_id, **kwargs)
20+
21+
# Add CDK Nag
22+
Aspects.of(self).add(AwsSolutionsChecks())
23+
24+
# Amazon Connect instance
25+
amazon_connect_instance = connect.CfnInstance(self, "AmazonConnectInstance",
26+
attributes=connect.CfnInstance.AttributesProperty(
27+
inbound_calls=True,
28+
outbound_calls=True,
29+
auto_resolve_best_voices=False,
30+
contactflow_logs=True,
31+
contact_lens=True,
32+
early_media=False,
33+
use_custom_tts_voices=False
34+
),
35+
identity_management_type="CONNECT_MANAGED",
36+
instance_alias="amazon-connect-instance"
37+
)
38+
39+
# KMS key for call recordings and transcripts
40+
call_recordings_key = kms.Key(self, "CallRecordingsKey",
41+
enable_key_rotation=True,
42+
pending_window=Duration.days(30),
43+
alias="amazon-connect-call-recordings-key"
44+
)
45+
46+
# Access logs S3 Bucket for call recordings and transcripts
47+
call_recordings_access_logs_bucket = s3.Bucket(self, "CallRecordingsAccessLogsBucket",
48+
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
49+
encryption=s3.BucketEncryption.KMS,
50+
encryption_key=call_recordings_key,
51+
removal_policy=RemovalPolicy.RETAIN,
52+
enforce_ssl=True,
53+
versioned=True,
54+
bucket_name="amazon-connect-call-recordings-access-logs-bucket"
55+
)
56+
57+
# S3 Bucket for call recordings and transcripts
58+
call_recordings_bucket = s3.Bucket(self, "CallRecordingsBucket",
59+
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
60+
encryption=s3.BucketEncryption.KMS,
61+
encryption_key=call_recordings_key,
62+
removal_policy=RemovalPolicy.RETAIN,
63+
enforce_ssl=True,
64+
versioned=True,
65+
server_access_logs_bucket=call_recordings_access_logs_bucket,
66+
bucket_name="amazon-connect-call-recordings-bucket",
67+
lifecycle_rules=[
68+
s3.LifecycleRule(
69+
enabled=True,
70+
expiration=Duration.days(365*2)
71+
)
72+
]
73+
)
74+
75+
# Associate S3 bucket with Amazon Connect instance for call recordings and transcripts
76+
call_recordings_storage_config = connect.CfnInstanceStorageConfig(self, "CallRecordingsStorageConfig",
77+
instance_arn=amazon_connect_instance.attr_arn,
78+
resource_type="CALL_RECORDINGS",
79+
storage_type="S3",
80+
81+
s3_config=connect.CfnInstanceStorageConfig.S3ConfigProperty(
82+
bucket_name=call_recordings_bucket.bucket_name,
83+
bucket_prefix="recordings",
84+
encryption_config=connect.CfnInstanceStorageConfig.EncryptionConfigProperty(
85+
encryption_type="KMS",
86+
key_id=call_recordings_key.key_arn
87+
)
88+
)
89+
)
90+
91+
# IAM Role for CTR Delivery Stream
92+
ctr_delivery_stream_role = iam.Role(self, "CtrDeliveryStreamRole",
93+
assumed_by=iam.ServicePrincipal("firehose.amazonaws.com"),
94+
role_name="amazon-connect-ctr-delivery-stream-role"
95+
)
96+
97+
# Grant permissions to the CTR IAM role
98+
ctr_delivery_stream_role.add_to_policy(iam.PolicyStatement(
99+
actions=[
100+
"s3:PutObject",
101+
"s3:GetObject",
102+
"s3:ListBucket",
103+
"s3:ListMultipartUploadParts",
104+
"s3:AbortMultipartUpload",
105+
"s3:GetBucketLocation",
106+
"kms:Encrypt",
107+
"kms:Decrypt",
108+
"kms:ReEncrypt",
109+
"kms:GenerateDataKey",
110+
"kms:DescribeKey",
111+
"kms:CreateGrant"
112+
],
113+
resources=[
114+
call_recordings_bucket.bucket_arn,
115+
call_recordings_key.key_arn
116+
]
117+
))
118+
119+
# Firehose Delivery Stream for CTR
120+
ctr_delivery_stream = firehose.CfnDeliveryStream(self, "CtrDeliveryStream",
121+
delivery_stream_name="amazon-connect-ctr-delivery-stream",
122+
delivery_stream_type="DirectPut",
123+
delivery_stream_encryption_configuration_input=firehose.CfnDeliveryStream.DeliveryStreamEncryptionConfigurationInputProperty(
124+
key_type="CUSTOMER_MANAGED_CMK",
125+
key_arn=call_recordings_key.key_arn
126+
),
127+
s3_destination_configuration=firehose.CfnDeliveryStream.S3DestinationConfigurationProperty(
128+
bucket_arn=call_recordings_bucket.bucket_arn,
129+
prefix="ctr/",
130+
role_arn=ctr_delivery_stream_role.role_arn,
131+
buffering_hints=firehose.CfnDeliveryStream.BufferingHintsProperty(
132+
interval_in_seconds=60
133+
),
134+
encryption_configuration=firehose.CfnDeliveryStream.EncryptionConfigurationProperty(
135+
kms_encryption_config=firehose.CfnDeliveryStream.KMSEncryptionConfigProperty(
136+
awskms_key_arn=call_recordings_key.key_arn
137+
)
138+
)
139+
)
140+
)
141+
142+
# Associate Firehose Delivery Stream with Amazon Connect instance for CTR
143+
ctr_storage_config = connect.CfnInstanceStorageConfig(self, "CtrStorageConfig",
144+
instance_arn=amazon_connect_instance.attr_arn,
145+
resource_type="CONTACT_TRACE_RECORDS",
146+
storage_type="KINESIS_FIREHOSE",
147+
kinesis_firehose_config=connect.CfnInstanceStorageConfig.KinesisFirehoseConfigProperty(
148+
firehose_arn=ctr_delivery_stream.attr_arn
149+
)
150+
)
151+
152+
# KMS key for scheduled reports
153+
scheduled_reports_key = kms.Key(self, "ScheduledReportsKey",
154+
enable_key_rotation=True,
155+
pending_window=Duration.days(30),
156+
alias="amazon-connect-scheduled-reports-key"
157+
)
158+
159+
160+
# Access logs S3 Bucket for scheduled reports
161+
scheduled_reports_access_logs_bucket = s3.Bucket(self, "ScheduledReportsAccessLogsBucket",
162+
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
163+
encryption=s3.BucketEncryption.KMS,
164+
encryption_key=scheduled_reports_key,
165+
removal_policy=RemovalPolicy.RETAIN,
166+
enforce_ssl=True,
167+
bucket_name="amazon-connect-scheduled-reports-access-logs-bucket"
168+
)
169+
170+
# S3 Bucket for scheduled reports
171+
scheduled_reports_bucket = s3.Bucket(self, "ScheduledReportsBucket",
172+
block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
173+
encryption=s3.BucketEncryption.KMS,
174+
encryption_key=scheduled_reports_key,
175+
removal_policy=RemovalPolicy.RETAIN,
176+
enforce_ssl=True,
177+
versioned=True,
178+
server_access_logs_bucket=scheduled_reports_access_logs_bucket,
179+
bucket_name="amazon-connect-scheduled-reports-bucket"
180+
)
181+
182+
# Associate S3 bucket with Connect instance for scheduled reports
183+
scheduled_reports_storage_config = connect.CfnInstanceStorageConfig(self, "ScheduledReportsStorageConfig",
184+
instance_arn=amazon_connect_instance.attr_arn,
185+
resource_type="SCHEDULED_REPORTS",
186+
storage_type="S3",
187+
188+
s3_config=connect.CfnInstanceStorageConfig.S3ConfigProperty(
189+
bucket_name=scheduled_reports_bucket.bucket_name,
190+
bucket_prefix="reports",
191+
encryption_config=connect.CfnInstanceStorageConfig.EncryptionConfigProperty(
192+
encryption_type="KMS",
193+
key_id=scheduled_reports_key.key_arn
194+
)
195+
)
196+
)
197+
198+
# Assign phone number
199+
phone_number = connect.CfnPhoneNumber(self, "PhoneNumber",
200+
target_arn=amazon_connect_instance.attr_arn,
201+
country_code="GB",
202+
description="Inbound Phone Number",
203+
type="DID"
204+
)
205+
206+
# Create hours of operation
207+
hours_of_operation = connect.CfnHoursOfOperation(self, "HoursOfOperation",
208+
config=[connect.CfnHoursOfOperation.HoursOfOperationConfigProperty(
209+
day="MONDAY",
210+
start_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
211+
hours=9,
212+
minutes=0
213+
),
214+
end_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
215+
hours=17,
216+
minutes=0
217+
)
218+
),
219+
connect.CfnHoursOfOperation.HoursOfOperationConfigProperty(
220+
day="TUESDAY",
221+
start_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
222+
hours=9,
223+
minutes=0
224+
),
225+
end_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
226+
hours=17,
227+
minutes=0
228+
)
229+
),
230+
connect.CfnHoursOfOperation.HoursOfOperationConfigProperty(
231+
day="WEDNESDAY",
232+
start_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
233+
hours=9,
234+
minutes=0
235+
),
236+
end_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
237+
hours=17,
238+
minutes=0
239+
)
240+
),
241+
connect.CfnHoursOfOperation.HoursOfOperationConfigProperty(
242+
day="THURSDAY",
243+
start_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
244+
hours=9,
245+
minutes=0
246+
),
247+
end_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
248+
hours=17,
249+
minutes=0
250+
)
251+
),
252+
connect.CfnHoursOfOperation.HoursOfOperationConfigProperty(
253+
day="FRIDAY",
254+
start_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
255+
hours=9,
256+
minutes=0
257+
),
258+
end_time=connect.CfnHoursOfOperation.HoursOfOperationTimeSliceProperty(
259+
hours=17,
260+
minutes=0
261+
)
262+
)],
263+
instance_arn=amazon_connect_instance.attr_arn,
264+
name="Main",
265+
time_zone="Europe/London",
266+
description="Business Hours of Operation",
267+
)

python/amazon-connect/app.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env python3
2+
import aws_cdk as cdk
3+
4+
from amazon_connect.amazon_connect_stack import AmazonConnectStack
5+
6+
7+
app = cdk.App()
8+
9+
AmazonConnectStack(app, "AmazonConnectStack")
10+
11+
app.synth()

0 commit comments

Comments
 (0)