From a4af5e86d9503ea030138eed9bc5a2d5cc61d472 Mon Sep 17 00:00:00 2001 From: Timur Usmanov Date: Tue, 24 Feb 2026 19:01:17 +0300 Subject: [PATCH 1/4] Add ansible, finish roles/common --- ansible/ansible.cfg | 11 +++++++++++ ansible/group_vars/all.yml | 0 ansible/inventory/hosts.ini | 2 ++ ansible/playbooks/deploy.yml | 0 ansible/playbooks/provision.yml | 6 ++++++ ansible/playbooks/site.yml | 0 ansible/roles/app_deploy/defaults/main.yml | 0 ansible/roles/app_deploy/handlers/main.yml | 0 ansible/roles/app_deploy/tasks/main.yml | 0 ansible/roles/common/defaults/main.yml | 7 +++++++ ansible/roles/common/tasks/main.yml | 15 +++++++++++++++ ansible/roles/docker/defaults/main.yml | 0 ansible/roles/docker/handlers/main.yml | 0 ansible/roles/docker/tasks/main.yml | 0 14 files changed, 41 insertions(+) create mode 100644 ansible/ansible.cfg create mode 100644 ansible/group_vars/all.yml create mode 100644 ansible/inventory/hosts.ini create mode 100644 ansible/playbooks/deploy.yml create mode 100644 ansible/playbooks/provision.yml create mode 100644 ansible/playbooks/site.yml create mode 100644 ansible/roles/app_deploy/defaults/main.yml create mode 100644 ansible/roles/app_deploy/handlers/main.yml create mode 100644 ansible/roles/app_deploy/tasks/main.yml create mode 100644 ansible/roles/common/defaults/main.yml create mode 100644 ansible/roles/common/tasks/main.yml create mode 100644 ansible/roles/docker/defaults/main.yml create mode 100644 ansible/roles/docker/handlers/main.yml create mode 100644 ansible/roles/docker/tasks/main.yml diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000000..06c1114147 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,11 @@ +[defaults] +inventory = inventory/hosts.ini +roles_path = roles +host_key_checking = False +remote_user = vboxuser +retry_files_enabled = False + +[privilege_escalation] +become = True +become_method = sudo +become_user = root diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/inventory/hosts.ini b/ansible/inventory/hosts.ini new file mode 100644 index 0000000000..918c0757ff --- /dev/null +++ b/ansible/inventory/hosts.ini @@ -0,0 +1,2 @@ +[webservers] +devops-vm ansible_host=127.0.0.1 ansible_port=10022 ansible_user=vboxuser diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/playbooks/provision.yml b/ansible/playbooks/provision.yml new file mode 100644 index 0000000000..da481312ef --- /dev/null +++ b/ansible/playbooks/provision.yml @@ -0,0 +1,6 @@ +- name: Provision web servers + hosts: webservers + become: yes + + roles: + - common diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/app_deploy/defaults/main.yml b/ansible/roles/app_deploy/defaults/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/app_deploy/handlers/main.yml b/ansible/roles/app_deploy/handlers/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/app_deploy/tasks/main.yml b/ansible/roles/app_deploy/tasks/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml new file mode 100644 index 0000000000..2282a109a1 --- /dev/null +++ b/ansible/roles/common/defaults/main.yml @@ -0,0 +1,7 @@ +--- +common_packages: + - python3-pip + - curl + - git + - vim + - htop diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml new file mode 100644 index 0000000000..493e3d0be3 --- /dev/null +++ b/ansible/roles/common/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 3600 + +- name: Install common packages + apt: + name: "{{ common_packages }}" + state: present + +- name: Set timezone to UTC + community.general.timezone: + name: Etc/UTC + hwclock: UTC diff --git a/ansible/roles/docker/defaults/main.yml b/ansible/roles/docker/defaults/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/docker/handlers/main.yml b/ansible/roles/docker/handlers/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml new file mode 100644 index 0000000000..e69de29bb2 From 968c0f560d7435501afc4231d6012cf9f5f24828 Mon Sep 17 00:00:00 2001 From: Timur Usmanov Date: Wed, 25 Feb 2026 17:34:32 +0300 Subject: [PATCH 2/4] Install docker on vm --- ansible/playbooks/provision.yml | 1 + ansible/roles/common/defaults/main.yml | 1 + ansible/roles/docker/defaults/main.yml | 2 ++ ansible/roles/docker/handlers/main.yml | 8 ++++++++ ansible/roles/docker/tasks/main.yml | 27 ++++++++++++++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/ansible/playbooks/provision.yml b/ansible/playbooks/provision.yml index da481312ef..1e88a7e3ca 100644 --- a/ansible/playbooks/provision.yml +++ b/ansible/playbooks/provision.yml @@ -4,3 +4,4 @@ roles: - common + - docker diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml index 2282a109a1..16b22d978b 100644 --- a/ansible/roles/common/defaults/main.yml +++ b/ansible/roles/common/defaults/main.yml @@ -5,3 +5,4 @@ common_packages: - git - vim - htop + - gpg diff --git a/ansible/roles/docker/defaults/main.yml b/ansible/roles/docker/defaults/main.yml index e69de29bb2..51c637c764 100644 --- a/ansible/roles/docker/defaults/main.yml +++ b/ansible/roles/docker/defaults/main.yml @@ -0,0 +1,2 @@ +--- +ubuntu_user: vboxuser diff --git a/ansible/roles/docker/handlers/main.yml b/ansible/roles/docker/handlers/main.yml index e69de29bb2..3471bdb63d 100644 --- a/ansible/roles/docker/handlers/main.yml +++ b/ansible/roles/docker/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: restart docker + service: + name: docker + state: restarted +- name: Update apt cache + ansible.builtin.apt: + update_cache: yes diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml index e69de29bb2..1190069cac 100644 --- a/ansible/roles/docker/tasks/main.yml +++ b/ansible/roles/docker/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Add Docker repo + ansible.builtin.deb822_repository: + check_date: true + check_valid_until: true + name: docker + uris: https://download.docker.com/linux/ubuntu + suites: '{{ ansible_facts["distribution_release"] }}' + components: stable + signed_by: https://download.docker.com/linux/ubuntu/gpg + notify: Update apt cache + +- name: Install Docker + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - python3-docker + state: present + +- name: Add ubuntu user to docker group + ansible.builtin.user: + name: '{{ ubuntu_user }}' + groups: docker + append: yes + notify: restart docker From d9e7b936c8c1b591ebc77c7cdb236b11fc07c0fa Mon Sep 17 00:00:00 2001 From: Timur Usmanov Date: Wed, 25 Feb 2026 19:33:27 +0300 Subject: [PATCH 3/4] Finish task 3 cleanly, start task4 --- ansible/docs/LAB05.md | 210 +++++++++++++++++++++ ansible/group_vars/all.yml | 18 ++ ansible/playbooks/deploy.yml | 7 + ansible/roles/app_deploy/defaults/main.yml | 4 + ansible/roles/app_deploy/handlers/main.yml | 10 + ansible/roles/app_deploy/tasks/main.yml | 38 ++++ ansible/roles/docker/handlers/main.yml | 3 - ansible/roles/docker/tasks/main.yml | 14 +- 8 files changed, 298 insertions(+), 6 deletions(-) create mode 100644 ansible/docs/LAB05.md diff --git a/ansible/docs/LAB05.md b/ansible/docs/LAB05.md new file mode 100644 index 0000000000..d52854f683 --- /dev/null +++ b/ansible/docs/LAB05.md @@ -0,0 +1,210 @@ +# Task 2 + +### "First" run +(Not really the first, I tore the environment down manually). + +```text +timur@timur-ficus:~/proj/DevOps-Core-Course/ansible$ ansible-playbook playbooks/provision.yml + +PLAY [Provision web servers] ******************************************************************************************************************* + +TASK [Gathering Facts] ************************************************************************************************************************* +[WARNING]: Host 'devops-vm' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information. +ok: [devops-vm] + +TASK [common : Update apt cache] *************************************************************************************************************** +ok: [devops-vm] + +TASK [common : Install common packages] ******************************************************************************************************** +changed: [devops-vm] + +TASK [common : Set timezone to UTC] ************************************************************************************************************ +ok: [devops-vm] + +TASK [docker : Add Docker repo] **************************************************************************************************************** +changed: [devops-vm] + +TASK [docker : update apt cache] *************************************************************************************************************** +changed: [devops-vm] + +TASK [docker : Install Docker] ***************************************************************************************************************** +changed: [devops-vm] + +TASK [docker : Add ubuntu user to docker group] ************************************************************************************************ +ok: [devops-vm] + +RUNNING HANDLER [docker : restart docker] ****************************************************************************************************** +changed: [devops-vm] + +PLAY RECAP ************************************************************************************************************************************* +devops-vm : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +``` + +### The next run + +```text +timur@timur-ficus:~/proj/DevOps-Core-Course/ansible$ ansible-playbook playbooks/provision.yml + +PLAY [Provision web servers] ******************************************************************************************************************* + +TASK [Gathering Facts] ************************************************************************************************************************* +[WARNING]: Host 'devops-vm' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information. +ok: [devops-vm] + +TASK [common : Update apt cache] *************************************************************************************************************** +ok: [devops-vm] + +TASK [common : Install common packages] ******************************************************************************************************** +ok: [devops-vm] + +TASK [common : Set timezone to UTC] ************************************************************************************************************ +ok: [devops-vm] + +TASK [docker : Add Docker repo] **************************************************************************************************************** +ok: [devops-vm] + +TASK [docker : update apt cache] *************************************************************************************************************** +skipping: [devops-vm] + +TASK [docker : Install Docker] ***************************************************************************************************************** +ok: [devops-vm] + +TASK [docker : Add ubuntu user to docker group] ************************************************************************************************ +ok: [devops-vm] + +PLAY RECAP ************************************************************************************************************************************* +devops-vm : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +``` + +After this run, nothing changed. Even `apt update` was skipped because it is triggered by changes in `Add Docker repo`. + +### Analysis: what changed the first time + +Everything related to `apt` and `docker` because the packages were not installed. + +### Why nothing changed the second time + +This is why we need Ansible: it checks that the system is in the desired state before doing anything (providing +idempotency). The system was already in the desired state because Ansible was run just before. + + +# Task 3 + +### Terminal output + +```text +timur@timur-ficus:~/proj/DevOps-Core-Course/ansible$ ansible-playbook playbooks/deploy.yml --ask-vault-pass +Vault password: + +PLAY [Deploy application] ********************************************************************************************************************** + +TASK [Gathering Facts] ************************************************************************************************************************* +[WARNING]: Host 'devops-vm' is using the discovered Python interpreter at '/usr/bin/python3.12', but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information. +ok: [devops-vm] + +TASK [app_deploy : load vault] ***************************************************************************************************************** +ok: [devops-vm] + +TASK [app_deploy : DockerHub Login] ************************************************************************************************************ +changed: [devops-vm] + +TASK [app_deploy : Pull image] ***************************************************************************************************************** +changed: [devops-vm] + +TASK [app_deploy : Stop and remove running container] ****************************************************************************************** +ok: [devops-vm] + +TASK [app_deploy : Run container] ************************************************************************************************************** +changed: [devops-vm] + +TASK [app_deploy : Wait for port] ************************************************************************************************************** +ok: [devops-vm] + +TASK [app_deploy : Healthcheck] **************************************************************************************************************** +ok: [devops-vm] + +PLAY RECAP ************************************************************************************************************************************* +devops-vm : ok=8 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +### `docker ps` output + +```text +vboxuser@devops-vm:~$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +0cdb6ce0a0f5 timurusmanov/devops-infoservice:latest "gunicorn -b 0.0.0.0…" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp devops-infoservice +``` + +### Healthcheck + +Healthcheck passed: Ansible printed `ok`. + +# Task 4 + +## Architecture overview + +## 1. Architecture Overview +### Ansible version used +```text +ansible [core 2.20.2] + config file = None + configured module search path = ['/home/timur/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] + ansible python module location = /usr/lib/python3.14/site-packages/ansible + ansible collection location = /home/timur/.ansible/collections:/usr/share/ansible/collections + executable location = /usr/bin/ansible + python version = 3.14.3 (main, Feb 13 2026, 15:31:44) [GCC 15.2.1 20260209] (/usr/bin/python) + jinja version = 3.1.6 + pyyaml version = 6.0.3 (with libyaml v0.2.5) +``` + +### Target VM OS and version +Ubuntu 24.04 LTS + +### Role structure diagram or explanation +3 roles: +1. `common` for setting up necessary system software and configuration +2. `docker` for installing Docker +3. `app_deploy` for pulling and running the application. + +### Why roles instead of monolithic playbooks? + + +## 2. Roles Documentation + +For each role (common, docker, app_deploy): +### Purpose: What does this role do? +### Variables: Key variables and defaults +### Handlers: What handlers are defined? +### Dependencies: Does it depend on other roles? + +## 3. Idempotency Demonstration +### Terminal output from FIRST provision.yml run +### Terminal output from SECOND provision.yml run +### Analysis: What changed first time? What didn't change second time? +### Explanation: What makes your roles idempotent? + +## 4. Ansible Vault Usage +### How you store credentials securely +### Vault password management strategy +### Example of encrypted file (show it's encrypted!) +### Why Ansible Vault is important + +## 5. Deployment Verification +### Terminal output from deploy.yml run +### Container status: `docker ps` output +### Health check verification: `curl` outputs +### Handler execution (if any) + +## 6. Key Decisions +### Why use roles instead of plain playbooks? +### How do roles improve reusability? +### What makes a task idempotent? +### How do handlers improve efficiency? +### Why is Ansible Vault necessary? + +## 7. Challenges (Optional) +### Issues encountered and solutions +### Keep it brief - bullet points OK + + diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index e69de29bb2..6f28a0f3e1 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -0,0 +1,18 @@ +$ANSIBLE_VAULT;1.1;AES256 +35666430376135623761373732656538383137656466336266366239303435363364353462323136 +3765323833663966376435333161643165363562656364390a663564353162643738303335646261 +32613533636439346534623965376632363761656532666462613536613235633965626138353866 +3636316635316430320a633562383464383065626561333064633661616364663534653531636533 +31326237313365373739663031353664613036656230323239613165663932656364326630353135 +35306339626335616238623561353030323063363531383331646464323066626230616336616436 +39386238633763616530396361336563663366383831643431663562316331323834663336613932 +61643833383139396265353330643237356335343266363261333765363735633731346565646437 +65653262333733623732623962326434613334383131393461333533356136303836356264383461 +33303533653533633038383038643330393763356334353465373464373166366665346366643432 +32646233323362653635313966633636633139393165353339653535666136613039666336646161 +34366137623666333632386231643238366265373064346564316637393935643063313831343861 +36303064383063363630386566393539333664386665386162376238313134666538303261363332 +34303537656335376338363533646630653862656164313939366263663662383136373932663665 +30393463643534663434663538663934303666316534333932346164343866636161383763666139 +38393365653832383536613535666534383634353536353233653537653762626133376361613065 +36383937376137623539626363363866336566643235393565633463326665396664 diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml index e69de29bb2..56850a7585 100644 --- a/ansible/playbooks/deploy.yml +++ b/ansible/playbooks/deploy.yml @@ -0,0 +1,7 @@ +--- +- name: Deploy application + hosts: webservers + become: yes + + roles: + - app_deploy diff --git a/ansible/roles/app_deploy/defaults/main.yml b/ansible/roles/app_deploy/defaults/main.yml index e69de29bb2..28b2e06e76 100644 --- a/ansible/roles/app_deploy/defaults/main.yml +++ b/ansible/roles/app_deploy/defaults/main.yml @@ -0,0 +1,4 @@ +--- +default_port: 5000 +default_restart_policy: unless-stopped +default_environment_variables: '{}' diff --git a/ansible/roles/app_deploy/handlers/main.yml b/ansible/roles/app_deploy/handlers/main.yml index e69de29bb2..02471f6ea9 100644 --- a/ansible/roles/app_deploy/handlers/main.yml +++ b/ansible/roles/app_deploy/handlers/main.yml @@ -0,0 +1,10 @@ +--- +- name: restart container + community.docker.docker_container: + name: '{{ app_container_name }}' + image: '{{ docker_image }}:{{ docker_image_tag }}' + published_ports: + - '{{ app_port }}:{{ default_port }}' + env: "{{ default_environment_variables }}" + restart_policy: '{{ default_restart_policy }}' + state: restarted diff --git a/ansible/roles/app_deploy/tasks/main.yml b/ansible/roles/app_deploy/tasks/main.yml index e69de29bb2..d43fa6ee63 100644 --- a/ansible/roles/app_deploy/tasks/main.yml +++ b/ansible/roles/app_deploy/tasks/main.yml @@ -0,0 +1,38 @@ +--- +- name: load vault + ansible.builtin.include_vars: '../group_vars/all.yml' + +- name: DockerHub Login + community.docker.docker_login: + username: '{{ dockerhub_username }}' + password: '{{ dockerhub_password }}' + no_log: true + +- name: Pull image + community.docker.docker_image_pull: + name: '{{ docker_image }}' + tag: '{{ docker_image_tag }}' + +- name: Stop and remove running container + community.docker.docker_container: + name: '{{ app_container_name }}' + state: absent + +- name: Run container + community.docker.docker_container: + name: '{{ app_container_name }}' + image: '{{ docker_image }}:{{ docker_image_tag }}' + published_ports: + - '{{ app_port }}:{{ default_port }}' + env: "{{ default_environment_variables }}" + restart_policy: '{{ default_restart_policy }}' + state: started + +- name: Wait for port + ansible.builtin.wait_for: + port: '{{ app_port }}' + +- name: Healthcheck + ansible.builtin.uri: + url: 'http://localhost:{{ app_port }}/health' + status_code: 200 diff --git a/ansible/roles/docker/handlers/main.yml b/ansible/roles/docker/handlers/main.yml index 3471bdb63d..3627303e6b 100644 --- a/ansible/roles/docker/handlers/main.yml +++ b/ansible/roles/docker/handlers/main.yml @@ -3,6 +3,3 @@ service: name: docker state: restarted -- name: Update apt cache - ansible.builtin.apt: - update_cache: yes diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml index 1190069cac..e155cdb79a 100644 --- a/ansible/roles/docker/tasks/main.yml +++ b/ansible/roles/docker/tasks/main.yml @@ -8,7 +8,12 @@ suites: '{{ ansible_facts["distribution_release"] }}' components: stable signed_by: https://download.docker.com/linux/ubuntu/gpg - notify: Update apt cache + register: repo_added + +- name: update apt cache + when: repo_added is changed + ansible.builtin.apt: + update_cache: true - name: Install Docker ansible.builtin.apt: @@ -18,10 +23,13 @@ - containerd.io - python3-docker state: present + notify: + - restart docker - name: Add ubuntu user to docker group ansible.builtin.user: name: '{{ ubuntu_user }}' groups: docker - append: yes - notify: restart docker + append: true + notify: + - restart docker From 9aa449df701375e21bb2df7a466814f5b4783ab1 Mon Sep 17 00:00:00 2001 From: Timur Usmanov Date: Thu, 26 Feb 2026 12:15:47 +0300 Subject: [PATCH 4/4] Finish documentation for lab5 --- ansible/docs/LAB05.md | 75 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/ansible/docs/LAB05.md b/ansible/docs/LAB05.md index d52854f683..3a7e157729 100644 --- a/ansible/docs/LAB05.md +++ b/ansible/docs/LAB05.md @@ -168,43 +168,94 @@ Ubuntu 24.04 LTS 3. `app_deploy` for pulling and running the application. ### Why roles instead of monolithic playbooks? - +Roles act as reusable and invokable playbooks. Increases modularity. ## 2. Roles Documentation -For each role (common, docker, app_deploy): -### Purpose: What does this role do? -### Variables: Key variables and defaults -### Handlers: What handlers are defined? -### Dependencies: Does it depend on other roles? +### common +- **Purpose**: Configure the system and set up common software. +- **Variables**: `common_packages` contains a list of packages to install +- **Handlers**: none +- **Dependencies**: no other roles needed + +### docker +- **Purpose**: Install the latest Docker version and configure the system +- **Variables**: `ubuntu_user` is the user to add to the `docker` group, in my case `vboxuser` +- **Handlers**: `restart docker` restarts the daemon +- **Dependencies**: no other roles required + +### app\_deploy +- **Purpose**: Pull and run the app +- **Variables in the role**: + - `default_port: 5000` is the listened port inside the container + - `default_restart_policy: unless-stopped` + - `default_environment_variables: '{}'` is the env. variables passed to the app +- **Variables in the vault** `group_vars/all.yml`: + - `dockerhub_username` is my username on DockerHub + - `dockerhub_password` is my PAT (by principle of least privilege, it grants read-only access only to public images) + - `app_name: devops-infoservice` is the container and image name (without my username) + - `docker_image: "{{ dockerhub_username }}/{{ app_name }}"` is the full image name on DockerHub + - `docker_image_tag: latest`, as required by the lab + - `app_port: 5000` is the port exposed on the VM + - `app_container_name: "{{ app_name }}"` is the container name +- **Handlers**: `restart container` restarts the container +- **Dependencies**: requires the `docker` role to run before it ## 3. Idempotency Demonstration ### Terminal output from FIRST provision.yml run +See Task 2. ### Terminal output from SECOND provision.yml run +See Task 2. ### Analysis: What changed first time? What didn't change second time? +See Task 2. ### Explanation: What makes your roles idempotent? +I took care to specify the desired state of the machine instead of imperatively running the commands. +This way, Ansible can determine what it actually needs to run, and, of course, on the second run there will be nothing +to do. ## 4. Ansible Vault Usage ### How you store credentials securely +I store them in the `group_vars/all.yml` vault (encrypted with a password). ### Vault password management strategy +The password is stored securely inside my head ;) +So unless you apply a soldering iron directly to the head, you will not extract it. ### Example of encrypted file (show it's encrypted!) +For example: +```sh +head -n 2 group_vars/all.yml +``` +Yields: +```text +$ANSIBLE_VAULT;1.1;AES256 +35666430376135623761373732656538383137656466336266366239303435363364353462323136 +``` +So this file is an unreadable Ansible vault that uses AES256 symmetric encryption. + ### Why Ansible Vault is important +Since I have to push the variable file to GitHub, I have to encrypt it so that nobody can see the credentials. ## 5. Deployment Verification -### Terminal output from deploy.yml run -### Container status: `docker ps` output -### Health check verification: `curl` outputs -### Handler execution (if any) +See Task 3. ## 6. Key Decisions ### Why use roles instead of plain playbooks? +See **Why roles instead of monolithic playbooks?** in **Architecture overview**. ### How do roles improve reusability? +When done correctly, a role acts like a module that does one specific task and does it well. +This allows engineers to paste the same role into new projects. + ### What makes a task idempotent? +When the task specifies what the system should be like by the end of the task, it can be re-run multiple times, but +runs after the first one will see that the system is already in the desired state and do nothing. + ### How do handlers improve efficiency? +Handlers only execute when a task has changed the system state, not always. That reduces overhead. + ### Why is Ansible Vault necessary? +See **Why Ansible Vault is important** in **Ansible Vault Usage**. ## 7. Challenges (Optional) ### Issues encountered and solutions -### Keep it brief - bullet points OK - +- Running `apt update` only if the docker repo has been newly added. Tried handlers, but it turned out they only run + after all tasks have run (which really should have been clarified better in the lecture, IMHO).