The Terraform provider example
One flow, authored in HCL for the flow-as-code/flowascode provider, deployed
to a dev and a prod environment from the same commit, and a cookbook of
smaller flows beside it. The tutorials walk through it step by step; this page
is the map of the files.
Everything here was applied to a live Amazon Connect instance on 2026-09-29
with Terraform 1.8.5 and provider v0.1.0 from the Terraform Registry, then
destroyed. tests/terraformProviderExample.test.ts holds the parts that do not
need an AWS account on every push: every flow reads back through the HCL reader,
lints clean, and is already terraform fmt output; the flows module's
companion regenerates byte for byte; the environments differ only where they
should.
What is here
flows/ a Terraform module holding the flows
appointment-line.flow.tf the flow, as a flowascode_contact_flow resource
appointment-line.flowdoc.json the same flow as a FlowDoc, for the studio
variables.tf the instance, and one ARN per reference
outputs.tf the flow's ARN and its document hash, as flow-cli emit writes them
versions.tf the provider the module needs
envs/dev/ dev: creates its own hours, queue and function
envs/platform/ a platform team's configuration prod reads
envs/prod/ prod: reads the platform's state
cookbook/ eight flows, one pattern each, and what they bind
ci/promote-flows.yml a GitHub Actions pipeline: plan, dev, then prod
The flow is written once
flows/appointment-line.flow.tf is the demo appointment line: it checks
hours of operation, sets a queue, looks the caller up with a Lambda function,
and transfers. It names what it uses by reference key, never by ARN:
check_hours_of_operation {
hours_of_operation_id = "hours:main-line"
}
and binds each key once, in the resource's refs map, to a variable of the
module:
refs = {
"hours:main-line" = var.main_line_hours_arn
"lambda:appointment-lookup" = var.appointment_lookup_arn
"queue:appointments" = var.appointments_queue_arn
}
The module has no provider block and no credentials. Each environment's root module configures the providers and passes its own ARNs in.
Two environments, one module call each
envs/dev/main.tf creates the hours, the queue and the function, and calls the
module with their attributes. envs/prod/main.tf creates none of them; it
reads a platform team's state and calls the same module with its outputs. The
module call is the only place the two differ:
module "flows" {
source = "../../flows"
connect_instance_id = var.connect_instance_id
main_line_hours_arn = aws_connect_hours_of_operation.main_line.arn
appointment_lookup_arn = aws_lambda_function.appointment_lookup.arn
appointments_queue_arn = aws_connect_queue.appointments.arn
}
module "flows" {
source = "../../flows"
connect_instance_id = var.connect_instance_id
main_line_hours_arn = data.terraform_remote_state.platform.outputs.main_line_hours_arn
appointment_lookup_arn = data.terraform_remote_state.platform.outputs.appointment_lookup_arn
appointments_queue_arn = data.terraform_remote_state.platform.outputs.appointments_queue_arn
}
Both applies printed the same appointment_line_document_sha256,
3d12a6cd22f8e04018712c78915e89cef32b09d60849b573a7af41f14a641e65: the hash
of the flow as a FlowDoc, with its references still tokens. Prod ran the
document dev ran. Connect holds a different ARN in each environment, and only
there.
Running it
You need Terraform 1.8 or later or OpenTofu 1.10 or later (the provider is on
both registries), credentials for an AWS account, and the
id of an Amazon Connect instance in it. The dev and platform roots also need an
appointment-lookup.zip for the function, which is yours to supply; any
Node.js handler returning a string map will do.
cd envs/dev
export TF_VAR_connect_instance_id=<your instance id>
terraform init
terraform apply
The region is in each root's providers.tf. The tutorials show the output of
every step and what to change for your own flows: