Skip to content

Internet Requirements

Discover the exact internet egress a role or playbook needs — the host:port allowlist a customer's proxy or firewall must permit — by running the role in an internet-hardened environment and watching what it tries to reach.

Invoke it by asking Claude (e.g. "discover the internet requirements for the perimeter_auth role") or with the slash command /internet-requirements.

Why this exists

Customers run Epic infrastructure behind restrictive egress controls. To document what a role legitimately needs to reach, guessing from the code is error-prone: package installs pull transitive dependencies, downloads follow redirects to CDN hosts, and some fetches happen on the control node rather than the target. This skill produces an empirical, conclusive list instead.

How it works

The dev AWS test-VM subnets have no route to the internet — everything egresses through a proxy. The skill leans on that:

  1. Stand up a dedicated, default-deny squid proxy (the aws-squid-proxy Coder template) — separate from the shared dev proxy, so its logs contain only this role's traffic and it starts by blocking everything.
  2. Point a fresh test VM and the Ansible controller at that proxy.
  3. Run the role. squid logs every attempt; a blocked one appears as TCP_DENIED … CONNECT host:443.
  4. Add the blocked host to the proxy's allowlist, wait for it to take effect, and re-run.
  5. Repeat until the run is clean. The union of allowed hosts across all runs is the requirement list.

Granularity is host:port — plain squid logs CONNECT host:443 for HTTPS without intercepting TLS, which is exactly what a proxy/firewall allowlist needs (no URL paths).

What you get

A table of every requirement, attributed to the task and file that needed it (never a line number — those drift), plus caveats. Example, from a real run against perimeter_auth (RHEL 9, --tags install):

host:port Needed by Where Side
rhui.us-west-2.aws.ce.redhat.com:443 SELinux tooling + nginx/logrotate deps (dnf) imported role linux-system-roles.selinux, via perimeter_auth : Configure SELinux target
nginx.org:443 perimeter_auth : Import nginx GPG key tasks/install_nginx_redhat.yml target
nginx.org:80 nginx yum repo + package install tasks/install_nginx_redhat.yml target
github.com:443 perimeter_auth : Download nginx-prometheus-exporter tasks/enable_monitoring.yml controller
release-assets.githubusercontent.com:443 ↳ GitHub release CDN (302 target) tasks/enable_monitoring.yml controller

Limitations — read these before trusting a result

  • Empirical, not exhaustive. The list only covers the code paths the run actually exercised. A branch that didn't execute (a different OS family, a feature flag off, an already-satisfied step) won't reveal its requirements.
  • Union across runs, not the final run. Because roles are idempotent, a dependency satisfied early (a package installed in run 1) won't be re-requested later, so it won't appear in the final run's log. The skill accumulates across every run.
  • Platform- and region-specific. e.g. rhui.us-west-2.aws.ce.redhat.com is the AWS RHUI mirror for one region; a Satellite host, a different region, or a non-AWS RHEL build differ. The list reflects where it was run.
  • squid only sees HTTP/HTTPS/FTP. Egress over raw TCP, git-over-SSH, or a client that ignores http_proxy won't appear — the skill flags that case rather than silently missing it.
  • A task that clears the proxy hides its requirement. Some tasks set environment: { http_proxy: "" } to force direct egress (e.g. perimeter_auth's controller-side exporter download). That traffic bypasses the discovery proxy entirely — so a run can report success with an empty proxy log while still having a real requirement. The skill recovers those hosts by pulling the URL through the proxy by hand, and flags them as controller-side with the note that the task currently forces direct egress (which would fail on a hardened control node).

Prerequisites & cleanup

Run it from a dev workspace (the Ansible controller must sit in the same subnet /28 as the proxy and test VM — the default). The skill stands up the aws-squid-proxy workspace and a test VM, and tears both down when finished; the proxy's disposable ubuntu/squid Fargate task is controlled entirely through a shared EFS directory (allowlist + access log). Template internals live in coder/aws/squid-proxy/CLAUDE.md.