diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..315f38d08 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,43 @@ +Vagrant.configure("2") do |config| + config.vm.box = "bento/ubuntu-24.04" + + config.vm.hostname = "quicknotes-vm" + config.vm.network "forwarded_port", + guest: 8080, + host: 18080, + host_ip: "127.0.0.1" + + config.vm.synced_folder "./app", + "/home/vagrant/app", + type: "rsync" + + config.vm.provider "virtualbox" do |vb| + vb.memory = 1024 + vb.cpus = 2 + end + + config.vm.provision "shell", inline: <<-SHELL + + GO_VERSION="1.24.5" + + apt-get update + + apt-get install -y curl tar + + rm -rf /usr/local/go + + curl -LO https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz + + tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz + + cat >/etc/profile.d/go.sh </etc/profile.d/go.sh < default: Box 'bento/ubuntu-24.04' could not be found. Attempting to find and install... + default: Box Provider: virtualbox + default: Box Version: >= 0 +==> default: Loading metadata for box 'bento/ubuntu-24.04' + default: URL: https://vagrantcloud.com/api/v2/vagrant/bento/ubuntu-24.04 +==> default: Adding box 'bento/ubuntu-24.04' (v202510.26.0) for provider: virtualbox (amd64) + default: Downloading: https://vagrantcloud.com/bento/boxes/ubuntu-24.04/versions/202510.26.0/providers/virtualbox/amd64/vagrant.box +==> default: Successfully added box 'bento/ubuntu-24.04' (v202510.26.0) for 'virtualbox (amd64)'! +==> default: Importing base box 'bento/ubuntu-24.04'... +``` + +``` +vagrant ssh -c 'go version' +go version go1.24.5 linux/amd64 +``` + +### From host port: + +``` +$ curl -s http://localhost:18080/health +{"notes":7,"status":"ok"} +``` + +### From guest port: + +``` +$ curl -s http://localhost:8080/health +{"notes":7,"status":"ok"} +``` + +### By ssh: + +``` +vagrant ssh -c 'curl -s http://localhost:8080/health' +{"notes":7,"status":"ok"} +``` + +## Breaking VM + +``` +vagrant snapshot save snapshot_for_lab +==> default: Snapshotting the machine as 'snapshot_for_lab'... +==> default: Snapshot saved! You can restore the snapshot at any time by +==> default: using `vagrant snapshot restore`. You can delete it using +==> default: `vagrant snapshot delete`. +``` + +### Check + +``` +vagrant ssh -c 'go version' +bash: line 1: go: command not found +``` + +### restore output + +``` +time vagrant snapshot restore snapshot_for_lab +==> default: Forcing shutdown of VM... +==> default: Restoring the snapshot 'snapshot_for_lab'... +==> default: Checking if box 'bento/ubuntu-24.04' version '202510.26.0' is up to date... +==> default: Resuming suspended VM... +==> default: Booting VM... +==> default: Waiting for machine to boot. This may take a few minutes... + default: SSH address: 127.0.0.1:2222 + default: SSH username: vagrant + default: SSH auth method: private key +==> default: Machine booted and ready! +==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision` +==> default: flag to force provisioning. Provisioners marked to run always will still run. +vagrant snapshot restore snapshot_for_lab 1,47s user 1,26s system 21% cpu 12,865 total +``` + +### Verify + +``` +vagrant ssh -c 'go version' +go version go1.24.5 linux/amd64 +``` + + +## Questions + +### a + +I choose rsync as the synced folder type to mount host's `.app` directory. It's simple, reliable, helps to avoid some performance and permission issues + +Trade-off: no real-live syncronisation + +### b +Vagrant uses NAT by default. It allows VM acces external network while remaining isolated from other devices on local network. Binding the port forvaring rule to 127.0.0.1 is safer than using a bridged interface, because the application is only accessible from the local network and other devicec could connect directly to the application, unnecessarily becoming more vulnerable to attack + +### c + +I used the shell provisioner to install Go. The installation process only required a few commands: downloading the Go tarball, extracting it, and updating the PATH. The shell provisioner is the simplest solution for this task because it is built into Vagrant and does not require additional tooling or configuration. Tools such as Ansible, Puppet, or Chef are more suitable for larger and more complex infrastructure deployments. + +### d + +Pinning Go to 1.24.5 ensures that every student receives exactly the same compiler version and environment. If only 1.24 were specified, future patch releases could be installed automatically, potentially introducing different behavior, bug fixes, or dependency resolution results. + +### e + +Snapshot in on the same disk with VM. Disk broken - snapshot lost also. Disk formatted - no more snapshot. + +### f + +VirtualBox snapshots use a copy-on-write (CoW) mechanism. When a snapshot is created, the existing virtual disk is not duplicated. Instead, unchanged disk blocks are shared, and only new or modified blocks are stored separately after the snapshot is taken. + +As a result, taking 10 snapshots does not immediately require 10 times the disk space of a single snapshot. Disk usage grows only as changes accumulate between snapshots. However, many snapshots can still consume significant storage over time if the VM's disk contents change frequently. + +### g + +Snapshotting becomes an antipattern when snapshots are kept for a long time and form long dependency chains. Each snapshot depends on previous disk states, which increases storage complexity and can reduce VM performance. + +Long snapshot chains also make management more difficult and increase the risk that corruption of a parent snapshot affects all dependent snapshots. For long-term protection and recovery, proper backups and reproducible provisioning are preferable to maintaining many snapshots. \ No newline at end of file diff --git a/submissions/lab7.md b/submissions/lab7.md new file mode 100644 index 000000000..e99527a69 --- /dev/null +++ b/submissions/lab7.md @@ -0,0 +1,165 @@ +# Lab 7 submission + +`playbook.yaml' + +``` +--- +- hosts: vagrant + become: true + + vars: + addr: ":8080" + data_dir: "/var/lib/quicknotes" + bin: "/usr/local/bin/quicknotes" + data_path: "/var/lib/quicknotes" + seed_path: "/var/lib/quicknotes/seed.json" + + handlers: + - name: restart quicknotes + ansible.builtin.systemd: + name: quicknotes + state: restarted + + tasks: + + - name: Create user + ansible.builtin.user: + name: quicknotes + shell: /usr/sbin/nologin + system: true + + - name: Create data directory + ansible.builtin.file: + path: /var/lib/quicknotes + state: directory + owner: quicknotes + group: quicknotes + mode: "0750" + + - name: Copy binary + ansible.builtin.copy: + src: files/quicknotes + dest: /usr/local/bin/quicknotes + owner: root + group: root + mode: "0755" + notify: restart quicknotes + + - name: Deploy service file + ansible.builtin.template: + src: templates/quicknotes.service.j2 + dest: /etc/systemd/system/quicknotes.service + notify: restart quicknotes + + - name: Reload systemd + ansible.builtin.systemd: + daemon_reload: true + + - name: Enable service + ansible.builtin.systemd: + name: quicknotes + enabled: true + + - name: Start service + ansible.builtin.systemd: + name: quicknotes + state: started +``` + +`inventory.ini` + +``` +[vagrant] +labvm ansible_host=127.0.0.1 + +[vagrant:vars] +ansible_user=vagrant +ansible_port=2222 +ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key +``` + +``` +PLAY [vagrant] ************************************************************************************************************************* + +TASK [Gathering Facts] ***************************************************************************************************************** +ok: [labvm] + +TASK [Create user] ********************************************************************************************************************* +changed: [labvm] + +TASK [Create data directory] *********************************************************************************************************** +changed: [labvm] + +TASK [Copy binary] ********************************************************************************************************************* +changed: [labvm] + +TASK [Deploy service file] ************************************************************************************************************* +changed: [labvm] + +TASK [Reload systemd] ****************************************************************************************************************** +ok: [labvm] + +TASK [Enable service] ****************************************************************************************************************** +changed: [labvm] + +TASK [Start service] ******************************************************************************************************************* +changed: [labvm] + +RUNNING HANDLER [restart quicknotes] *************************************************************************************************** +changed: [labvm] + +PLAY RECAP ***************************************************************************************************************************** +labvm : ok=9 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +``` +curl -s http://localhost:18080/health +{"notes":4,"status":"ok"} +``` + +``` +ansible-playbook -i ansible/inventory.ini ansible/playbook.yaml + +PLAY [vagrant] ************************************************************************************************************************************************************************** + +TASK [Gathering Facts] ****************************************************************************************************************************************************************** +ok: [labvm] + +TASK [Create user] ********************************************************************************************************************************************************************** +ok: [labvm] + +TASK [Create data directory] ************************************************************************************************************************************************************ +ok: [labvm] + +TASK [Copy binary] ********************************************************************************************************************************************************************** +ok: [labvm] + +TASK [Deploy service file] ************************************************************************************************************************************************************** +ok: [labvm] + +TASK [Reload systemd] ******************************************************************************************************************************************************************* +ok: [labvm] + +TASK [Enable service] ******************************************************************************************************************************************************************* +ok: [labvm] + +TASK [Start service] ******************************************************************************************************************************************************************** +ok: [labvm] + +PLAY RECAP ****************************************************************************************************************************************************************************** +labvm : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +- a. Command just runs a shell command and usually cannot determine the desired state. Dedicated modules are idempotent: they check the current state and only make changes when needed. + +- b. handler runs only if change is detected. It is good, because service won't rerun without need and playbook runs faster + +- c. For this lab: + + - group_vars/ — environment-specific settings (dev, staging, prod). + - Role defaults/ — sensible default values that can be overridden. + - Playbook vars: — values tightly coupled to this specific playbook. + +This keeps configuration separate from automation logic. + +- d. No. This playbook does not use any ansible_* facts. I can set `gather_facts: false` and it will skips the setup task, reducing SSH traffic and saving roughly a few hundred milliseconds to a couple of seconds per host per run. \ No newline at end of file