Tickety
TT / TT-40 Hosting
TT-41 Ready for development

Stand the hosting up

infra 8 points · Engineering

There is nowhere to publish to. Before any workflow can copy a file there has to be a bucket with a name in front of it.

The stack owns everything except one thing: the delegation in the root account that points toptable at this account's hosted zone. That is done by hand, once, and everything else follows from it.

Acceptance criteria

  • One CloudFormation template under infra/ creates the hosted zone, the certificate, the bucket, the distribution, the IAM roles and the alias record
  • The domain name comes in as a template parameter. The certificate ARN does not, because the stack now issues it rather than being handed one
  • The bucket has static website hosting enabled with index.html as the index document. CloudFront takes the website endpoint as a custom origin, not the REST endpoint — KB-7 has why, and getting this wrong breaks the previews rather than the live site, so it will pass a casual test
  • HTTP redirects to HTTPS
  • A robots.txt at the bucket root disallows /tt-
  • The bucket name, distribution id, role ARNs and site URL are recorded in the GitHub Actions environments the later stories read. No workflow hardcodes any of them
  • Uploading a hand-built dist/ and loading https://toptable.enablis.tech/ serves the app

DNS and the certificate

  • The hosted zone for toptable.enablis.tech is created in the development account, and its four nameservers are a stack output. The delegation is wired up from them by hand, in the root account
  • The hosted zone is retained when the stack is deleted. Its nameservers are what that delegation points at, and a zone deleted and recreated is given different ones. Losing them takes the site dark in a way that reads as a certificate problem
  • The certificate is requested with DNS validation against that zone, in us-east-1 whatever region the bucket is in. CloudFront reads certificates from that region only
  • The alias record for toptable.enablis.tech points at the distribution
  • The first deploy stops at the certificate and waits. ACM validates over public DNS and nothing public knows where the zone is until the delegation exists. The nameservers are available from the zone long before the stack finishes, so the wait is workable — but it has to be written down somewhere a person will find it, or it reads as a hang

Two roles, not one

  • A publish role, trusted by GitHub's OIDC provider and scoped to this repository, may write to the bucket and create invalidations on the distribution, and may do nothing else. TT-42 and TT-43 assume this one
  • An infrastructure role, trusted the same way, may change the stack's own resources. Only the infrastructure workflow assumes it
  • They are separate because the infrastructure role can write IAM. Giving that to the role every merge and every pull request push already holds is a privilege escalation one careless workflow edit away

Deploying the stack

  • A workflow applies the template. Nothing is deployed from a laptop once the first apply has happened
  • It runs only when infra/ changed. A merge that touches nothing there deploys no infrastructure
  • A pull request touching infra/ gets a CloudFormation changeset created and posted on it, and does not execute it. The same bargain as a preview: something a person can read before approving, rather than a diff and a hope
  • Merging applies the changeset. The review is the changeset on the pull request, not a second approval after it — somebody reads what will change, approves the pull request, and merging carries out the thing they read
  • So the protection that matters sits on the pull request, not on the environment. Nothing waits for an approval after a merge, so a merge to main touching infra/ changes infrastructure. main requiring a review is what makes that a gate rather than a formality
  • Infrastructure still uses its own environment, separate from the previews'. They hold different role ARNs. It carries values, not a gate
  • Applying a template that has not changed is a no-op and reports as one rather than failing
  • A failed apply leaves the stack in a state the next run can proceed from, and says which resource failed

Agents

Two more, in .claude/agents/, on the same terms as the five TT-2 established. The model is set explicitly on both.

Agent Model Responsible for
infra-developer sonnet The CloudFormation template, the workflows and the IAM policies. Works to KB-7
infra-reviewer opus Reads an infrastructure diff cold as an AWS engineer would. Reports on security posture, least privilege, blast radius and AWS practice
  • infra-reviewer has no Write and no Edit, for the reason reviewer does not. A reviewer that can edit quietly fixes what it finds, and then you have the fix instead of the finding
  • It is a separate agent from reviewer because the questions are different ones. Whether a policy is least privilege, whether a bucket should be public, whether a role can escalate its own permissions and whether a change can be rolled back are not things a code reviewer is looking for
  • infra-developer is separate from the other developers because none of them should be writing IAM, and because a template is not code that tests can cover

Notes

The first apply is by hand and is the exception. The role the workflow assumes is created by this stack, so it does not exist until the stack has been applied once.

It is also the only apply that waits for a person. Once the delegation is in place the certificate validates and renews on its own, and no later deploy stops for anybody. KB-7 has the ordering.

Linked pages

Comments

No comments on this issue