Back to sections

Infrastructure as Code Quiz

Test what you actually know about Infrastructure as Code. Free sample questions below, from easy to hard, with instant explanations.

easy

1. What is the purpose of the terraform.tfstate file?

Stores the configuration code
Logs all Terraform commands
Defines variable defaults
Tracks the current state of deployed infrastructure (real-world mapping)Correct

Terraform needs some way to remember what it's already created and how that maps to your actual cloud resources, and that's exactly what the state file does. Without it, Terraform couldn't tell what's changed (drift) or compute an accurate plan for what to do next.

medium

2. [Terraform] How do you share modules across teams securely?

Publish to private Terraform Registry (Terraform Cloud/Enterprise) or Git (with version tags)Correct
Email .zip files
Commit modules directly in each repo
Use source = "../local-module"

Copying module code into every repo means a bug fix has to be applied in a dozen places, and a plain relative path like ../local-module isn't something other teams can even reach. Publishing to a private registry or a version-tagged Git repo lets teams pull a specific, stable version of a shared module without duplicating any code.

hard

3. A `null_resource` uses a local-exec provisioner that runs a shell script inserting a row into an external database whenever the resource is created. Running `terraform apply` twice in a row, with no configuration changes, inserts the row twice, creating a duplicate. Why doesn't Terraform prevent this?

Terraform's idempotency guarantee covers whether it reapplies the same resource creation action for identical config, not what an arbitrary script inside a provisioner does; the script itself has to be written to be idempotentCorrect
The external database has no unique constraint on the row, and adding one is Terraform's responsibility to generate automatically
local-exec provisioners always rerun on every apply regardless of any triggers, which is a known Terraform bug
null_resource is a deprecated resource type that always retriggers on every apply, unlike every other resource type, which are immune to this issue

Terraform's core idempotency guarantee is about its own resource lifecycle: reapplying the same configuration against infrastructure that already matches it produces no further changes, because Terraform compares desired state against actual state and only acts on differences. A local-exec provisioner is just an arbitrary shell command with no concept of desired versus actual state, so it reruns once per resource creation (or whenever its triggers change), but whether the script's own effect, like an INSERT statement, is safe to repeat is entirely up to whoever wrote it. null_resource is a normal, still-supported resource used specifically to attach provisioners without an underlying cloud object, and provisioners are treated as a last resort precisely because they sit outside Terraform's usual state-comparison model.

easy

4. In Terraform, what is the primary purpose of a module?

To encrypt sensitive variables before they are written to the state file
To package a reusable, self-contained set of resources that can be called multiple times with different input variablesCorrect
To lock the state file so only one engineer can run apply at a time
To automatically roll back a failed apply to the previous known-good state

A module is a folder of configuration that groups related resources together, like a VPC module bundling subnets, route tables, and gateways, so that same bundle can be called repeatedly with different input variables instead of copy-pasting the same HCL for every environment or team. Encryption of state, locking concurrent runs, and rollback on failure are all real Terraform-adjacent concerns, but none of them are what a module is for. Modules exist purely for organizing and reusing configuration.

medium

5. A team defines an `aws_db_instance` resource with `password = var.db_password` and applies it successfully. Months later, a security audit flags that the database password is sitting in plaintext inside terraform.tfstate. What is the best explanation and mitigation?

Terraform automatically encrypts any attribute derived from a variable named password or secret before writing it to state
Terraform state stores the full attributes of every managed resource, including sensitive ones, in plaintext by default, so state should live in an encrypted remote backend with tightly controlled access rather than be committed to version controlCorrect
The password only ends up in the state file if the resource is also referenced in an output block
This can only happen if `sensitive = true` was left off the variable, since marking a variable sensitive removes its value from state entirely

Terraform's state file is essentially a full JSON snapshot of every attribute of every managed resource, and that includes secrets like database passwords in plaintext, regardless of whether the source variable was marked sensitive. Marking a variable sensitive only suppresses it from being printed in CLI plan and apply output and logs, it does NOT remove or encrypt that value in state, which is why assuming otherwise is a common mistake. The real mitigation is treating the state file itself as a secret: an encrypted remote backend with strict access control, and never committing state to git.

hard

6. [Ansible] How do you test Ansible roles before deploying to production?

Use Molecule + Docker/Vagrant to create test instances, converge, verifyCorrect
Run on prod and hope
Manually check syntax
Use ansible-lint only

Testing directly on production is exactly the risk you're trying to avoid. Molecule spins up disposable test instances (via Docker or Vagrant), runs your role against them, and checks the result, so you catch problems on a throwaway environment before the role ever touches a real server.

easy

7. [IaC General] What does declarative infrastructure mean?

You script step-by-step commands to configure resources
You manually click in the cloud console
You use imperative shell scripts only
You describe the desired end state; the tool figures out how to achieve itCorrect

Declarative means you describe the outcome you want ('I want 3 servers running this image') and let the tool figure out how to get there, rather than writing out every individual step yourself like you would in an imperative script or by clicking through a console manually.

medium

8. [Ansible] Which feature ensures idempotency (running twice has same effect as once)?

Using shell module
Running with -v flag
Using command module
Using declarative modules (e.g., file, package, service)Correct

Modules like file, package, and service always check the current state of the system BEFORE making a change, so if something's already in the right state, they simply do nothing. That's what makes running a playbook twice as safe as running it once, versus a raw shell or command module that just blindly re-executes whatever you told it to.

hard

9. A security group was created manually in the AWS console before a team adopted Terraform. They've now written an `aws_security_group` resource block that matches it exactly, but running `terraform apply` would create a brand-new duplicate security group instead of managing the existing one. What should they do instead?

Run `terraform refresh` so the existing security group's attributes get pulled into the new resource block automatically
Add `lifecycle { create_before_destroy = true }` to the resource so Terraform detects the existing security group automatically
Run `terraform import` to bind the existing security group's real-world ID to the new resource address in state, then reconcile any config differences the next plan reportsCorrect
Delete the manually created security group first, then run `terraform apply` normally so Terraform creates a fresh one under management

terraform import is built exactly for this situation: it takes a resource address already declared in configuration plus an existing cloud resource's ID, and creates an entry for it in state so Terraform starts managing the real object instead of creating a competing duplicate. Deleting the working security group first is needlessly destructive and risks an outage if anything currently depends on it. terraform refresh only updates the recorded attributes of resources Terraform is already tracking in state, it can't adopt a resource with no state entry at all, and create_before_destroy is a lifecycle setting that governs replacement ordering, unrelated to adopting unmanaged resources.

easy

10. [CloudFormation] What file format(s) can define a CloudFormation template?

JSON only
JSON or YAMLCorrect
HCL or JSON
YAML only

AWS built CloudFormation to accept templates written in either JSON or YAML, it doesn't force you into just one. Most people end up preferring YAML since it supports comments and a shorter, more readable syntax for its special functions.

Ready for the real thing?

Take the full timed Infrastructure as Code quiz and see your score.

    Welcome to OpsQuiz!

    Real scenario-based DevOps questions, hands-on practice, and clear explanations for every answer.