Before infrastructure code is sent to any cloud API, a static check can be run over the files themselves. What kinds of mistakes does that layer catch, and what is it structurally unable to catch?
answer
- reads the file, nothing else
- no credentials, no API calls
- typos, style, obvious risk
- cannot see existing infrastructure
basics
~20 sStatic checks read only the source, so they catch syntax and schema errors, unknown or misspelled attributes, style and naming violations, deprecated constructs, hardcoded secrets, and obviously risky settings. They cannot know what infrastructure exists or what a change would actually do.
solid answer
~50 sThe static layer parses the files and validates them against the tool's own schema, so it catches anything that is wrong on the page: syntax errors, a resource type or attribute that does not exist, a required argument missing, a type mismatch, a deprecated construct. On top of that, teams usually run a linter for conventions and a security scanner that pattern-matches risky declarations — public storage, an unencrypted disk, a wide-open network rule, a credential written as a literal string. What it cannot do is reason about reality. It has not read any recorded state, has not contacted the provider, and typically has not resolved the actual variable values, so it cannot tell you whether the change deletes something, whether the name collides with an existing resource, or whether your account is even permitted to create it. It is fast, credential-free and safe to run on every commit — and that cheapness is exactly why its scope is narrow.
go deeper
Be ready to say that static checks read only the files — catching typos, missing arguments, style breaches and hardcoded secrets — and that they run on every commit because they are fast and need no credentials.
Separate the three tools that live here: schema validation, convention linting, and security scanning. Explain why a source-level scanner misses a risky value that arrives through a variable or a module default.
Talk about operating the layer: rule-set curation, an auditable suppression path, keeping it blocking rather than advisory, and why it is the only layer you can safely run on a pull request from an untrusted fork.
Frame it as the cheapest place to encode organisational standards, and be honest about the ceiling — beyond a point, pushing more rules into source-level scanning produces noise, and the guardrail belongs against the resolved change instead.
## What "static" actually means here Static means the check reads the source and nothing else: no recorded state file, no API calls, no credentials. That constraint is what makes the layer cheap — it runs on a laptop before a commit, in a pre-commit hook, and in the first seconds of a pipeline — and it is also exactly what bounds what it can know. Three kinds of tool live at this layer, and it helps to separate them because interviewers often blur them together. ## 1. Parse and schema validation The tool's own validation step reads the configuration and checks it is internally coherent: does it parse, does every referenced resource type exist in the declared provider, are required arguments present, do the types line up, are references to other resources resolvable, is an attribute name real. This is by far the highest-value check per second in the whole pyramid. Infrastructure languages are unforgiving about attribute names, and catching a typo here saves a pipeline run. Note the nuance many candidates get wrong: some validation steps still need the provider *plugins* installed locally, because that is where the schema lives — but downloading a plugin is not the same as calling a cloud API with credentials. The check still contacts no account. ## 2. Linting and convention checks A linter enforces the things a schema does not care about: formatting, naming conventions, required tag or label keys, banned resource types, module version pinning, deprecated arguments that still parse, unused variables. These are style and hygiene rules — the class of comment a human reviewer would otherwise leave a dozen times a week, better automated so review attention goes to design. ## 3. Security and secret scanning A scanner pattern-matches the declarations against a rule library: a storage bucket with public access, a database without encryption at rest, a network rule allowing the whole internet on an administrative port, logging disabled, an access key pasted as a literal. This is genuinely useful and genuinely shallow: it can only see what is written literally in the file. If the risky value arrives through a variable, an interpolation, or a default deep inside a shared module, a source-level scanner may miss it entirely — which is one of the reasons the layer above, which inspects the *resolved change*, exists. ## The structural blind spots Be crisp about these, because that is what separates a memorised list from understanding: - **It does not know what exists.** A configuration can be flawless text and still describe a change that destroys a production database, because "destroy" is a property of the difference between the file and reality, not of the file. - **It does not know your inputs.** The same source produces different infrastructure per environment. Static checks usually see the declaration, not the values a particular run will supply. - **It does not know the provider's rules.** Cloud APIs enforce constraints no schema encodes: name uniqueness across an account, region availability, combinations that are syntactically legal and semantically rejected, quota, permissions. - **It does not know order or timing.** Nothing here can tell you a resource will take twenty minutes to become ready or that a delete will fail because something else is attached. ## How teams actually use it Run everything at this layer on every commit, and fail the build on it. It is fast enough that there is no argument about cost, and its failures are unambiguous: a typo is a typo. The one operational caution is rule noise — a security scanner shipped with hundreds of rules will flag findings your organisation has consciously accepted, so you need an explicit, reviewed suppression mechanism, or the whole layer becomes a wall of warnings people learn to scroll past. A useful framing for the interview: this layer answers "is this file sane?", the next answers "is this change safe?", and only a real deployment answers "will the cloud accept it?". Being able to say which question you are answering at which point in the pipeline is the actual competence being probed.
- If a security scanner flags a rule your team has deliberately accepted, what do you do?Suppress it explicitly, in code, with a reason and an owner — an inline exception or a curated rule set that is reviewed like any other change. What you must not do is lower the whole gate to warning-only, because the layer then stops blocking anything and the next real finding scrolls past unnoticed.
- Does the static layer need cloud credentials to run?No, and that is a large part of its value. It may need the provider plugin or schema available locally to know which attributes exist, but it contacts no account. That means it runs safely on a developer's laptop, in a pre-commit hook, and on untrusted pull requests from forks where handing out credentials would be dangerous.
saying these in an interview costs you the question
- Believing validation contacts the cloud to check resources exist
- Thinking a linter can tell you what a change will destroy
- Assuming a secret scanner catches secrets passed through variables
- Treating a clean static run as approval to apply