Skip to main content
RunBook Academy

← All assessments

Final assessment · advanced · ~180 min · pass ≥ 80%

Git, CI/CD & GitOps for Infrastructure Engineers — Final Practical Assessment

Objectives

  • Diagnose a flawed delivery environment end-to-end
  • Identify technical risk, blast radius, and required evidence
  • Prescribe structurally sound remediation and validation
  • Distinguish procedural from structural controls in prevention

10 graded questions · 50 additional practice-bank scenarios · last verified 2026-08-25

Assessment questions

Objective questions are scored automatically. Scenario answers use a second-stage rubric for evidence, remediation, and rollback.

Knowledge check · 10 questions

  1. Q1. Diagnose this problem and propose a remediation.

    A developer added an S3 backend to the production Terraform configuration and committed `terraform.tfvars` containing: ```hcl aws_region = "us-east-1" bucket = "acme-prod-tfstate" dynamodb_table = "acme-prod-tflock" ``` along with three lines that look innocuous to a reviewer but are in fact credentials: ```hcl aws_access_key_id = "AKIAIOSFODNN7EXAMPLE" aws_secret_access_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" aws_session_token = "FQoGZXIvYXdzEHcaSESSIONTOKEN" ``` A `git log -p terraform.tfvars` shows the lines were added in the same commit that introduced the backend; `gitleaks` was not configured for this repository. The push was direct to `main` because the repository has no CODEOWNERS file and no required reviewers on the path.

  2. Q2. Diagnose this problem and propose a remediation.

    A team stores Kubernetes Secrets for a production namespace in a `values-prod.yaml` committed to the application Helm chart repository: ```yaml database: host: prod-db.acme.internal username: app password: "Hunter2!Hunter2!" sslmode: verify-full api: jwtSecret: "eyJhbGciOiJIUzI1NiJ9.real-secret-not-a-jwt" ``` The chart is consumed by Argo CD via a Helm source; Argo CD has not been configured to ignore the rendered Secret manifest, and the Application is `Synced` and `Healthy`. A `git log --all -p` shows the password has been in the repo for nine months; a GitHub secret-scanning alert fired three days ago and was dismissed with the comment "false positive — test value."

  3. Q3. Diagnose this problem and propose a remediation.

    The repository's `.github/workflows/deploy.yml` contains the following step: ```yaml - name: Configure kubectl env: KUBECONFIG: ${ secrets.KUBECONFIG_PROD } run: | echo "$KUBECONFIG" | base64 -d > kubeconfig kubectl --kubeconfig=kubeconfig apply -f manifests/ ``` The `KUBECONFIG_PROD` secret was set at the repository level by an engineer who pasted a base64-encoded kubeconfig containing a long-lived service-account token bound to the `cluster-admin` ClusterRole. The token is 12 months old; the service account was created by an out-of-band `kubectl create serviceaccount` during an emergency six months ago. The deploy job has run 240 times since.

  4. Q4. Diagnose this problem and propose a remediation.

    A `pre-commit` configuration in the team template runs a `gitleaks` scan, but the engineer's local environment has `core.hooksPath` unset (`.git/hooks/` is the default), so the hook is never installed. The engineer committed a private SSH deploy key intended for `~/.ssh/id_ed25519` into `ansible/inventory/prod`. The key was added with `git add -A` from a directory in which `ansible/inventory/prod/` had not yet been added to `.gitignore`. The push succeeded because the repository has no required status checks and no CODEOWNERS for the inventory path.

  5. Q5. Diagnose this problem and propose a remediation.

    An engineer force-pushed to `main` after an interactive rebase, replacing the eight-commit history with a squashed two-commit history. The pre-push tip was at commit `8f1a2b3`; the post-push tip is at `c4d5e6f`. Branch protection does not block force pushes from the bypass list, which includes the on-call rotation. Production is pinned to the container digest `sha256:9c4e...7a` built from `8f1a2b3`. CI for two feature branches that were based on `8f1a2b3` now shows "Your branch is behind `origin/main` by 6 commits" with merge conflicts against a base that no longer exists.

  6. Q6. Diagnose this problem and propose a remediation.

    A release branch `release/2026-08` was force-pushed at 02:14 to "clean up" four commits the releaser considered noise. The force push was performed from a laptop on the releaser's home network (the audit log shows the IP) and was not coordinated with the platform team. Three downstream pipelines were configured to build from the tip of `release/2026-08`: the container build pipeline, the SBOM regeneration job, and the Terraform plan artifact. All three jobs rebuilt at 02:15, producing artifacts whose SHAs differ from those referenced in the production deploy manifest. The deploy manifest in the GitOps repo still references the original tags.

  7. Q7. Diagnose this problem and propose a remediation.

    The team uses per-environment branches — `env/staging`, `env/production`, `env/dev` — and a workflow that deploys the tip of each branch to the matching environment. A developer force-pushed `env/staging` at 14:22 with a `--force` (no `--force-with-lease`) after rebasing onto `env/production`. The force-push orphaned four commits from the previous day, one of which contained a Terraform module version bump that staging was depending on. The CI status on the orphaned commits is green; the new tip is failing on a kubeconform validation because the module bump is gone. The branch-protection rule on `env/staging` has "Allow force pushes" enabled for the team group.

  8. Q8. Diagnose this problem and propose a remediation.

    An attacker compromised a developer GitHub personal access token and pushed a workflow file change to `.github/workflows/ci.yml` that added a step which exfiltrated `secrets.*` to an external webhook. The push went to a feature branch; the attacker also opened a pull request from the branch with the title "test: bump ci workflow." Branch protection requires one reviewer; the reviewer approved without reading the diff because the diff appeared to be a single-line bump. The workflow ran on the PR and read `secrets.AWS_ACCESS_KEY_ID`, `secrets.AWS_SECRET_ACCESS_KEY`, and every other repository secret, then POSTed them to a webhook. The webhook delivery is visible in the repository audit log under "workflow run logs."

  9. Q9. Diagnose this problem and propose a remediation.

    The repository `acme/infrastructure` is the source of truth for Terraform, Ansible, and the GitOps overlay. Branch protection on `main` requires a single approval and a passing CI build, but does not require a CODEOWNERS review, does not restrict force-pushes, and does not restrict direct pushes from administrators. There is no `CODEOWNERS` file. The last 30 commits to `main` were merged by three different engineers, two of whom are not in the platform team GitHub team. CI status checks pass on every commit.

  10. Q10. Diagnose this problem and propose a remediation.

    The repository branch-protection rule on `main` requires one approval and "CI must pass," but the CI workflow runs only `terraform fmt -check` and `terraform validate`. There is no static-analysis step (`tflint`, `tfsec`, `checkov`), no kubeconform step, no SBOM step, no image scan, no secret scan, and no required check for `argocd-image-updater` diff. A change that introduced a misconfigured `replicas: 0` in a production Deployment was approved and merged; CI was green because `terraform fmt` and `terraform validate` succeeded. The mistake was caught by an on-call engineer at 03:00 when the monitoring alert fired.

Passing score: 80%. Answers are checked in this browser.

Git, CI/CD & GitOps for Infrastructure Engineers — Final Practical Assessment

The final practical assessment grades ten scenarios in a three-hour attempt. The source retains fifty additional scenarios as a practice and instructor bank, but they do not inflate the graded workload. Each scenario presents a deliberately flawed delivery environment and asks the student to diagnose, evidence, remediate, roll back, and prevent. A passing score is 80%.

The practical is open-book and open-shell: the scenarios describe what the team sees, and the student must show the evidence chain that distinguishes a real diagnosis from an assertion. Every scenario answer should include:

  • the symptom and its impact
  • the evidence you would collect, in order
  • the structural or procedural cause, with justification
  • the smallest remediation that fixes the root cause
  • the rollback you would keep ready if the remediation failed
  • the structural prevention that makes the failure impossible

A high-quality answer is specific, references the platform object involved (branch-protection rule, IAM role binding, ClusterRoleBinding, Application sync policy, registry admission policy), and identifies a concrete change in the operator’s practice. An answer that names the fix without naming the evidence is procedural; an answer that names the structural prevention without naming the evidence chain is unsupported.

Rubric calibration example

Use the checklist literally: mark only an item that the written response states explicitly. Do not award credit for what the learner may have meant.

  • Insufficient: “Rotate the key and rerun the pipeline.” This proposes an action but gives no evidence, blast-radius analysis, rollback, or structural prevention.
  • Passing: names the relevant audit and platform evidence, distinguishes the proximate and structural cause, orders containment before cleanup, proposes the smallest safe change, and states a usable rollback.
  • Excellent: does everything in the passing response and also identifies negative tests, ownership, expiry/cleanup, post-change verification, and a control that makes recurrence structurally impossible.

The displayed evidence, remediation, and rollback criteria are the observable grading contract. A fluent answer receives no implied credit for a criterion it does not actually address.