Environment Setup
An environment is stood up from three Terraform modules in adventive-platform-infra, in order: build the AMI (imagebuilder), create the Cloudflare tunnel and its Secrets Manager credentials (cloudflare-tunnels), then run the EC2 fleet (cflared-asg). All commands run from the local sandbox that sources .cowork-env; deploys never run from CI. Modules live under infra/<service>/ and are parameterized by a var.environments map, not a -var env= flag (the imagebuilder module is environment-agnostic and takes no env at all).
Prerequisites
Section titled “Prerequisites”- The Cloudflare account is on the Workers Paid plan with Zero Trust enabled, and the environment’s DNS zone is active (
adventive.dev,adventivestg.com, oradventive.com). - The environment’s VPC and subnet exist, and the artifacts bucket
adventive-platform-artifactsexists. - The Aurora endpoints the tunnel will reach are known (they become the ingress
servicetargets).
Step 1: build the AMI
Section titled “Step 1: build the AMI”The tunnel host image is built by AWS EC2 Image Builder from the imagebuilder module: a recipe on an Ubuntu 22.04 parent, layering the AWS-managed components (update-linux, aws-cli, amazon-cloudwatch-agent) and the Adventive components (adv-cflared-cloudflared, adv-cflared-bootstrap-script, adv-cflared-newrelic). The bootstrap script is uploaded to S3 by Terraform (aws_s3_object), so no manual copy is needed. The AMI is environment-agnostic: one image serves every environment.
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/imagebuilder && . ~/Documents/Claude/.cowork-env && terraform applyRun the pipeline to bake the image, then publish its AMI ID to the SSM parameter the ASGs read. See Deployment for the pipeline run and the SSM publish (the publish Lambda and its manual fallback).
Step 2: create the Cloudflare tunnel and secrets
Section titled “Step 2: create the Cloudflare tunnel and secrets”The cloudflare-tunnels module creates, per environment: a named Cloudflare tunnel (config_src = local), a proxied CNAME per ingress hostname pointing at <tunnel-uuid>.cfargotunnel.com, and an AWS Secrets Manager secret at /adventive/cloudflared/<env> holding the rendered config.yml (tunnel UUID, credentials-file path, metrics: 0.0.0.0:2000, the ingress rules, and a catch-all http_status:404) plus the credentials JSON. Add the environment’s entry to the module’s environments map with its zone_id, apex, and ingress list, then apply.
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/cloudflare-tunnels && . ~/Documents/Claude/.cowork-env && terraform plan -out=tfplanReview the plan, confirm the tunnel and secret are for the intended environment only, then terraform apply tfplan. The tunnel secret and the rendered credentials live in Terraform state, so the state backend must be treated as sensitive.
Step 3: run the EC2 fleet
Section titled “Step 3: run the EC2 fleet”The cflared-asg module creates, per environment: the runtime IAM role and instance profile (adv-cflared-runtime-<env>), an egress-only security group, a launch template that reads the AMI ID from SSM at apply time, and an Auto Scaling Group with a rolling instance refresh. Add the environment to this module’s environments map with its subnet ID(s), instance type, desired capacity, and min_healthy_percentage, then apply.
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/cflared-asg && . ~/Documents/Claude/.cowork-env && terraform plan -out=tfplanReview that the launch template image_id is the intended AMI and the IAM policy grants read on both /adventive/cloudflared/<env> and the New Relic license secret, then terraform apply tfplan. The ASG launches an instance from the AMI; at boot, cflared-bootstrap.service resolves the environment from the adv:env instance tag, fetches the tunnel secret and the New Relic license key from Secrets Manager, writes /etc/cloudflared/config.yml plus the credentials file and /etc/newrelic-infra.yml, and then cloudflared.service starts.
Step 4: verify
Section titled “Step 4: verify”- The Cloudflare Zero Trust dashboard shows the
adv-cflared-<env>tunnel with a healthy connector. - A throwaway Worker bound to the environment’s Hyperdrive resource runs
SELECT 1against the Aurora endpoint successfully. - On the host (via Session Manager or an SSM
send-command),cflared-bootstrap,cloudflared, andnewrelic-infraare allactive,/etc/newrelic-infra.ymlhas the license key, andcurl -s http://127.0.0.1:2000/metricsreturnscloudflared_tunnel_ha_connectionsat 1 or more. - The host appears in New Relic (account 497659) under Infrastructure.
The full verification checklist is in the runbook.