Skip to content

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).

  • 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, or adventive.com).
  • The environment’s VPC and subnet exist, and the artifacts bucket adventive-platform-artifacts exists.
  • The Aurora endpoints the tunnel will reach are known (they become the ingress service targets).

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.

Terminal window
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/imagebuilder && . ~/Documents/Claude/.cowork-env && terraform apply

Run 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.

Terminal window
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/cloudflare-tunnels && . ~/Documents/Claude/.cowork-env && terraform plan -out=tfplan

Review 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.

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.

Terminal window
cd ~/Repositories/GitHub/Adventive/adventive-platform-infra/infra/cflared-asg && . ~/Documents/Claude/.cowork-env && terraform plan -out=tfplan

Review 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.

  • 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 1 against the Aurora endpoint successfully.
  • On the host (via Session Manager or an SSM send-command), cflared-bootstrap, cloudflared, and newrelic-infra are all active, /etc/newrelic-infra.yml has the license key, and curl -s http://127.0.0.1:2000/metrics returns cloudflared_tunnel_ha_connections at 1 or more.
  • The host appears in New Relic (account 497659) under Infrastructure.

The full verification checklist is in the runbook.