The Front Door Stops Moving

September 25, 2026

Right now, the company's own homepage answers at whatever address this desk happened to have when I last ran the build.

That is not an exaggeration. The bare domain, nothing in front of it, has an address record pointed at a number the project looks up live.

Every run, it asks a public service on the internet what its own address is at that moment, and writes the answer into the zone.

It works. Right up until something reconnects.

So today that record comes out. The line that pins the front door of a business to one machine gets deleted, and the front door moves somewhere with no address to lose.

A storage bucket, named for the domain itself. Files, sitting there. No server. Nothing running, nothing to patch, nothing that can be logged into.

resource "aws_s3_bucket" "limitless_site" {
  bucket = "limitlessinteractive.com"
}

First it needs a certificate, so it asks for one covering the domain and everything underneath it. To prove ownership, it writes a record into the zone and waits for the authority to read it back.

Then a delivery network goes in front of the bucket. Copies of the site parked in data centers around the world, so the page comes from whichever one is nearest to you.

Anyone arriving over an unencrypted connection gets bounced to the secure one, no exceptions.

Copies held an hour by default, a day at the outside. Two countries turned away at the edge.

And the network signs every request it makes to that bucket, so the bucket knows who is asking.

Then the address at the top of the zone gets written one final time.

Except it is not an address anymore. It is a pointer to the network itself.

There is no number in it. Nothing to go stale. Nothing to keep current. Nobody has to remember to update it, ever again.

resource "aws_route53_record" "limitless_site" {
  zone_id = "Z05575802ULDZNGHPUH6L"
  name    = ""
  type    = "A"

  alias {
    name                   = format("%s.", aws_cloudfront_distribution.limitless_site.domain_name)
    zone_id                = aws_cloudfront_distribution.limitless_site.hosted_zone_id
    evaluate_target_health = false
  }
}

The front door of the business finally stops moving.

Certificate, issued. Network, live. The name resolves from anywhere on earth in under a second.

And the bucket behind it is completely empty.

Don't Change

Welcome back.

Before the break I said the company homepage was answering at whatever address this desk happened to have that morning. That isn't a figure of speech. It's literally what the project was doing, on purpose, in writing.

Buried in the cluster configuration, there's a block that runs a shell command and reads the result back into the project. The command fetches a public service called ipinfo.io, which answers one question: what address does the rest of the internet see when you talk to it?

It comes back as a bundle of facts. The project pulls out one field. The address.

And there's a comment directly above that block. Three words. Don't change.

I like that comment. Somebody knew this was load-bearing and knew it looked deletable.

# Don't change - gets current IP
data "external" "current_ip" {
  program = ["bash", "-c", "curl -s 'https://ipinfo.io/json'"]
}

The Apex

That address gets written into a set of records. Most are fine — the application hostnames, the monitoring dashboards, the media services. Those live on the cluster, the cluster is on that connection, so pointing them at it is correct. Not elegant. Not wrong.

But two of those records aren't application hostnames. They're the bare domains themselves. The apex. Nothing in front of it. Just limitlessinteractive.com, and madeof.glass.

The names on the business cards, pointed at a live lookup of whatever this machine's address was the last time somebody ran the build.

You Can't Put a CNAME There

So why an address record at all? Why not point the domain at a hostname, the way you point everything else at a hostname, and let it follow along?

Because you can't. Not at the apex.

Here's the mechanism. When you point one name at another name, that's a CNAME record. And the rule in the specification is strict: if a name has a CNAME on it, it can't have anything else on it. No other record types. At all.

Fine for a login hostname. But the apex isn't empty. It's where your mail exchange record lives, where the sender policy text lives, where the name servers for the zone are published.

So a CNAME on the apex tells the world your domain has no mail, no name servers, and no policy records. The whole zone falls over.

Which means the apex has to be an address record. Which means it has to be a number. Which means somebody has to know the number, and keep knowing it, forever.

That constraint is thirty-plus years old and it's the entire reason this problem exists.

A Number That Will Eventually Be Wrong

And a number you have to keep knowing is a number that will eventually be wrong.

Not dramatically wrong. Nobody attacks you. There's no incident. The modem reboots during a storm, or the provider rotates the pool, and the connection comes back with a different lease.

Now the front door of two companies points at a stranger. It stays wrong until somebody notices, and then a while longer, because the caches out in the world are still holding the old answer for as long as you told them to.

To be fair: this is a reasonable thing to do when you have a cluster on a connection and need names pointed at it today. It's the shortest path from nothing to working. It's just that the bare domain got swept into the same mechanism as the monitoring dashboards, and the bare domain isn't the same kind of thing.

The Marketing Site Doesn't Need a Server

So today starts with a reframe, and I think it's the real insight of the day.

The marketing site doesn't need a server.

It's a handful of files. Text, images, styling. No login, no database. Every visitor gets identical bytes. So the whole apparatus underneath — the machine, the operating system, the web server process, the patch schedule, the address it lives at — exists to solve a problem the site doesn't have.

Take the server away and a long list of failure modes goes with it. The process can't crash, because there's no process. The disk can't fill up. Nobody can log into it.

Named for the Domain Itself

So the first thing created is a bucket in S3 — object storage — named for the domain, exactly. That's a fossil of the original static-website feature, which matched an incoming hostname to a bucket of the same name. We're not using that mechanism, but the convention stuck, and it still means nobody has to guess later which bucket belongs to which site.

Four Separate Systems Get a Vote

Then comes the part that eats an afternoon the first time you meet it. Bucket permissions.

Four separate systems get a vote on whether a stranger can read a file out of that bucket — per-object lists, the bucket policy, ownership controls, and a guardrail called the public access block that grants nothing and exists purely to say no. That last one was added after a long run of companies discovering their files were readable by the entire internet.

Today, the guardrail is switched off, all four settings, so the bucket may be public if a policy says so. A policy says so — anyone in the world, read objects only, this bucket only.

resource "aws_s3_bucket_public_access_block" "limitless_site" {
  bucket = aws_s3_bucket.limitless_site.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_policy" "limitless_site" {
  depends_on = [aws_s3_bucket_public_access_block.limitless_site]

  bucket = aws_s3_bucket.limitless_site.id
  policy = jsonencode(
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Sid" : "PublicReadGetObject",
          "Effect" : "Allow",
          "Principal" : "*",
          "Action" : [
            "s3:GetObject"
          ],
          "Resource" : [
            "arn:aws:s3:::limitlessinteractive.com/*"
          ]
        }
      ]
    }
  )
}

So the public read path is open, and the network in front is going to use a different, signed path anyway. That's the more interesting half.

Prove It in DNS

Next, the certificate. If this is going to be the real front door, it has to be encrypted, and that means proving to a certificate authority that you control the domain.

The request covers two names: the bare domain, and a wildcard — anything-dot-the-domain. One certificate, everything under the roof.

Validation goes through DNS, not email. That choice matters more than it looks.

Email validation means a message goes to an address at the domain, somebody clicks a link, and the certificate issues. It works exactly once and then it needs a human every renewal. If that person leaves, the certificate expires on a Saturday.

DNS validation means the authority hands you a record, you publish it, and it checks. Here's the payoff: leave the record in place and renewal is automatic, forever, with nobody involved. The proof stays published, so the proof stays valid.

There's also a lifecycle instruction — create the replacement before destroying the old one, so there's never a moment with no certificate at all.

resource "aws_acm_certificate" "limitless_site" {
  domain_name               = "limitlessinteractive.com"
  validation_method         = "DNS"
  subject_alternative_names = toset(["*.limitlessinteractive.com"])

  lifecycle {
    create_before_destroy = true
  }
}

The Same Record Name

Now, publishing those validation records. This is the genuinely tricky part of today's work.

The authority hands back one validation record per name on the certificate. Two names, so you'd expect two records, and the project loops over them and writes each into the zone.

Except the two names are the apex and the wildcard of that same apex. And for those two, the authority returns the same record name, with the same value. It's the same proof. Proving you control the domain proves you control everything under it.

So the loop has two distinct keys, apex and wildcard, but both produce a record at one identical location. Two writes. One address.

Without a flag saying overwrite is allowed, the second write fails. The record already exists, the tooling refuses to clobber it, and the certificate sits in pending validation until it times out.

So there's an overwrite flag on it. One line. It looks like nothing. It's the difference between the certificate issuing and the certificate never issuing.

The lifetime on those records is sixty seconds, which is the right instinct — they get read once, shortly after you write them.

resource "aws_route53_record" "limitless_site_dvo" {
  depends_on = [aws_acm_certificate.limitless_site]

  for_each = {
    for dvo in aws_acm_certificate.limitless_site.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }

  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = "Z05575802ULDZNGHPUH6L"
}

Northern Virginia by Accident

Small aside, and this one is pure luck.

A certificate fronting a content delivery network has to be issued in one specific region. Northern Virginia. Not the region your site lives in — that one, because the network's control plane only looks there. People lose afternoons to this. They set up in Oregon or Ireland, the certificate issues cleanly, and the distribution refuses it with an error that doesn't explain why.

This project never hits it, because the whole project is pinned to Northern Virginia. I don't think that was a decision about certificates — it's just where things started. The requirement is satisfied by accident.

Some fraction of every working system is coincidence nobody has audited yet.

The Distribution

So now the distribution.

Instead of one copy of the site in one building, there are copies cached in data centers around the world, and a visitor gets served from whichever is close. Someone in Sydney doesn't wait for a round trip to Virginia.

The distribution needs to know where the real copy lives. That's the origin — here, the bucket's storage endpoint, the programmatic one that speaks the storage service's own protocol.

That's a fork in the road worth naming. A bucket can present itself two ways. The website endpoint behaves like an old-fashioned web server: ask for a folder, get the index page inside it. The storage endpoint behaves like an object store. Ask for a key, get the object.

Today uses the storage endpoint, with a setting naming a default root object, index.html — which covers the root and only the root. A subfolder doesn't automatically find the index inside it.

  origin {
    domain_name              = aws_s3_bucket.limitless_site.bucket_regional_domain_name
    origin_access_control_id = aws_cloudfront_origin_access_control.limitless_site.id
    origin_id                = local.s3_origin_id
  }

  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"

Not a bug. It's the shape you inherit, and you choose it for a good reason — the next thing created.

Origin Access Control

Origin access control. This is the piece I like most in today's work, and it's four lines long.

The problem it solves: if the delivery network fetches from your bucket over the plain public path, anyone else can too. They skip the network entirely and hit storage directly. Your caching, your rules, your certificate, your restrictions — all optional, because there's a second door wide open next to the first one.

So instead, the distribution gets an identity, and every request it makes back to the bucket is signed with it — the same scheme the command line tools use, signature version four.

Signing behavior is set to always. Not "sign if the request doesn't already carry a signature." Always.

resource "aws_cloudfront_origin_access_control" "limitless_site" {
  name                              = "limitlessinteractive.com"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

So the bucket can tell a request that came through the front from one that didn't. The delivery network stops being a suggestion and starts being the way in.

And that only works over the storage endpoint, because the website endpoint doesn't speak that protocol. The missing folder-index behavior is the price. Good trade for a marketing site. Bad trade for documentation with a deep folder tree.

Forwarding Nothing Is What Makes It Work

Now the caching rules, which are where a delivery network is either fast or pointless.

Two settings do almost all the work, and both are about what the network is allowed to ignore.

Query Strings

Query strings: not forwarded. The home page, and the home page with a marketing tag glued on the end, and the home page with somebody's tracking parameter — all the same page as far as the cache is concerned. One copy serves all of them.

Cookies

Cookies: not forwarded either. Same logic.

This is the thing people get wrong, and it's worth being blunt. If you forward everything to be safe, you have not been safe — you've made the cache key unique per visitor, nothing ever hits cache, and you're paying for a global network to be a slow proxy in front of one bucket.

Forwarding nothing is what makes it work.

The lifetimes: a floor of zero, a default of one hour, a ceiling of one day. Long enough that the bucket barely gets touched, short enough that a typo on the homepage isn't wrong all week. And anyone arriving over an unencrypted connection is redirected, so the certificate isn't optional.

  default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

There's also a geographic restriction — two countries, China and Russia, blocked at the edge, so those requests never reach the bucket at all.

  restrictions {
    geo_restriction {
      locations        = ["CN", "RU"]
      restriction_type = "blacklist"
    }
  }

There Is No Number in the Configuration

And now we close the loop we opened at the top.

Remember the constraint. The apex has to be an address record. It can't point at a hostname. And the distribution has no stable address to point at — it has hundreds, changing constantly, by design.

So what gets written is an alias record. And an alias is a genuinely odd object.

To the outside world it looks like an ordinary address record. A resolver asks for the domain, gets back a number, and never learns anything unusual happened.

But nothing in the zone holds a number. What's stored is a pointer to the distribution. When a query comes in, the DNS service resolves that pointer at answer time and hands back the addresses of whichever edge locations suit whoever is asking.

So it satisfies the specification, because the answer really is an address record. And it satisfies reality, because nobody had to write the address down.

There is no number in the configuration. That's the whole point. A number is a thing that goes stale. The absence of one is the fix.

One Apex Got Upgraded and One Went Quiet

Which brings us to the deletions. And I want to be straight, because it isn't symmetrical.

The block that wrote the live-lookup address into both apexes gets removed. Not commented out. Removed.

So the bare domain for the software company now resolves through the alias, to the delivery network, to the bucket. Solved.

And the bare domain for the other company — the one whose subdomains carry the login service, the dashboards, the media stack — that record is gone, and nothing replaces it. Its subdomains are untouched, written by a different block, still pointing at the cluster. But the bare name at the root has no answer anymore.

I think that's deliberate — that domain is where the internal tooling lives, and its root was never a website. It was swept along by a loop covering both zones, and getting it out of the loop is the point.

Still, worth saying out loud: one apex got upgraded and one went quiet, and only one was the headline.

Public Buckets

The last piece is the smallest — one more entry in the root file, alongside the others. Identity. Mail. Networking. The cluster. Client hosting. And now public buckets. The entire footprint of two businesses, legible on one screen, and adding a website to it is one line.

module "pub_buckets" {
  source = "./modules/pub_buckets"
}

The Bucket Is Empty

So what's actually true at the end of the day.

A bucket named for the domain. A certificate that renews without a person. A distribution in front, encrypted-only, caching hard, signing every request back to the bucket. And a front door with no number in it.

And the bucket is empty.

Nothing in today's work uploads a file. No build step, no publish command. The delivery mechanism is complete and the thing being delivered doesn't exist yet.

Which is the right order, I think. The plumbing is the part with sharp edges — the certificate region, the duplicated validation record, the signed origin, the apex constraint. Content is the easy part, and the easy part shouldn't block on the hard part.

Fair warning to whoever does that next, though: the cache is now holding copies for an hour. The moment there are real files in that bucket, "I uploaded it and the site didn't change" becomes the most common sentence in the building. There's a command to purge the edge copies. Nobody has written it down anywhere yet.

Deleting a Number

But here's what I keep coming back to.

This whole episode is about deleting a number.

A number that was correct when it was written, that had to be re-derived on every run, that quietly tied the public identity of two companies to the state of one internet connection — and the work was to arrange things so that number is never needed again by anyone.

Nobody will notice. There'll be no incident report about the outage that didn't happen. No customer will write in to say the website resolved correctly. The best possible outcome is that the front door is never thought about again for as long as the company exists.

That's the job. Most of the good work in this line of business is invisible, and the invisible part isn't the setup. It's the forgetting.

The front door of the business finally stops moving.

Now somebody has to put something behind it.

valar morghulis