Skip to content

Legacy Systems

← Back to all decks

16 cards — 🟢 3 easy | 🟡 4 medium | 🔴 3 hard

🟢 Easy (3)

1. What is the first rule of the archaeological approach when inheriting a legacy system?

Show answer Observe what exists first — don't change anything yet. The previous team was not stupid; they were working with different constraints, solving different problems, under different time pressures, using the tools available at the time.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

2. When Git says max_connections=100, the server says 500, and docs say 200, which is the real value?

Show answer The server is real. Always. Git is what someone intended. The server is what's actually running. Common causes of drift include manual hotfixes during incidents, config management running a different branch, and environment variable overrides.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

3. Why are cron jobs described as "the dark matter of infrastructure"?

Show answer Cron jobs are the tribal knowledge of a system — nobody documents them, nobody remembers adding them, and they run silently until they break. They hold critical processes together and should be inventoried on day one when inheriting a system.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

🟡 Medium (4)

1. What commands should you run in the "First Day Survey" to understand an inherited system's purpose and network connections?

Show answer For purpose: systemctl list-units --type=service --state=running. For network listeners: ss -tlnp (TCP) and ss -ulnp (UDP). For active connections: ss -tnp to see what's talking to what. Also check installed packages (rpm -qa or dpkg -l), cron jobs, and recently modified files in /etc.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

2. What is the Config Reading Protocol for understanding configs you didn't write?

Show answer Four steps: (1) Find the REAL config the process actually reads (check process cmdline, /proc/PID/cmdline). (2) Identify what was customized vs. default (rpm -V or dpkg -V). (3) Read for intent — comments are gold, look for TODO/HACK/FIXME and date-stamped comments. (4) Map config interdependencies — includes, environment variables, templates vs. rendered configs.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

3. Name four methods for tracing system dependencies when there is no documentation.

Show answer (1) Network connections: ss -tnp shows TCP connections with process names. (2) DNS lookups: tcpdump port 53 reveals what hostnames the system resolves. (3) Filesystem reads: lsof -p PID shows open files, sockets, and libraries. (4) Environment variables: cat /proc/PID/environ reveals database URLs, API endpoints, and integration points.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

4. What are three signs that critical knowledge is trapped as tribal knowledge rather than documented?

Show answer (1) A README says "ask Dave about the deployment process" but Dave left 2 years ago. (2) A script references a path in a specific user's home directory as the canonical source. (3) "We always restart it on the first Monday of the month" but nobody knows why. Discovery technique: git log --all --format='%an' | sort | uniq -c | sort -rn to find who wrote the most code and whether they're still on the team.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

🔴 Hard (3)

1. How can you use systemd unit files to discover service dependencies and configuration sources?

Show answer Run systemctl cat to see the full unit file. After=, Requires=, and Wants= directives reveal ordered dependencies. ExecStartPre= reveals setup steps that must run before the service. Environment= and EnvironmentFile= reveal configuration sources. You can also run systemd-analyze dot to generate a full dependency graph.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

2. How do you use strace to find which config files a process actually reads at startup?

Show answer Run strace -f -e openat to trace all file open calls. Filter out ENOENT (file not found) to see only files that were successfully opened. For a running process: strace -f -e openat -p PID. For nginx specifically: strace -f -e openat nginx -t 2>&1 | grep -v ENOENT. This reveals the real config files versus what you assume they are.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.

3. Why should you "disable before deleting" when decommissioning legacy components, and what is the recommended waiting period?

Show answer If you don't understand what something does, you can't know it's unused. Disabling (rather than deleting) lets you observe whether anything breaks. Wait at least a month after disabling before deleting. Additionally, never change things before understanding them — observe for at least two weeks before making non-emergency changes to inherited systems.

Remember: Modernization patterns: Strangler Fig (gradual), Big Bang (risky), Branch by Abstraction.