Skip to main content

Amazon Connect - Operata Integration Updates - Terraform Deployment Guide

How to deploy your Operata AWS integration stacks using Terraform

Written by Hamish Keay

Deploying with Terraform

This guide covers deploying the full suite of Operata Cloud Collector v3 stacks using Terraform.

Operata publishes pre-synthesized Terraform JSON files (.tf.json).

You download one file per stack, set a handful of variables, and run terraform apply. No CDK, npm, or other build tooling is needed - only Terraform and AWS credentials.


The Operata stacks affected by this update, and the key dates, are:

Stack

Runtime

Support Deadline

Function Blocked

CTR

Amazon Linux 2

31 July 2026

3 March 2027

CLD

Amazon Linux 2

31 July 2026

3 March 2027

CLD

Python 3.9

Already passed

30 September 2026

What you need to know before starting:

  • ⏱ Each stack takes approximately 5-15 minutes to deploy.

  • 📦 Terraform state is stored locally by default. For team environments, configure a remote backend (e.g. S3) before deploying.

  • 🔑 Keep your Operata API key out of version control - pass it inline or store it in a secrets manager.


Prerequisites

Requirement

Notes

Terraform

v1.8.x or later - install guide

AWS credentials

In the target account, with permission to create IAM, Lambda, Kinesis, EventBridge, Secrets Manager, and CloudWatch Logs resources - and (for clrules) CloudFormation and Amazon Connect rule resources

Operata Group ID

How to find your Operata Group ID

Operata API key

Terraform .tf.json file(s)

Download from the Operata S3 bucket: https://operata-customer-assets.s3.amazonaws.com/ccv3-templates/<filename>. See available stacks below for the exact filename for each stack.


Available stacks

Not sure if you need the VPC variant? Check with whoever manages your AWS account - VPC deployments are typically used in enterprise or regulated environments where Lambda functions must run inside a private network. If you're not sure, the standard (non-VPC) variant is generally the right choice.

Stack

Description

Filename

Contact Trace Records (CTR)

Ingests CTR data from your Amazon Connect Kinesis stream

cloud-collector-v3-contact-trace-records.tf.json

Contact Lens Data (CLD)

Ingests Contact Lens output from S3.

cloud-collector-v3-contact-lens-data.tf.json

Contact Flow Logs (CFL)

Ingests contact flow logs from CloudWatch

cloud-collector-v3-contact-flow-logs.tf.json

Lex V2 Logs

Ingests Lex V2 conversation logs from CloudWatch

cloud-collector-v3-lexv2-logs.tf.json

Contact Lens Rules (CLR)

Deploys real-time and post-call Contact Lens rules into your Amazon Connect instance via nested CloudFormation stacks.

cloud-collector-v3-contact-lens-rules.tf.json

Contact Trace Records - VPC

VPC variant of CTR

cloud-collector-v3-contact-trace-records-vpc.tf.json

Contact Lens Data - VPC

VPC variant of CLD

cloud-collector-v3-contact-lens-data-vpc.tf.json

Contact Flow Logs - VPC

VPC variant of CFL

cloud-collector-v3-contact-flow-logs-vpc.tf.json

Lex V2 Logs - VPC

VPC variant of Lex V2 Logs

cloud-collector-v3-lexv2-logs-vpc.tf.json

VPC variants: Choose the VPC variant only if your AWS account requires Lambda functions to run inside a VPC. VPC variants require two additional variables: a VPC ID and a list of private subnet IDs.

Stacks are independent and can be deployed in any combination.


How to deploy each stack

Each section below contains a complete, ready-to-run deploy block and destroy block. Substitute <bucket> and <env> plus any stack-specific values before running. For production, <bucket> is operata-customer-assets and <env> is prod.


1. Contact Trace Records (CTR)

Deploy:

mkdir -p ~/operata/ctr-<env>
cd ~/operata/ctr-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-trace-records.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
ctr_kinesis_stream_arn = "arn:aws:kinesis:ap-southeast-2:111111111111:stream/..."
connect_instance_friendly_name = "Prod"
agent_data_s3_bucket_name = ["", ""]
EOF
terraform init
terraform apply

agent_data_s3_bucket_name expects a two-element list in the format ["bucket-name", "prefix/"]. If you have an agent data S3 bucket set up, enter those values. Otherwise leave it as ["", ""].

Destroy:

terraform destroy

CTR - VPC variant:

mkdir -p ~/operata/ctr-vpc-<env>
cd ~/operata/ctr-vpc-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-trace-records-vpc.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
ctr_kinesis_stream_arn = "arn:aws:kinesis:ap-southeast-2:111111111111:stream/..."
connect_instance_friendly_name = "Prod"
agent_data_s3_bucket_name = ["", ""]
enrichment_lambda_vpc_id = "vpc-0123456789abcdef0"
enrichment_lambda_vpc_private_subnets = ["subnet-aaaa", "subnet-bbbb"]
EOF
terraform init
terraform apply

2. Contact Lens Data (CLD)

Deploy:

mkdir -p ~/operata/cld-<env>
cd ~/operata/cld-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-data.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
contact_lens_data_s3_bucket_name = "<your-contact-lens-bucket>"
EOF
terraform init
terraform apply

Destroy:

terraform destroy

CLD - VPC variant:

mkdir -p ~/operata/cld-vpc-<env>
cd ~/operata/cld-vpc-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-data-vpc.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
contact_lens_data_s3_bucket_name = "<your-contact-lens-bucket>"
s3_kinesis_integrator_lambda_vpc_id = "vpc-0123456789abcdef0"
s3_kinesis_integrator_lambda_vpc_private_subnets = ["subnet-aaaa", "subnet-bbbb"]
EOF
terraform init
terraform apply

3. Contact Flow Logs (CFL)

Deploy:

mkdir -p ~/operata/cfl-<env>
cd ~/operata/cfl-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-flow-logs.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
cf_log_group = "/aws/connect/<instance>/ContactFlowLogs"
connect_instance_friendly_name = "Prod"
EOF
terraform init
terraform apply

Destroy:

terraform destroy

CFL - VPC variant:

mkdir -p ~/operata/cfl-vpc-<env>
cd ~/operata/cfl-vpc-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-flow-logs-vpc.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
cf_log_group = "/aws/connect/<instance>/ContactFlowLogs"
connect_instance_friendly_name = "Prod"
cfl_decoder_lambda_vpc_id = "vpc-0123456789abcdef0"
cfl_decoder_lambda_vpc_private_subnets = ["subnet-aaaa", "subnet-bbbb"]
EOF
terraform init
terraform apply

4. Lex V2 Logs

Deploy:

mkdir -p ~/operata/lexv2-<env>
cd ~/operata/lexv2-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-lexv2-logs.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
lex_log_group_name = "/aws/lex/<your-bot>/conversation-logs"
EOF
terraform init
terraform apply

Destroy:

terraform destroy

Lex V2 Logs - VPC variant:

mkdir -p ~/operata/lexv2-vpc-<env>
cd ~/operata/lexv2-vpc-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-lexv2-logs-vpc.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
operata_group_id = "<your-operata-group-id>"
operata_api_key = "<your-operata-api-key>"
lex_log_group_name = "/aws/lex/<your-bot>/conversation-logs"
lex_enrichment_lambda_vpc_id = "vpc-0123456789abcdef0"
lex_enrichment_lambda_vpc_private_subnets = ["subnet-aaaa", "subnet-bbbb"]
EOF
terraform init
terraform apply

5. Contact Lens Rules (clrules)

Deploy this stack if your Operata configuration uses Contact Lens event processing. clrules deploys two sets of Amazon Connect rules into your instance - one for real-time and one for post-call Contact Lens analysis.


How it works: this Terraform stack wraps the Operata Contact Lens Rules CloudFormation template via an aws_cloudformation_stack resource. Running terraform apply provisions a nested CloudFormation stack named operata-contact-lens-rules-<env> in your account, which in turn creates the Connect rules.


Deploy:

mkdir -p ~/operata/clrules-<env>
cd ~/operata/clrules-<env>
curl -O https://<bucket>.s3.amazonaws.com/ccv3-templates/cloud-collector-v3-contact-lens-rules.tf.json
cat > terraform.tfvars <<EOF
aws_region = "ap-southeast-2"
amazon_connect_instance_arn = "arn:aws:connect:ap-southeast-2:111111111111:instance/<your-instance-id>"
EOF
terraform init
terraform apply

The apply takes approximately 25 seconds. Rule creation is serialized to respect the Amazon Connect CreateRule API rate limit (2 requests per second).


Verify:

aws connect list-rules \
--region ap-southeast-2 \
--instance-id <your-instance-id> \
--publish-status PUBLISHED \
--query 'RuleSummaryList[?starts_with(Name, `operata_`)] | length(@)'

Destroy:

terraform destroy

clrules creates no AWS Secrets Manager secrets. No force-deletion step is required after destroy.


Upgrading an existing stack

⚠️ If unexpected resources appear in the plan, contact Operata before proceeding.

To apply a newer Operata release to an already-deployed stack:

  1. Download the new .tf.json file into the same working directory, replacing the previous file. (Filenames no longer include a version tag, so the latest release is always available at the same URL).

  2. Run terraform plan to confirm only the expected resources change (typically the Lambda zip key and a few metadata fields).

  3. Run terraform apply.

State in the working directory tracks resource identity, so the upgrade is in place. The EventBridge pipe, Kinesis stream, and IAM resources are not replaced. For clrules specifically, terraform apply triggers a CloudFormation stack update on the nested operata-contact-lens-rules-<env> stack, which diffs and updates only the changed rules.


Redeploying after a destroy

AWS Secrets Manager schedules secrets for deletion with a 30-day recovery window - they are not removed immediately after terraform destroy. If you attempt terraform apply again before the window expires, the apply will fail with:

InvalidRequestException: You can't create this secret because a secret with this name is already scheduled for deletion.

To unblock an immediate redeploy, force-delete the affected secrets after destroy:

aws secretsmanager delete-secret \
--region ap-southeast-2 \
--secret-id /cloud-collector-v3/<service>/apiToken-<env> \
--force-delete-without-recovery

⚠️ --force-delete-without-recovery permanently removes the secret. Use this only when you intend to recreate it immediately.


Secrets created per stack:

Stack

Secrets

clrules

None

CTR

/cloud-collector-v3/ctr/apiToken-<env>

CLD

/cloud-collector-v3/cld/apiToken-<env>

CFL

/cloud-collector-v3/cfl/apiToken-<env>, /cloud-collector-v3/cfl/redactionPolicyCache-<env>

Lex V2 Logs

/cloud-collector-v3/lex/apiToken-<env>, /cloud-collector-v3/lex/redactionPolicyCache-<env>


How to verify it's working

1. Make or receive a short test call in your Amazon Connect instance

If testing an inbound call: remember to Close Contact before checking for data, or it won't appear.
Data may take up to 5 minutes to appear in Operata after the call ends.


2. Check API activity

Go to Group Settings → Integrations → API Management and look for a recent Last Used timestamp on the API key.

  • Recent activity shown → your stack is sending data. Continue to Step 3.

  • No recent activity → stop here. Check that operata_api_key and operata_group_id in your terraform.tfvars match what's in your Operata account, then re-test. If it still doesn't show activity after correcting these, contact Operata support.

3. Check the relevant data view for your stack

  • CTR → Calls and Logs → Details / Summary - confirm the test call appears.

  • Contact Lens (CLD) → Dashboards → Conversational Analytics - confirm data appears, filtering by test agent name or sorting by most recent call.

If data doesn't appear after 10 minutes, proceed to the troubleshooting steps below.


Troubleshooting

Work through the checklist below before contacting Operata support:

EventBridge Pipe fails to create on first apply. This is an IAM eventual-consistency issue. The role and policies are created correctly, but EventBridge performs an upfront access check before IAM has finished propagating. Re-run terraform apply - Terraform leaves the role in place and only retries the pipe.

Secret already scheduled for deletion. Force-delete the affected secret(s) via the CLI (see Redeploying after a destroy above), then re-apply.

CLD deploys cleanly but no data appears in Operata. The EventBridge Pipe shows RUNNING but no contact-lens summaries appear. Check that Contact Lens is enabled on your Amazon Connect instance and that calls are being processed with Contact Lens analysis turned on.

Terraform inline_policy deprecation warning. Terraform may print a deprecation warning on aws_iam_role.inline_policy. This is a provider-level notice only. The configuration applies cleanly and has no functional impact.


Frequently asked questions

Q: What happens if we haven't migrated before the deadline?

A: Nothing stops working immediately. Existing alerts and notifications will continue as normal. However, if issues arise, AWS will require the update to be completed before they can help with support cases - and Operata will do the same.

Q: Will this cause any downtime or data loss?
A: There is a brief gap of approximately 2–5 minutes per stack during the update where data collection is paused. Calls handled during this window will not appear in Operata. Schedule updates outside of peak contact centre hours where possible.

Q: Do I need to update all stacks at once?
A: No. Each stack can be updated independently. However, we recommend completing all applicable stacks within the same maintenance window to avoid running a mixed-runtime environment.


Need help?

If you run into any issues, or aren't sure which stacks or environment applies to your setup, we're here to help.

📧 Email us at help@operata.com
💬 Or send a message directly from within the Operata application

Did this answer your question?