Lab — Week 1: Environment Provisioning and Threat Modeling
Due: 10 July 2026
Submission: GitLab repo secdevops-s26-<CECS>
- Overview
- Prerequisites
- Repository setup
- Part 1: Environment Provisioning
- Part 2: Threat Modeling
- Submission
Overview
This week establishes the two foundations the rest of the course builds on: a reproducible, documented environment and a threat model that explains why every control you add actually matters. You cannot harden what you haven’t defined.
The lab has two parts:
- Part 1 — Environment Provisioning stands up the three-VM Target System you will use for the rest of the term. A reproducible, documented environment is itself a security control — if you know exactly what your system is supposed to look like, you can detect deviations from it.
- Part 2 — Threat Modeling produces a STRIDE threat model for that system. You will return to this document throughout the course, marking threats as mitigated as you apply controls.
Prerequisites
- Proxmox host provisioned and accessible
- VM templates created (
template-kali,template-ubuntu-26.04) per the Proxmox setup page - OpenTofu (
tofu) installed on the Proxmox host - Ansible installed on the machine you run the playbook from (the Proxmox host or your workstation)
Repository setup
These steps apply to both parts.
-
Create a private GitLab repo at gitlab.cecs.pdx.edu named
secdevops-s26-<CECS>(replace<CECS>with your MCECS username). Clone it to your working machine. -
Add
dmcgrathand the TA as Developer members of your repo.
Part 1: Environment Provisioning
Provision the three-VM Target System and capture a documented baseline.
Tasks
-
Create a folder
lab01/in the repo. All Part 1 deliverables go in that folder. -
Copy the provided Terraform configuration from
secdevops/devsecops-lab/into your repo, or work from it directly on the Proxmox host. -
Read through
main.tfandvariables.tfentirely before making any changes. For each resource block, write a one-sentence explanation of what it creates and why. - Modify
variables.tf(or create aterraform.tfvarsfile) to set your SSH public key:student_ssh_pubkey = "ssh-ed25519 AAAA... your-key-here" - Run the provisioning sequence:
tofu init tofu plan # review what will be created before applying tofu applyRebuilding a single VM. If one VM ends up in a bad state — a botched cloud-init or a half-finished Ansible run — you don’t have to tear down the whole stack. Run
tofu apply -replace='proxmox_vm_qemu.ubuntu_server'to destroy and recreate just that VM, leaving the others untouched. The three addresses areproxmox_vm_qemu.kali,proxmox_vm_qemu.ubuntu_server, andproxmox_vm_qemu.wazuh. Afterward, re-run the Ansible playbook (step 7) against that host to reconfigure it, then runtofu planto confirm there is no drift. - Verify all three VMs are running and reachable. You reach the VMs over the management network (
172.20.100.0/24) — the network the Proxmox host shares with them through the SDNSNATzone, which also DHCP-assigns these addresses. You cannot reach the VMs on their10.10.10.xlab addresses from the Proxmox host: that internal bridge is deliberately isolated (no host IP, no gateway, no uplink), so attack and monitoring traffic stays confined to that segment. The10.10.10.xinterfaces only carry traffic between the VMs. Find each VM’s DHCP-assigned management address in the web UI under Datacenter → SDN → IPAM, which lists every address theSNATzone has handed out and the VM it belongs to (or usetofu show):# From the Proxmox host shell — management IPs, NOT the 10.10.10.x lab IPs. # (Example addresses; yours are DHCP-assigned and will differ.) ssh kali@172.20.100.105 # kali ssh student@172.20.100.102 # ubuntu-server ssh student@172.20.100.103 # wazuh -
Configure the VMs with Ansible. The provided
devsecops-labrepository ships an Ansible playbook (ansible/site.yml) that installs every package and service the rest of the course depends on — Docker, the Wazuh agent, Suricata, and the rest — and pre-pulls the DVWA image so you don’t wait on downloads during later labs. It installs software only; it does not apply any security controls (those are your lab deliverables).From the
ansible/directory of thedevsecops-labrepo:cd devsecops-lab/ansible # 1. Fill in inventory.ini with the IPs your VMs received (one per host group). # Verify the internal_iface for each VM with `ip a` if needed. nano inventory.ini # 2. Run the playbook against all three hosts. # First run (before your SSH key is in place): add -k to be prompted for the # SSH password. Add -K (or --ask-become-pass) if sudo needs a password. ansible-playbook site.yml -k -K # Subsequent runs, once key auth works: ansible-playbook site.yml -K # Target a single host while troubleshooting: ansible-playbook site.yml -l ubuntu_server -KRe-run the playbook until it completes with no failed tasks (it is idempotent — running it twice is safe). Confirm Docker is present on ubuntu-server and the DVWA image is pre-pulled:
ssh student@172.20.100.102 'docker --version && docker image ls vulnerables/web-dvwa' - Take a Proxmox snapshot named
baselineon all three VMs:for vmid in 200 201 202; do qm snapshot $vmid baseline --description "Pre-course baseline $(date +%Y-%m-%d)" done - Draw a network diagram (text or image) showing the three VMs, their IP addresses, roles, and which bridge each interface is on.
Deliverables
Create lab01/lab01.md in your repo containing:
- Terraform annotation — your one-sentence explanation of each resource block in
main.tf tofu showoutput — paste the full output aftertofu applycompletes- Ansible run output — paste the final
PLAY RECAPshowing all three hostsokwithfailed=0 - Screenshot of all three VMs shown as running in the Proxmox web UI
- Network diagram (inline ASCII or attached image) showing VM names, IPs, and bridge assignments
- SSH verification — paste the output of
hostname && ip arun on each VM
Part 2: Threat Modeling
Before hardening anything, you need a systematic answer to the question: what are you defending against? This part produces a STRIDE threat model for your Target System. You will return to this document throughout the course, marking threats as mitigated as you apply controls.
Prerequisites
- Part 1 complete — all three VMs running
Tasks
- Draw a data flow diagram (DFD) for your Target System. The diagram must show:
- All three VMs (Kali, ubuntu-server, wazuh) as processes
- All data flows between them (HTTP/HTTPS, Wazuh agent traffic, SSH, database queries)
- Trust boundaries (internal bridge boundary, container boundary, host/guest boundary)
- External actors (the internet, the student at the keyboard)
Use ASCII art inline in your markdown, or attach an image.
-
Apply STRIDE to each component in the diagram. For each combination of component and threat category, decide whether a threat exists and, if so, document it using the template below.
-
Produce at least 10 threat entries covering at least 4 different STRIDE categories and at least 3 different components.
-
For each threat, rate likelihood (H/M/L) and impact (H/M/L), and briefly explain your reasoning.
-
Identify your top 5 threats by combined score. These are the threats you will focus on mitigating over the rest of the course.
- For each of your top 5, identify which future week of the course you expect will address it.
Threat entry template
### T-XX: [Short name]
- **Category**: [Spoofing | Tampering | Repudiation | Information Disclosure | Denial of Service | Elevation of Privilege]
- **Component**: [which VM, service, or interface]
- **Scenario**: [concrete description of how an attacker exploits this — be specific]
- **Likelihood**: H/M/L — [one sentence rationale]
- **Impact**: H/M/L — [one sentence rationale]
- **Planned mitigation**: [which lab will address this]
- **Status**: OPEN
Deliverables
Create lab02/threat-model.md in your repo containing:
- Data flow diagram with trust boundaries clearly marked
- At least 10 threat entries using the template above
- Top 5 summary table — threat ID, score, and which lab addresses it
This document will be updated throughout the course. Keep it current.
Submission
Commit all files for both parts — lab01/ and lab02/ (and any image files) — and push to your GitLab repo. Ensure dmcgrath and the TA can view the repo. The lab is considered submitted when the commit appears in GitLab before the due date.