module "runlayer_infrastructure" in your root configuration. Merge examples with your existing values; do not declare the same input twice.
DNS and TLS
domain_name is the application hostname, such as ai.example.com. hosted_zone_name is the existing authoritative Route 53 zone, such as example.com; they are usually different. The deployment guide creates and validates *.example.com in ACM and creates the application DNS record in that zone.
For DNS in another account, configure aws.route53 with the DNS account role and set cross_account_hosted_zone_id to that zone’s ID. Always pass both provider aliases to the module. The certificate must be in the workload account and ALB region.
For DNS outside Route 53, supply an issued ssl_certificate_arn, leave enable_acm_dns_validation = false and create_dns_records = false, then create the application DNS record yourself using the module’s alb_dns_name output. Complete ACM validation with your DNS provider before deploying.
Choose one certificate strategy:
Access choices
Private ALBs and PrivateLink do not remove outbound requirements. AWS VPC endpoints cover specific AWS APIs; WorkOS, AuthKit, catalog, and other external services still need outbound HTTPS. Review egress requirements.
Network Configuration
CreateLoadBalancer to fail with A load balancer cannot be attached to multiple subnets in the same Availability Zone. Subnet size can be small (for example /26) as long as the ALB has free IPs (~8+). Multiple ALBs may share the same public subnets.
For topology options, see Networking.
Security Configuration
waf_webhook_allowlist_ipv4_cidrs and waf_webhook_allowlist_ipv6_cidrs
default to []. They admit the specified request-origin IPs only for POST
agent webhook invocation: /api/v1/agents/{uuid}/webhooks/{token} and the
legacy /api/v1/assistants/{uuid}/webhooks/{token}, with an optional trailing
slash. Paths are URL-decoded and normalized before matching. Webhook management
routes and other methods receive no additional access; existing general
allowlists and public-path exemptions still apply.
Nonempty lists require waf_enable_ip_allowlisting = true; nonempty IPv6 lists
also require enable_ipv6 = true. Invalid configurations fail planning; empty
lists remain valid when either feature is disabled. General allowlist CIDRs
remain required when allowlisting is enabled. Entries must be valid IPv4 CIDRs
with prefix lengths 1–32 or IPv6 CIDRs with prefix lengths 1–128.
The caller maintains these ranges; the module does not fetch vendor IP lists.
Managed WAF rules and webhook authentication still apply. These lists cover
invocation routes across agents, so review the admitted ranges, webhook
credentials/signing, and execution identity with your security team before
activation. ALB security groups must also permit the integration’s source IPs.
When AgentCore is enabled, WAF IP allowlisting requires AgentCore VPC mode with PrivateLink. PUBLIC mode has no stable source IP to allowlist. Configure this before deployment:
Slack and Microsoft Teams with an IP allowlist
Agents and the Runlayer Assistant answer in Slack and Teams only if those services can reach your deployment. Messages to Slack and Teams go out from Runlayer, but every mention, DM, reply and button click comes back in as an HTTPSPOST from Slack or Microsoft to your public hostname. If the WAF IP allowlist, the ALB security group or a VPN-only ingress drops those requests, posting from Runlayer to Slack still works, but agents never reply and nothing shows up in Runlayer’s logs.
Slack and Microsoft don’t publish a fixed list of source IPs for these requests, so allowlisting their IPs isn’t reliable. Exempt the paths instead:
- Requests are still authenticated. Slack events and button clicks must carry a valid signature from the app’s signing secret, Teams messages a valid Bot Framework JWT, and the install and consent callbacks a signed link or one-time state. AWS managed WAF rules still apply.
- Keep
alb_allowed_cidrs(andalb_allowed_ipv6_cidrs) open to the internet,0.0.0.0/0. The WAF exemption doesn’t open the security group. - With a private-only ALB, Slack and Teams can’t reach you at all. Use the dual ALB setup: the public ALB takes Slack and Teams traffic and the internal ALB serves your users.
- If
SLACK_APP_URLorMS_TEAMS_APP_URLpoints at a different host thanAPP_URL, that host must be publicly reachable instead.
POST /api/v1/integrations/slack/... means the request never reached Runlayer.
Dual ALB Setup (Split-Horizon DNS)
- Public DNS → public ALB
- Private DNS → internal ALB
- ECS services register with both ALBs
- WAF applies only to the public ALB
VPC Peering for Cross-VPC Connectivity
existing_vpc_id).
Inbound PrivateLink access to Runlayer
Expose Runlayer to consumer VPCs with an endpoint service:terraform output -raw privatelink_service_name to create consumer interface endpoints. Accept endpoint requests when acceptance is required and configure consumer DNS, routing, and security groups.
Outbound private connections for Runlayer Deploy
Private connections let MCP servers you run on Runlayer Deploy reach systems on your private network, through AWS PrivateLink or a tunnel. Turn on the connection types you need:runlayer.yaml. See private connections.
Upgrade the module with the application: each module release selects the matching router, endpoint, and connector bundle. Enable tunnels only with a compatible application release. Upgrade the application before the module; on rollback, restore the previous module configuration before the application. See Updates.
When runlayer_obs_otel_enabled = true, the module runs a private OTEL
Collector for tunnel metrics and traces once the configured bearer secret or
plaintext fallback resolves. An unseeded secret leaves the collector disabled;
seeding it later enables the collector on the next apply without an input
change. Schedule that apply as a tunnel interruption: it restarts tunnel
routers and drops live sessions while clients reconnect.
Routers and endpoints send OTLP/HTTP to its Cloud Map name on port 4318. The
collector alone receives the observability bearer secret. Of the module-managed
tunnel tasks, it is also the only one with public HTTPS egress; for telemetry,
routers and endpoints can reach only the collector. Tunnel logs continue to use
CloudWatch Logs. One
256 CPU / 512 MiB replica is the default capacity for up to 100 endpoint
tasks, about 1,700 metric points/second, and 1,000 sampled spans/second. Set
tunnel_otel_collector_desired_count = 2 for redundant capacity; changing only
this value scales the collector without redeploying tunnel routers or endpoints.
For an existing-VPC deployment, confirm the selected private subnets can reach
otlp.obs.runlayer.com on HTTPS before upgrading. Schedule the upgrade for a
tunnel interruption: adding the collector endpoints restarts the tunnel routers
and drops live tunnel sessions while clients reconnect. Apply the new module,
wait for the collector service to reach steady state, then wait for existing
tunnel connections to reconcile to the current configuration. The deprecated
tunnel_otel_proxy_security_group_id output remains valid during migration, so
an existing Tailscale telemetry proxy can keep the same SG attached through the
soak. Do not remove that proxy until collector metrics and traces are healthy.
To roll back during soak, set runlayer_obs_otel_enabled = false, apply, and
wait for tunnel connections to reconcile away their collector endpoints before
restoring the previous module and application versions. This stops tunnel
metrics and traces during rollback. Application observability logs keep
exporting when runlayer_obs_otel_logs_enabled = true; tunnel logs remain in
CloudWatch.
Optional tunnel connector metadata
Tunnel connectors send no optional metadata by default. To share their release version, add this environment setting to each connector container:version is currently the
only supported value. Empty or unset disables reporting. Unknown values prevent
startup. Version metadata travels inside the encrypted tunnel session and never
changes access permissions or routing.
Settings → Network access shows distinct reported connector versions.
Multiple versions can appear during an upgrade. Disconnected sessions disappear
after the next endpoint heartbeat; stale endpoint reports expire.
Connector versions is hidden when no current versions are reported. This
does not change connection status.
The backend and UI can be upgraded before the tunnel bundle. Keep router and
endpoint images on the current released bundle during that rollout; deploy the
metadata-capable bundle separately after the backend is stable. Building or
publishing a bundle does not deploy it.
Finish upgrading the backend and workers before upgrading tunnel endpoints.
Before rolling back to a backend release without metadata support, disable
reporting and reconnect opted-in connectors. Wait for endpoint heartbeats to
clear the stored version reports, then restore the previous endpoint bundle
before rolling back the backend.
Private connection provisioning
ECS private connections reconcile asynchronously. Revision2 is an internal private-connection configuration marker, separate from the ECS module release (for example, v33.1.0). This migration guidance applies to existing connections, not initial platform installation. Existing Deploy PrivateLink
connections upgrade to connection configuration revision 2, adding connection-owned access
security groups while retaining the existing endpoint and legacy security group.
Wait for reconciliation before creating or redeploying an MCP deployment that uses
the connection. Each deployment reserves one of its five security-group slots
for its service. Tunnels use the remaining four slots first; PrivateLink
connections fill any free slots in connection-name order. These connections use
shared access groups, adding no endpoint rules per deployment. Reordering the
connections in YAML does not change the allocation.
PrivateLink connections beyond those four attachment slots use rules referencing
the deployment’s service security group. Each overflow connection consumes one
inbound rule per configured port on its endpoint security group, shared across
all deployments using that connection through direct grants. With the default
60-rule quota and no other rules, a five-port overflow connection supports 12
deployments; existing rules, including legacy grants, reduce that capacity.
Tunnels remain limited to four per deployment, including deployments that also
use PrivateLink.
The ECS module upgrade grants workers permission to inspect the applied VPC rule
quota and prefix lists and describe ECS service deployments before rolling out
updated workers. During the upgrade, a deployment selecting more than four
connections can fail on an older worker. Retry it after the rollout finishes.
Existing deployments with four or fewer private connections retain their shared
access and do not need a redeploy. Redeploy when adding connections.
Private-connection redeploys wait for ECS to finish rolling out replacement tasks
before removing obsolete direct ingress grants. Endpoints and DNS names stay the
same.
The worker checks rule capacity before applying overflow grants, but concurrent
AWS changes can still exhaust it. A capacity error identifies the affected group
and required headroom. Reducing selected ports or overflow usage, removing unused
grants, or increasing the AWS quota can free capacity.
Before rolling back the application, reduce each affected deployment to four or
fewer total private connections and redeploy it to restore shared security-group
attachments. Then roll back the backend and worker images. An image rollback
alone does not restore network rules. Removing access blocks new connections
after rollout; existing tracked TCP connections may remain open.
RUNLAYER_PRIVATE_CONNECTION_TERRAFORM_TIMEOUT_SECONDS defaults to 1800 and
must be a positive finite number. Set it through additional_backend_env_vars
to override the shared deadline for Terraform init, apply/destroy, and output
commands. It does not change ordinary MCP deployment timeouts. Failed
reconciliation preserves the connection’s prior usable state and is retried
automatically up to 3 times, at least 15 minutes apart; if it still fails,
contact Runlayer support to inspect and recover the upgrade before retrying the
deployment.