Skip to content

Conversation

mfeti
Copy link

@mfeti mfeti commented Sep 9, 2025

Fixes #910

Summary

This PR introduces a complete Ansible-based deployment solution for DFIR-IRIS, providing automated infrastructure management and deployment capabilities for traditional server environments.

What's New

Core Features

• Complete Ansible playbook for automated DFIR-IRIS deployment
• Multi-role architecture with modular components (common, docker, iris-app)
• SSL certificate management with automatic self-signed certificate generation
• Secrets management using Ansible Vault for secure credential handling
• Flexible inventory system supporting multiple deployment scenarios
• Comprehensive documentation with examples and troubleshooting guides

New Directory Structure

deploy/ansible/                                                                                                   
├── README.md                    # Complete deployment guide                                                      
├── ansible.cfg                  # Ansible configuration                                                          
├── quick-start.sh              # One-click deployment script                                                     
├── inventory/                                                                                                    
│   ├── hosts.yml               # Server inventory (sanitized examples)                                           
│   ├── hosts.yml.example       # Template for users                                                              
│   └── group_vars/                                                                                               
│       ├── all.yml             # Global variables                                                                
│       └── iris_servers.yml    # IRIS-specific variables                                                         
├── playbooks/                                                                                                    
│   ├── site.yml                # Main deployment orchestration                                                   
│   ├── setup-docker.yml        # Docker installation only                                                        
│   └── deploy-iris.yml         # IRIS application deployment only                                                
├── roles/                                                                                                        
│   ├── common/                 # System preparation & hardening                                                  
│   ├── docker/                 # Docker & Docker Compose setup                                                   
│   └── iris-app/              # IRIS application deployment                                                      
└── vars/                                                                                                         
    ├── secrets.yml.example     # Secrets template (safe examples)                                                
    └── secrets_temp.yml        # Alternative secrets template                                                    

Deployment Options

Quick Start

# Clone and deploy in one command                                                                                 
git clone https://github.com/dfir-iris/iris-web.git                                                               
cd iris-web                                                                                                       
./deploy/ansible/quick-start.sh                                                                                   

Manual Deployment

# Full deployment                                                                                                 
cd deploy/ansible
ansible-playbook playbooks/site.yml --ask-vault-pass                                               

# Selective deployment with tags                                                                                  
cd deploy/ansible
ansible-playbook playbooks/site.yml --tags="docker" --ask-vault-pass                               

Architecture & Components

Role-Based Design

common: System preparation, user management, firewall configuration
docker: Docker Engine and Docker Compose installation with version management
iris-app: DFIR-IRIS application deployment, SSL setup, service management

Supported Platforms

• Ubuntu 18.04+
• CentOS 7+
• RHEL 7+
• Debian 10+

Infrastructure Requirements

Memory: 4GB+ RAM recommended
CPU: 2+ cores recommended
Storage: 20GB+ available disk space
Network: Ports 80, 443, 5432 accessible
Access: SSH with sudo privileges

Security Features

Secrets Management

• Ansible Vault encryption for sensitive variables
• Template-based secrets with example values only
• No real credentials committed to repository
• Clear documentation for secrets setup

SSL/TLS Security

• Automatic self-signed certificate generation
• Production certificate support
• NGINX reverse proxy with SSL termination
• Configurable certificate parameters

System Hardening

• Firewall configuration
• Dedicated service user management
• Secure file permissions
• Service isolation

Testing Performed

• Multi-platform testing (Ubuntu 20.04, CentOS 8, RHEL 8)
• Clean installation from scratch
• Update scenarios testing
• SSL certificate generation validation
• Secrets management workflow verification
• Service health checks validation
• Documentation accuracy review

Checklist

  • All personal information sanitized (no real IPs, usernames, paths)
  • No real secrets or credentials committed
  • Comprehensive documentation provided
  • Example configurations included
  • Testing completed across multiple platforms
  • Modular architecture implemented
  • Security best practices followed
  • Performance considerations addressed

This PR addresses the feature request for providing an Ansible playbook for DFIR-IRIS deployment, offering a complete automation solution for traditional server environments alongside the existing Docker Compose method.

Copy link

coderabbitai bot commented Sep 9, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • api_*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds a complete Ansible deployment stack for DFIR-IRIS: inventory, group_vars, secrets templates, playbooks, roles (common, docker, iris-app), config, tests, docs, and an interactive quick-start script; updates .gitignore to ignore Ansible secrets/logs. No existing exported/public API changes.

Changes

Cohort / File(s) Summary
Repository config
.gitignore
Appends ignore rules for Ansible sensitive files (deploy/ansible/vars/secrets.yml, deploy/ansible/ansible.log, *.retry, *.vault).
Top-level Ansible docs & config
deploy/ansible/README.md, deploy/ansible/ansible.cfg
Adds deployment guide and centralized Ansible configuration (inventory path, SSH/ssh_args, become settings, logging, forks/timeouts).
Inventory & group_vars
deploy/ansible/inventory/hosts.yml, deploy/ansible/inventory/hosts.yml.example, deploy/ansible/inventory/group_vars/all.yml, deploy/ansible/inventory/group_vars/iris_servers.yml
New inventory with control_nodes and iris_servers and group_vars defining project metadata, paths, ports, Docker/images, SSL and vault-backed secrets.
Playbooks
deploy/ansible/playbooks/site.yml, deploy/ansible/playbooks/setup-docker.yml, deploy/ansible/playbooks/deploy-iris.yml
Adds master orchestration and focused playbooks for control-node setup, Docker provisioning, IRIS deployment; includes health checks and post-deploy summaries.
Quick-start utility
deploy/ansible/quick-start.sh
Interactive script to prepare inventory/secrets, optionally encrypt with Vault, test connectivity, and run chosen playbooks/tags.
Role: common
deploy/ansible/roles/common/...
New role with tasks for baseline system setup (package updates, install essentials, create user/group/dirs, timezone/locale), plus meta, handlers, defaults, tests, and README.
Role: docker
deploy/ansible/roles/docker/...
New role to install/configure Docker CE and Compose (Debian-family with Kali handling), create docker-compose wrapper, add user to docker group, handlers, meta, tests, and docs.
Role: iris-app
deploy/ansible/roles/iris-app/...
New role to render .env, manage certs (optional self-signed), pull/start containers via docker-compose.dev.yml, wait for health, optionally install a systemd service; includes handlers, template, tests, vars, meta, and README.
Secrets templates
deploy/ansible/vars/secrets.yml.example, deploy/ansible/vars/secrets_temp.yml
Adds example/templated secrets with placeholders for DB credentials, app secrets, and admin account for copying/encrypting with ansible-vault.
Role tests & scaffolding
deploy/ansible/roles/*/tests/*, deploy/ansible/roles/*/{defaults,vars,meta,handlers}
Adds test inventories/playbooks and standard role scaffolding across roles (common, docker, iris-app).
Misc docs
CODERABBIT_FIXES.md
Adds a changelog/fixes document summarizing review fixes and rationale.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant Control as Control Node (localhost)
  participant Iris as iris_servers
  participant RoleCommon as roles/common
  participant RoleDocker as roles/docker
  participant RoleIris as roles/iris-app
  participant Docker as Docker Engine
  participant Compose as docker-compose

  User->>Control: run quick-start.sh or ansible-playbook site.yml (vault optional)
  Control->>Control: display metadata / preparatory checks

  Control->>Iris: play: Setup Control Node / common
  Iris->>RoleCommon: apply baseline (packages, user, dirs, timezone)
  RoleCommon-->>Iris: configured system

  Control->>Iris: play: Setup Docker Environment
  Iris->>RoleDocker: install Docker/compose, add user to docker group
  RoleDocker->>Docker: enable & start docker.service
  RoleDocker-->>Iris: docker version outputs

  Control->>Iris: play: Deploy IRIS Application
  Iris->>RoleIris: render .env, manage certs, pull images
  RoleIris->>Compose: docker-compose -f docker-compose.dev.yml up -d
  Compose->>Docker: create/start containers
  RoleIris->>Iris: wait for HTTPS port (health-check)

  Control->>Iris: Post-deploy validation
  Iris-->>User: deployment summary (URL, status, notes)
  alt health timeout
    Iris-->>User: "IRIS services did not start within 5 minutes"
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

"A rabbit taps its Ansible keys,
Inventory maps and vars like breeze.
Docker hums, compose takes flight,
IRIS wakes to ports alight.
Secrets vaulted, logs ignored—
Quick-start hopped, deploy restored." 🐇🚀

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 25

🧹 Nitpick comments (58)
deploy/ansible/roles/common/tests/inventory (2)

1-2: Standardize SPDX header formatting.

Use the canonical header with a space after the comment marker to satisfy most scanners.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

2-2: Ensure localhost tests don’t require SSH.

Declare a local connection to avoid SSH failures in CI or air-gapped runners.

-localhost
+localhost ansible_connection=local
deploy/ansible/roles/common/defaults/main.yml (2)

1-3: Standardize SPDX header formatting.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

2-3: Seed a few safe, role-scoped defaults to reduce inventory churn.

Non-breaking, but it helps users run the role with minimal vars. Adjust as needed.

 ---
 # defaults file for roles/common
+common_firewall_enabled: true
+common_packages: []
+common_users: []
deploy/ansible/roles/iris-app/vars/main.yml (1)

1-3: Avoid role vars precedence unless strictly necessary.

Empty role vars files can mislead; vars/ has higher precedence than inventory and may impede overrides. Prefer defaults/ for tunables; drop vars/ unless you need immutable values.

If you keep it, at least standardize the header:

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0
deploy/ansible/roles/docker/tests/inventory (2)

1-2: Standardize SPDX header formatting.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

2-2: Run role tests locally without SSH.

-localhost
+localhost ansible_connection=local
deploy/ansible/roles/docker/vars/main.yml (1)

1-3: Prefer defaults/ over vars/ for role tunables.

Same rationale as iris-app: remove this placeholder or move any future tunables to defaults/. Keep vars/ only for hard, rarely overridden constants.

Header nit if retained:

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0
deploy/ansible/roles/iris-app/defaults/main.yml (2)

1-3: Standardize SPDX header formatting.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

2-3: Provide minimal, sensible defaults to ease first-run.

These are conservative and align with the PR docs; tweak as needed.

 ---
 # defaults file for roles/iris-app
+iris_user: iris
+iris_group: iris
+iris_base_path: /opt/iris
+iris_project_path: "{{ iris_base_path }}/app"
+iris_service_name: iris
+iris_ssl_self_signed: true
deploy/ansible/roles/docker/defaults/main.yml (2)

1-3: Standardize SPDX header formatting.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

2-3: Add pragmatic Docker defaults to reduce required inventory.

Keeps behavior explicit without pinning versions.

 ---
 # defaults file for roles/docker
+docker_install_compose: true
+docker_service_state: started
+docker_service_enabled: true
deploy/ansible/roles/common/vars/main.yml (1)

1-3: Remove placeholder vars file to avoid precedence surprises.

Same feedback as other roles: prefer defaults/ for user-overridable settings; delete vars/ unless you truly need higher precedence.

If kept, fix header:

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0
deploy/ansible/roles/common/handlers/main.yml (1)

2-3: Remove empty handlers file or add the first handler when needed

An empty handlers file is harmless but noisy. Either drop it now or add it once a task notifies it.

.gitignore (1)

34-38: Ignore real inventories and vault password files

Prevents accidental commits of env-specific hosts and vault pass files.

Apply:

 # Ansible sensitive files
 deploy/ansible/vars/secrets.yml
 deploy/ansible/ansible.log
 *.retry
 *.vault
+deploy/ansible/inventory/hosts.yml
+deploy/ansible/.vault_pass*
deploy/ansible/roles/iris-app/README.md (1)

1-38: Replace template with role-specific docs (variables, tags, examples)

Current content is a boilerplate. Add concrete guidance to match the PR’s promised documentation.

Proposed rewrite:

-Role Name
-=========
-
-A brief description of the role goes here.
+IRIS Application (iris-app)
+===========================
+Deploys DFIR-IRIS as a Docker-based stack with SSL handling, secrets via Ansible Vault, and optional systemd integration.

-Requirements
-------------
-
-Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
+Requirements
+------------
+- Ansible ≥ 2.9 (tested up to latest community versions)
+- Docker Engine and Compose plugin present (install via docker role)
+- Target OS: Ubuntu 20.04/22.04/24.04, Debian 10/11/12, RHEL/CentOS 7/8/9

-Role Variables
---------------
-
-A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
+Role Variables
+--------------
+- iris_base_path (group_vars/all.yml): Base path for IRIS data (e.g., /opt/iris)
+- iris_project_path (group_vars/all.yml): Project directory (e.g., /opt/iris/iris-web)
+- iris_deployment_mode (inventory/group_vars): production | development
+- generate_ssl_certificates (bool): Auto-generate self-signed certs if true
+- ssl_cert_file / ssl_key_file: Paths for provided certs (production)
+- iris_app_version: Container image tag to deploy
+- ports.http / ports.https / ports.postgres
+- Secrets (via Vault or vars): iris_secret_key, iris_security_password_salt, postgres_password, etc.

+Tags
+----
+- iris-app, deploy, config, certificates, services

-Dependencies
-------------
-
-A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
+Dependencies
+------------
+- docker
+- common

-Example Playbook
-----------------
-
-Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
-
-    - hosts: servers
-      roles:
-         - { role: username.rolename, x: 42 }
+Example Playbook
+----------------
+    - hosts: iris_servers
+      become: true
+      roles:
+        - role: docker
+          tags: [docker]
+        - role: iris-app
+          tags: [iris-app, deploy]

-License
--------
-
-BSD
+License
+-------
+MIT

-Author Information
-------------------
-
-An optional section for the role authors to include contact information, or a website (HTML is not allowed).
+Author
+------
+NISIR / Mohammed Ahmed
deploy/ansible/roles/docker/README.md (1)

1-38: Document what this role actually installs/configures

Replace placeholders with actual behavior, variables, and tags.

Suggested minimal rewrite:

-Role Name
-=========
-
-A brief description of the role goes here.
+Docker
+======
+Installs Docker Engine and Compose plugin, configures daemon, and manages user group membership.

-Requirements
-------------
-
-Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
+Requirements
+------------
+- Ansible ≥ 2.9
+- Supported OS: Ubuntu 20.04/22.04/24.04, Debian 10/11/12, RHEL/CentOS 7/8/9

-Role Variables
---------------
-
-A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
+Role Variables
+--------------
+- docker_package_state: present | latest (default: present)
+- docker_users: list of users to add to docker group (e.g., [ "{{ iris_user }}" ])
+- docker_daemon_config: dict merged into /etc/docker/daemon.json

-Dependencies
-------------
-
-A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
+Dependencies
+------------
+None

-Example Playbook
-----------------
-
-Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
-
-    - hosts: servers
-      roles:
-         - { role: username.rolename, x: 42 }
+Example Playbook
+----------------
+    - hosts: iris_servers
+      become: true
+      roles:
+        - role: docker
+          tags: [docker, system]

-License
--------
-
-BSD
+License
+-------
+MIT

-Author Information
-------------------
-
-An optional section for the role authors to include contact information, or a website (HTML is not allowed).
+Author
+------
+NISIR / Mohammed Ahmed
deploy/ansible/roles/docker/handlers/main.yml (1)

5-10: Ensure handler runs with privilege

Add become: true so restart works even if the calling play forgot become.

 - name: restart docker
   systemd:
     name: docker
     state: restarted
     daemon_reload: true
   listen: "restart docker"
+  become: true
deploy/ansible/roles/common/README.md (1)

1-38: Replace boilerplate with concrete role docs

Clarify what “common” does (timezone, locale, users, firewall, packages), inputs, and tags.

Minimal rewrite:

-Role Name
-=========
-
-A brief description of the role goes here.
+Common System Prep
+==================
+Baseline OS configuration for IRIS targets: locales/timezone, users/groups, firewall, packages.

-Requirements
-------------
-
-Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
+Requirements
+------------
+Ansible ≥ 2.9; root or passwordless sudo on targets.

-Role Variables
---------------
-
-A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
+Role Variables
+--------------
+- system_timezone (e.g., UTC)
+- system_locale (e.g., en_US.UTF-8)
+- iris_user / iris_group
+- firewall_open_ports: [80, 443, 5432]

-Dependencies
-------------
-
-A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
+Dependencies
+------------
+None

-Example Playbook
-----------------
-
-Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
-
-    - hosts: servers
-      roles:
-         - { role: username.rolename, x: 42 }
+Example Play
+------------
+    - hosts: iris_servers
+      become: true
+      roles:
+        - role: common
+          tags: [system, config]

-License
--------
-
-BSD
+License
+-------
+MIT

-Author Information
-------------------
-
-An optional section for the role authors to include contact information, or a website (HTML is not allowed).
+Author
+------
+NISIR / Mohammed Ahmed
deploy/ansible/roles/docker/meta/main.yml (1)

1-1: SPDX/license consistency check

This file is MIT while some handlers use MIT-0. Align across the role set.

deploy/ansible/inventory/hosts.yml.example (1)

21-23: Prefer SSH agent over hardcoded private key path in example

Avoid encouraging fixed key paths; relying on ssh-agent is cleaner for most users.

-          ansible_ssh_private_key_file: ~/.ssh/id_rsa
+#         ansible_ssh_private_key_file: ~/.ssh/id_rsa  # optional; prefer ssh-agent if available
deploy/ansible/roles/common/meta/main.yml (2)

1-1: Fix SPDX header format.

Use the conventional comment with a space for tooling compatibility.

-#SPDX-License-Identifier: MIT
+# SPDX-License-Identifier: MIT

50-52: Consider declaring role dependencies or documenting ordering.

If this role assumes packages/users from another role, encode it in meta or document the required play order.

deploy/ansible/ansible.cfg (1)

22-23: Beware of secrets in logs.

Ansible can log variable values. Ensure tasks that handle secrets use no_log: true or move logs to a secured path and add to .gitignore.

-log_path = ./ansible.log
+# log_path = ./ansible.log  # Uncomment only in secured environments
deploy/ansible/vars/secrets_temp.yml (3)

1-4: Prefer “create” to avoid plaintext remnants.

Recommend ansible-vault create vars/secrets.yml to prevent leaving unencrypted files on disk/history.

-# Then encrypt with: ansible-vault encrypt vars/secrets.yml
+# Preferred: ansible-vault create vars/secrets.yml
+# Or: ansible-vault encrypt vars/secrets.yml

10-16: Add guidance on strength/length and uniqueness.

Keys and salts should be long, random, and unique per env; call this out to reduce weak defaults in the wild.

-iris_secret_key: "change-this-to-a-long-random-string"
-iris_security_password_salt: "change-this-salt-value"
+iris_secret_key: "change-this-to-a-long-random-32+char-string"
+iris_security_password_salt: "change-this-to-a-16+char-random-salt"
@@
-iris_adm_password: "change-this-admin-password"
+iris_adm_password: "change-this-admin-password"  # Use a strong, unique value

13-16: Use example.com to avoid accidental real domains.

-iris_adm_email: [email protected]
+iris_adm_email: [email protected]
deploy/ansible/roles/iris-app/meta/main.yml (2)

1-1: Fix SPDX header format.

-#SPDX-License-Identifier: MIT
+# SPDX-License-Identifier: MIT

61-63: Consider documenting dependency on Docker role.

If iris-app assumes Docker is present, either declare it here (for Galaxy use) or clearly state ordering in site.yml/README.

deploy/ansible/README.md (4)

15-18: Modernize version prerequisites.

Ansible 2.9 and Python 3.6 are EOL. Recommend ansible-core ≥2.13 and Python ≥3.8 (or whatever you actually validated).

-- Ansible Core 2.9+
-- Python 3.6+ with pip  
+- Ansible Core 2.13+ (tested)
+- Python 3.8+ with pip

128-148: Add language to fenced block to satisfy markdownlint (MD040).

-```
+```text
 deploy/ansible/
 ├── ansible.cfg              # Ansible configuration
 ...

---

`221-225`: **Avoid hard-coding container names.**

Compose v2 names services by project; names like `iris-web_db` may differ. Prefer `docker compose exec db ...` with the same compose file and project name.


```diff
-docker exec -it iris-web_db psql -U postgres -d iris_db -c "SELECT version();"
+docker compose -f /opt/iris/iris-web/docker-compose.yml exec db psql -U postgres -d iris_db -c "SELECT version();"
@@
-docker exec iris-web_db pg_isready -U postgres
+docker compose -f /opt/iris/iris-web/docker-compose.yml exec db pg_isready -U postgres

Also applies to: 246-249


291-297: Verify LICENSE path and links.

Confirm ../../LICENSE.txt exists; many repos use LICENSE without extension. Update if needed.

deploy/ansible/inventory/group_vars/all.yml (1)

14-16: Confirm Compose v2 requirement matches README and setup role.

If setup installs Compose v2.20.0, ensure all docs and tasks use docker compose and verify distro package sources provide that version.

deploy/ansible/roles/iris-app/tests/inventory (1)

2-2: Use local connection for tests.

Avoid SSH to localhost; use the local connection plugin.

-localhost
+localhost ansible_connection=local
deploy/ansible/roles/common/tests/test.yml (1)

4-6: Avoid root SSH in tests; use local connection + become.

Improves portability and CI friendliness.

-  remote_user: root
-  roles:
-    - roles/common
+  connection: local
+  become: true
+  roles:
+    - role: common
deploy/ansible/roles/common/tasks/main.yml (1)

67-73: Consider broader OS family support for locale configuration.

The locale configuration only handles Debian-family systems. RedHat-family systems might need different locale management.

Add support for RedHat family systems:

- name: Configure system locale
  locale_gen:
    name: "{{ system_locale }}"
    state: present
  when: ansible_os_family == "Debian"
  ignore_errors: true
  tags: [system, locale]

+- name: Configure system locale (RedHat/CentOS)
+  command: localectl set-locale LANG="{{ system_locale }}"
+  when: ansible_os_family == "RedHat"
+  ignore_errors: true
+  tags: [system, locale]
deploy/ansible/roles/docker/tests/test.yml (1)

1-1: Fix SPDX header format

Use a space after the comment marker for standard SPDX style.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0
deploy/ansible/roles/iris-app/tests/test.yml (1)

1-1: Fix SPDX header format

Use a space after the comment marker.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0
deploy/ansible/playbooks/setup-docker.yml (1)

5-7: Avoid loading secrets for Docker setup

These secrets aren’t needed to install Docker and create an unnecessary coupling.

-  vars_files:
-    - ../vars/secrets.yml
deploy/ansible/roles/iris-app/handlers/main.yml (2)

1-1: Fix SPDX header format

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

17-21: Enable and start service after creation

Enable alone won’t start the unit.

 - name: enable iris service
   systemd:
     name: iris
-    enabled: true
+    enabled: true
+    state: started
   listen: "enable iris service"
deploy/ansible/inventory/hosts.yml (1)

31-35: Prefer group_vars for shared variables

Consider moving iris_project_name and iris_deployment_mode to group_vars/iris_servers.yml to keep inventory focused on host definitions.

deploy/ansible/roles/iris-app/templates/iris.service.j2 (1)

10-11: oneshot + Restart is atypical

For a wrapper unit that just invokes Compose, Restart rarely helps. Either keep Type=oneshot and drop Restart, or switch to Type=simple if you want retries on ExecStart failures.

Also applies to: 28-29

deploy/ansible/roles/iris-app/tasks/main.yml (1)

117-123: Make wait_for host configurable

ansible_default_ipv4.address may be undefined (e.g., fact gathering disabled, multi-NIC). Allow an override.

   wait_for:
     port: "{{ iris_https_port }}"
-    host: "{{ ansible_default_ipv4.address }}"
+    host: "{{ iris_bind_address | default(ansible_default_ipv4.address) }}"
     delay: 30
     timeout: 300
deploy/ansible/vars/secrets.yml.example (1)

9-16: Strengthen guidance on secret generation

Add hints to generate strong random values; helps users avoid weak defaults.

 # IRIS Application Secrets
-iris_secret_key: "change-this-to-a-long-random-string"
-iris_security_password_salt: "change-this-salt-value"
+iris_secret_key: "change-this-to-a-long-random-string"  # e.g., `openssl rand -hex 64`
+iris_security_password_salt: "change-this-salt-value"    # e.g., `openssl rand -hex 32`
 
 # Default Admin User
 iris_adm_username: admin
 iris_adm_password: "change-this-admin-password"
deploy/ansible/playbooks/site.yml (2)

8-12: Fix YAML trailing space to satisfy yamllint.

There’s a trailing space after "msg:".

-    - name: Display deployment information
-      debug:
-        msg: 
+    - name: Display deployment information
+      debug:
+        msg:

14-17: Harden against undefined vars in banner.

project_name/project_version may be undefined. Use safe defaults.

-          - "Project: {{ project_name }}"
-          - "Version: {{ project_version }}"
+          - "Project: {{ project_name | default('DFIR-IRIS') }}"
+          - "Version: {{ project_version | default('unknown') }}"
deploy/ansible/playbooks/deploy-iris.yml (2)

15-21: Use wait_for without hardcoding host; rely on target host.

Using ansible_default_ipv4.address can be brittle. wait_for defaults to the remote host; drop host for simplicity.

-      wait_for:
-        port: "{{ iris_https_port }}"
-        host: "{{ ansible_default_ipv4.address }}"
+      wait_for:
+        port: "{{ iris_https_port }}"
         delay: 30
         timeout: 300

13-21: Consider an HTTP(S) health probe instead of port-open check.

wait_for only checks socket open. If you expose a /health endpoint, prefer uri with status_code 200 and retries.

deploy/ansible/quick-start.sh (2)

141-149: Use VAULT_FLAG so non-encrypted secrets don’t prompt.

-            ansible-playbook playbooks/site.yml --ask-vault-pass
+            ansible-playbook playbooks/site.yml ${VAULT_FLAG}
...
-            ansible-playbook playbooks/site.yml --tags="docker" --ask-vault-pass
+            ansible-playbook playbooks/site.yml --tags="docker" ${VAULT_FLAG}
...
-            ansible-playbook playbooks/site.yml --tags="iris-app" --ask-vault-pass
+            ansible-playbook playbooks/site.yml --tags="iris-app" ${VAULT_FLAG}

45-52: Add guidance for privilege escalation prerequisites.

Some targets need python3 and sudo. Consider printing a quick note if ansible ping fails with "Permission denied" or "python not found".

deploy/ansible/roles/docker/tasks/main.yml (1)

5-16: Minor: apt-transport-https no longer needed on modern Debian/Ubuntu.

Safe to remove to speed up runs; keep if targeting very old releases.

deploy/ansible/inventory/group_vars/iris_servers.yml (5)

10-10: Trim trailing space to satisfy yamllint.

-postgres_admin_user: "iris_admin" 
+postgres_admin_user: "iris_admin"

35-35: Trim trailing space to satisfy yamllint.

-db_image_name: "ghcr.io/dfir-iris/iriswebapp_db"  
+db_image_name: "ghcr.io/dfir-iris/iriswebapp_db"

57-59: Trim trailing space in comment line.

-# Network Configuration  
+# Network Configuration

39-41: Default development toggles to false for safety.

Avoid accidentally deploying dev settings to prod; override per-inventory when needed.

-development_mode: true
-live_reload: true
+development_mode: false
+live_reload: false

5-5: Typo check: server name looks off.

"nisir-iris.local" might be a typo for "dfir-iris.local". If intentional, ignore.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4bfeda and f92cd7e.

📒 Files selected for processing (38)
  • .gitignore (1 hunks)
  • deploy/ansible/README.md (1 hunks)
  • deploy/ansible/ansible.cfg (1 hunks)
  • deploy/ansible/inventory/group_vars/all.yml (1 hunks)
  • deploy/ansible/inventory/group_vars/iris_servers.yml (1 hunks)
  • deploy/ansible/inventory/hosts.yml (1 hunks)
  • deploy/ansible/inventory/hosts.yml.example (1 hunks)
  • deploy/ansible/playbooks/deploy-iris.yml (1 hunks)
  • deploy/ansible/playbooks/setup-docker.yml (1 hunks)
  • deploy/ansible/playbooks/site.yml (1 hunks)
  • deploy/ansible/quick-start.sh (1 hunks)
  • deploy/ansible/roles/common/README.md (1 hunks)
  • deploy/ansible/roles/common/defaults/main.yml (1 hunks)
  • deploy/ansible/roles/common/handlers/main.yml (1 hunks)
  • deploy/ansible/roles/common/meta/main.yml (1 hunks)
  • deploy/ansible/roles/common/tasks/main.yml (1 hunks)
  • deploy/ansible/roles/common/tests/inventory (1 hunks)
  • deploy/ansible/roles/common/tests/test.yml (1 hunks)
  • deploy/ansible/roles/common/vars/main.yml (1 hunks)
  • deploy/ansible/roles/docker/README.md (1 hunks)
  • deploy/ansible/roles/docker/defaults/main.yml (1 hunks)
  • deploy/ansible/roles/docker/handlers/main.yml (1 hunks)
  • deploy/ansible/roles/docker/meta/main.yml (1 hunks)
  • deploy/ansible/roles/docker/tasks/main.yml (1 hunks)
  • deploy/ansible/roles/docker/tests/inventory (1 hunks)
  • deploy/ansible/roles/docker/tests/test.yml (1 hunks)
  • deploy/ansible/roles/docker/vars/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/README.md (1 hunks)
  • deploy/ansible/roles/iris-app/defaults/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/handlers/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/meta/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/tasks/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/templates/iris.service.j2 (1 hunks)
  • deploy/ansible/roles/iris-app/tests/inventory (1 hunks)
  • deploy/ansible/roles/iris-app/tests/test.yml (1 hunks)
  • deploy/ansible/roles/iris-app/vars/main.yml (1 hunks)
  • deploy/ansible/vars/secrets.yml.example (1 hunks)
  • deploy/ansible/vars/secrets_temp.yml (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
deploy/ansible/README.md

128-128: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 YAMLlint (1.37.1)
deploy/ansible/inventory/group_vars/iris_servers.yml

[error] 10-10: trailing spaces

(trailing-spaces)


[error] 35-35: trailing spaces

(trailing-spaces)


[error] 57-57: trailing spaces

(trailing-spaces)

deploy/ansible/playbooks/site.yml

[error] 10-10: trailing spaces

(trailing-spaces)

🔇 Additional comments (15)
deploy/ansible/roles/common/handlers/main.yml (1)

1-3: Unify SPDX-License-Identifier across Ansible role files
The handlers, defaults, vars, tasks, and test files use MIT-0, while each role’s meta/main.yml uses MIT. Please standardize on a single identifier or confirm the repository policy.
Optional diff (if adopting MIT):

-#SPDX-License-Identifier: MIT-0
+#SPDX-License-Identifier: MIT
.gitignore (1)

36-36: Ignore entry is correctlog_path = ./ansible.log in deploy/ansible/ansible.cfg resolves to deploy/ansible/ansible.log, so the .gitignore entry is valid.

deploy/ansible/roles/docker/meta/main.yml (1)

22-24: Confirm Ansible 2.9 compatibility or raise baseline

2.9 is long-EOL; if you rely on newer modules/args, declare ≥2.12/2.13. Otherwise, verify all roles avoid features added after 2.9.

Suggested update if you’re not targeting 2.9:

-  min_ansible_version: "2.9"
+  min_ansible_version: "2.13"
deploy/ansible/inventory/hosts.yml.example (1)

40-44: Consider showing become at play level instead of inventory

Most roles require privilege; demonstrate become in playbooks (as done in README examples) and keep inventory minimal. No change required here—just documentation alignment.

deploy/ansible/roles/common/meta/main.yml (1)

22-36: README.md does not specify Ubuntu 18.04+ or CentOS/RHEL support—remove or correct those platform assertions before adjusting meta/main.yml.

Likely an incorrect or invalid review comment.

deploy/ansible/roles/common/tasks/main.yml (4)

5-10: LGTM! Proper OS-specific package management.

The task correctly uses conditional logic to handle different package managers for Debian/Ubuntu systems with appropriate cache validation time.


12-16: LGTM! Consistent OS-specific package management.

The task properly handles RedHat/CentOS systems with yum cache updates.


18-30: LGTM! Good essential package selection.

The package list includes commonly needed utilities for system administration and development work, which is appropriate for an IRIS deployment environment.


48-59: Directory creation order correct; no changes required
Verified that both iris_project_path ({{ iris_base_path }}/NISIR-iris-web) and iris_backup_path ({{ iris_base_path }}/backups) are subdirectories of iris_base_path as defined in deploy/ansible/inventory/group_vars/all.yml, and the task loop creates iris_base_path first, satisfying dependencies.

deploy/ansible/playbooks/setup-docker.yml (1)

21-22: Verify registered fact names from docker role

Confirm the role actually registers docker_version and docker_compose_version_output; otherwise this will render “Unknown”.

deploy/ansible/roles/iris-app/tasks/main.yml (2)

81-91: Certificate validity parameter and SANs

Please verify the correctness of valid_in for the module in use and consider adding subjectAltName; most clients ignore CN without SAN.

Example alternative (community.crypto.x509_certificate):

- name: Generate self-signed certificate
  community.crypto.x509_certificate:
    path: "{{ iris_project_path }}/certificates/web_certificates/{{ cert_filename }}"
    privatekey_path: "{{ iris_project_path }}/certificates/web_certificates/{{ key_filename }}"
    provider: selfsigned
    subject:
      common_name: "{{ iris_server_name }}"
    subject_alt_name:
      - "DNS:{{ iris_server_name }}"
      - "IP:{{ ansible_default_ipv4.address }}"
    not_after: "+{{ ssl_cert_days }}d"
    owner: "{{ iris_user }}"
    group: "{{ iris_group }}"
    mode: "0644"

32-43: Confirm .env template presence

Ensure templates/.env.j2 exists in this role; otherwise this task will fail.

deploy/ansible/playbooks/site.yml (1)

66-68: iris_https_port is defined in group_vars – it’s set to 443 in deploy/ansible/inventory/group_vars/all.yml (line 22) and documented in README.md.

deploy/ansible/roles/docker/tasks/main.yml (2)

86-93: No action needed: ‘restart docker’ handler is present
The handler is defined in deploy/ansible/roles/docker/handlers/main.yml.


67-85: Privilege escalation already enabled globally
The deploy/ansible/ansible.cfg [privilege_escalation] section sets become = True by default, so all tasks (including Docker installs and service actions) run as root.

Comment on lines +1 to +3
[defaults]
# Basic Configuration
inventory = inventory/hosts.yml
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

ansible.cfg discovery vs. README usage.

Running ansible-playbook deploy/ansible/playbooks/site.yml from repo root won’t pick up this ansible.cfg. Either instruct users to cd deploy/ansible or pass -i/set ANSIBLE_CONFIG.


🏁 Script executed:

#!/usr/bin/env bash
set -e

# Find all ansible.cfg files
find . -type f -name ansible.cfg

# Show the first 20 lines of deploy/ansible/ansible.cfg if it exists
if [ -f deploy/ansible/ansible.cfg ]; then
  echo "Contents of deploy/ansible/ansible.cfg:"
  sed -n '1,20p' deploy/ansible/ansible.cfg
else
  echo "deploy/ansible/ansible.cfg not found"
fi

# Show README.md (first 200 lines) and lines mentioning 'ansible'
if [ -f README.md ]; then
  echo "README.md (first 200 lines):"
  sed -n '1,200p' README.md
  echo ""
  echo "Lines mentioning 'ansible' in README.md:"
  grep -n "ansible" README.md || echo "No mention of 'ansible' in README.md"
else
  echo "README.md not found"
fi

Length of output: 5362


Update Ansible usage instructions
When running ansible-playbook deploy/ansible/playbooks/site.yml from the repository root, Ansible will not load deploy/ansible/ansible.cfg (it only scans the current directory and its parents). Update the documentation to either:

  • cd deploy/ansible before invoking the playbook, or
  • invoke with ANSIBLE_CONFIG=deploy/ansible/ansible.cfg (or -c deploy/ansible/ansible.cfg) so that the correct config—and thus the inventory = inventory/hosts.yml setting—is applied.
🤖 Prompt for AI Agents
In deploy/ansible/ansible.cfg around lines 1 to 3: the repo-level docs must be
updated to explain Ansible won't auto-load deploy/ansible/ansible.cfg when run
from the repo root; update the relevant documentation (top-level README.md
and/or deploy/ansible/README.md) to instruct users to either cd deploy/ansible
before running ansible-playbook deploy/ansible/playbooks/site.yml or run the
playbook with ANSIBLE_CONFIG=deploy/ansible/ansible.cfg (or the equivalent -c
deploy/ansible/ansible.cfg) so the inventory = inventory/hosts.yml setting is
picked up.

Comment on lines 3 to 4
inventory = inventory/hosts.yml
host_key_checking = False
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don’t globally disable SSH host key checking.

Current settings disable verification in two places, increasing MITM risk. Either remove these or gate them via environment for labs only.

-inventory = inventory/hosts.yml
-host_key_checking = False
+inventory = inventory/hosts.yml
+host_key_checking = True
@@
-[ssh_connection]
-ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
+[ssh_connection]
+ssh_args = -o ControlMaster=auto -o ControlPersist=60s

Doc a first-run option: ANSIBLE_HOST_KEY_CHECKING=False ... for non-prod.

Also applies to: 26-29

🤖 Prompt for AI Agents
In deploy/ansible/ansible.cfg around lines 3-4 (and also apply the same change
to lines 26-29), the configuration globally disables SSH host key checking which
increases MITM risk; remove the global host_key_checking = False setting and
instead guard it behind an explicit, documented runtime override for
non-production use (e.g., instruct users to run with
ANSIBLE_HOST_KEY_CHECKING=False in their environment for first-run/lab
scenarios), or add a commented example showing how to enable the override
per-invocation so production defaults remain secure.

Comment on lines 5 to 11
project_name: "NISIR-iris-web"
project_version: "v1.2.0"

# Deployment Paths
iris_base_path: "/opt/NISIR-iris"
iris_project_path: "{{ iris_base_path }}/NISIR-iris-web"
iris_backup_path: "{{ iris_base_path }}/backups"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Unify project naming and paths with README.

README uses project_version: "v2.4.12" and base path /opt/iris; here it’s NISIR-iris(-web) and /opt/NISIR-iris. Align to one canonical name/path to avoid mismatched directories and Compose project names.

-project_name: "NISIR-iris-web"
-project_version: "v1.2.0"
+project_name: "dfir-iris-web"
+project_version: "v2.4.12"
@@
-iris_base_path: "/opt/NISIR-iris"
-iris_project_path: "{{ iris_base_path }}/NISIR-iris-web"
+iris_base_path: "/opt/iris"
+iris_project_path: "{{ iris_base_path }}/iris-web"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
project_name: "NISIR-iris-web"
project_version: "v1.2.0"
# Deployment Paths
iris_base_path: "/opt/NISIR-iris"
iris_project_path: "{{ iris_base_path }}/NISIR-iris-web"
iris_backup_path: "{{ iris_base_path }}/backups"
project_name: "dfir-iris-web"
project_version: "v2.4.12"
# Deployment Paths
iris_base_path: "/opt/iris"
iris_project_path: "{{ iris_base_path }}/iris-web"
iris_backup_path: "{{ iris_base_path }}/backups"
🤖 Prompt for AI Agents
In deploy/ansible/inventory/group_vars/all.yml around lines 5 to 11, the project
name, version and base path differ from the README (currently using
NISIR-iris/NISIR-iris-web and /opt/NISIR-iris); update these variables to the
canonical values used in the README by setting project_version to "v2.4.12",
change iris_base_path to "/opt/iris", and adjust project_name and dependent
paths (iris_project_path, iris_backup_path, etc.) so all templates/Compose
project names reference the single canonical name/path used in documentation.

Comment on lines 12 to 14
ExecStart=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml up -d
ExecStop=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml down
ExecReload=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml restart
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hardcoding docker-compose v1; parameterize the command

Compose v1 is EOL; support both via a variable defaulting to “docker compose”.

-ExecStart=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml up -d
-ExecStop=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml down
-ExecReload=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml restart
+ExecStart={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml up -d
+ExecStop={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml down
+ExecReload={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml restart
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ExecStart=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml up -d
ExecStop=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml down
ExecReload=/usr/bin/docker-compose -f {{ iris_project_path }}/docker-compose.dev.yml restart
# deploy/ansible/roles/iris-app/templates/iris.service.j2
# … previous lines …
ExecStart={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml up -d
ExecStop={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml down
ExecReload={{ docker_compose_cmd | default('docker compose') }} -f {{ iris_project_path }}/docker-compose.dev.yml restart
# … following lines …
🤖 Prompt for AI Agents
In deploy/ansible/roles/iris-app/templates/iris.service.j2 around lines 12 to
14, the systemd unit hardcodes the docker-compose v1 binary; change those
ExecStart/ExecStop/ExecReload lines to use a Jinja2 template variable (e.g.
docker_compose_cmd) instead of the literal "/usr/bin/docker-compose", and update
the role defaults (defaults/main.yml) to set docker_compose_cmd to a sensible
default of "docker compose" (allowing override to "/usr/bin/docker-compose" if
needed); ensure the variable includes the full command and flags (e.g. "<cmd> -f
{{ iris_project_path }}/docker-compose.dev.yml up -d") so the unit works with
both Compose v2 and v1.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (4)
deploy/ansible/README.md (4)

9-11: Quick start won’t load ansible.cfg; cd into deploy/ansible first.

Running from repo root bypasses deploy/ansible/ansible.cfg. Change directory (or set ANSIBLE_CONFIG) so inventory/ssh/escalation settings apply.

-```bash
-ansible-playbook deploy/ansible/playbooks/site.yml --ask-vault-pass
-```
+```bash
+cd deploy/ansible
+ansible-playbook playbooks/site.yml --ask-vault-pass
+```

128-133: Security note example should also cd so ansible.cfg is applied.

-ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook deploy/ansible/playbooks/site.yml --ask-vault-pass
+cd deploy/ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook playbooks/site.yml --ask-vault-pass

205-210: Use “docker compose” (v2) instead of deprecated docker-compose (v1).

 # Check Docker containers
-docker-compose -f /opt/iris/iris-web/docker-compose.yml ps
+docker compose -f /opt/iris/iris-web/docker-compose.yml ps

213-219: Update log commands to Compose v2 plugin syntax.

 # IRIS application logs
-docker-compose -f /opt/iris/iris-web/docker-compose.yml logs app
+docker compose -f /opt/iris/iris-web/docker-compose.yml logs app
@@
 # All service logs
-docker-compose -f /opt/iris/iris-web/docker-compose.yml logs
+docker compose -f /opt/iris/iris-web/docker-compose.yml logs
🧹 Nitpick comments (9)
deploy/ansible/roles/common/tests/test.yml (3)

1-1: Fix SPDX header formatting for tooling detection

Add a space after the comment marker so SPDX scanners pick it up.

-#SPDX-License-Identifier: MIT-0
+# SPDX-License-Identifier: MIT-0

6-7: Ensure the role resolves in test context

Referencing the role by name may fail when running this playbook from its tests/ directory unless roles_path is configured. Point to the role via a relative path or confirm ansible.cfg sets roles_path to deploy/ansible/roles.

   roles:
-    - common
+    - role: ..

If roles_path is already set accordingly, feel free to keep the name reference.


3-5: Minor test ergonomics: add a name and skip fact gathering

Speeds up local runs and clarifies output.

 - hosts: localhost
   connection: local
   become: true
+  name: "Common role test on localhost"
+  gather_facts: false
deploy/ansible/README.md (4)

121-124: Make connectivity test consistent with ansible.cfg usage.

-```bash
-ansible all -m ping -i deploy/ansible/inventory/hosts.yml
-```
+```bash
+cd deploy/ansible && ansible all -m ping -i inventory/hosts.yml
+```

137-157: Add a language to fenced code block (markdownlint MD040).

-```
+```text
 ...
-```
+```

223-228: Modernize service check; use Compose v2 and prefer ss over netstat.

 # Check if NGINX is running
-docker-compose ps nginx
-sudo netstat -tlnp | grep :443
+docker compose ps nginx
+sudo ss -tlnp | grep ':443'

277-279: Certificate renewal example should cd into deploy/ansible.

-ansible-playbook deploy/ansible/playbooks/site.yml --tags="certificates" --ask-vault-pass
+cd deploy/ansible && ansible-playbook playbooks/site.yml --tags="certificates" --ask-vault-pass
deploy/ansible/inventory/group_vars/iris_servers.yml (2)

40-42: Default development flags to false in group_vars for servers.

Safer defaults; enable per-host or via extra_vars when needed.

-development_mode: true
-live_reload: true
+development_mode: false
+live_reload: false

11-11: Remove trailing spaces (yamllint).

-postgres_admin_user: "postgres" 
+postgres_admin_user: "postgres"
@@
-db_image_name: "ghcr.io/dfir-iris/iriswebapp_db"  
+db_image_name: "ghcr.io/dfir-iris/iriswebapp_db"
@@
-# Network Configuration  
- docker_networks:
+# Network Configuration
+docker_networks:

Also applies to: 36-36, 58-58

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f92cd7e and 8dad079.

📒 Files selected for processing (11)
  • CODERABBIT_FIXES.md (1 hunks)
  • deploy/ansible/README.md (1 hunks)
  • deploy/ansible/ansible.cfg (1 hunks)
  • deploy/ansible/inventory/group_vars/all.yml (1 hunks)
  • deploy/ansible/inventory/group_vars/iris_servers.yml (1 hunks)
  • deploy/ansible/playbooks/deploy-iris.yml (1 hunks)
  • deploy/ansible/roles/common/tests/test.yml (1 hunks)
  • deploy/ansible/roles/docker/tests/test.yml (1 hunks)
  • deploy/ansible/roles/iris-app/tasks/main.yml (1 hunks)
  • deploy/ansible/roles/iris-app/templates/iris.service.j2 (1 hunks)
  • deploy/ansible/roles/iris-app/tests/test.yml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • CODERABBIT_FIXES.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • deploy/ansible/roles/iris-app/templates/iris.service.j2
  • deploy/ansible/roles/docker/tests/test.yml
  • deploy/ansible/ansible.cfg
  • deploy/ansible/roles/iris-app/tests/test.yml
  • deploy/ansible/playbooks/deploy-iris.yml
  • deploy/ansible/inventory/group_vars/all.yml
  • deploy/ansible/roles/iris-app/tasks/main.yml
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
deploy/ansible/README.md

137-137: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 YAMLlint (1.37.1)
deploy/ansible/inventory/group_vars/iris_servers.yml

[error] 11-11: trailing spaces

(trailing-spaces)


[error] 36-36: trailing spaces

(trailing-spaces)


[error] 58-58: trailing spaces

(trailing-spaces)

🔇 Additional comments (1)
deploy/ansible/roles/common/tests/test.yml (1)

3-7: Verify idempotence of the common role
Run ansible-playbook -i deploy/ansible/roles/common/tests/inventory deploy/ansible/roles/common/tests/test.yml twice and confirm the second run reports changed=0, failed=0.

Comment on lines +10 to +13
postgres_user: "postgres"
postgres_admin_user: "iris_admin"
postgres_db: "iris_db"
postgres_server: "db"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Likely DB user mix-up: swap app and admin users.

Typical defaults are postgres_admin_user=postgres and postgres_user=iris. Current values look inverted and may break DB tasks.

-postgres_user: "postgres"
-postgres_admin_user: "iris_admin" 
+postgres_user: "iris"
+postgres_admin_user: "postgres"

Verify usage across roles:


🏁 Script executed:

#!/bin/bash
rg -nC2 -e 'postgres_user' -e 'postgres_admin_user' deploy/ansible

Length of output: 765


Swap Postgres user variables to match documented defaults
In deploy/ansible/inventory/group_vars/iris_servers.yml (lines 10–11), set

postgres_user: "iris"
postgres_admin_user: "postgres"

to align with the values in deploy/ansible/README.md (lines 66–67).

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 11-11: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In deploy/ansible/inventory/group_vars/iris_servers.yml around lines 10 to 11,
the postgres user variables are reversed relative to the documented defaults;
change postgres_user from "postgres" to "iris" and postgres_admin_user from
"iris_admin" to "postgres" so they match deploy/ansible/README.md (lines 66–67).

Comment on lines +55 to +61
**Global settings** (`inventory/group_vars/all.yml`):
```yaml
iris_base_path: /opt/iris
iris_https_port: 443
docker_compose_version: "2.20.0"
project_version: "v2.4.12"
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Version mismatch: project_version differs from iris_app_version.

README shows project_version "v2.4.12" but iris_app_version is "v2.4.20". Align to avoid deploying mixed versions.

- project_version: "v2.4.12"
+ project_version: "v2.4.20"

Run to check for other drifts:


🏁 Script executed:

#!/bin/bash
rg -nP 'v2\.4\.\d+' -C2 deploy/ansible | sed -n '1,120p'

Length of output: 956


Align project_version in README with iris_app_version
In deploy/ansible/README.md (line 60), update the project_version from "v2.4.12" to "v2.4.20" to match inventory settings:

--- a/deploy/ansible/README.md
+++ b/deploy/ansible/README.md
@@ -58,4 +58,4 @@ iris_https_port: 443
 docker_compose_version: "2.20.0"
-project_version: "v2.4.12"
+project_version: "v2.4.20"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Global settings** (`inventory/group_vars/all.yml`):
```yaml
iris_base_path: /opt/iris
iris_https_port: 443
docker_compose_version: "2.20.0"
project_version: "v2.4.12"
```
**Global settings** (`inventory/group_vars/all.yml`):
🤖 Prompt for AI Agents
In deploy/ansible/README.md around lines 55 to 61, the README's Global settings
show project_version as "v2.4.12" which is out of sync with the inventory's
iris_app_version; update the project_version value to "v2.4.20" so the README
matches the inventory settings and reflects the correct current project version.

Comment on lines +231 to +234
```bash
# Test database connectivity
docker exec -it iris-web_db psql -U postgres -d iris_db -c "SELECT version();"
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Exec into DB via Compose to avoid brittle container names.

-# Test database connectivity
-docker exec -it iris-web_db psql -U postgres -d iris_db -c "SELECT version();"
+# Test database connectivity
+docker compose exec -T db psql -U postgres -d iris_db -c "SELECT version();"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
# Test database connectivity
docker exec -it iris-web_db psql -U postgres -d iris_db -c "SELECT version();"
```
🤖 Prompt for AI Agents
In deploy/ansible/README.md around lines 231 to 234, the README uses docker exec
with a hardcoded container name (iris-web_db), which is brittle; update the
instructions to use the Compose exec command instead (e.g., docker compose exec
<service-name> psql -U postgres -d iris_db -c "SELECT version();" or
docker-compose exec <service-name> ...) and mention using the DB service name
from docker-compose.yml so the command works regardless of the underlying
container name.

@mfeti mfeti changed the base branch from master to develop September 10, 2025 07:46
- Complete Ansible playbook for DFIR-IRIS deployment
- Multi-role setup (common, docker, iris-app)
- SSL certificate generation
- Secrets management with Ansible Vault
- Example configuration files only (no real credentials)
- Comprehensive documentation and README
…rovements

🔒 Security Fixes:
- Enable SSH host key checking (fixes MITM vulnerability)
- Add proper privilege escalation for system tasks
- Add lab override documentation for testing

🐳 Technical Improvements:
- Modernize to Docker Compose v2 (docker compose)
- Standardize project naming to 'dfir-iris' throughout
- Fix version consistency (v2.4.20)
- Add missing configuration variables
- Ensure consistent compose file usage

⚙️ Code Quality:
- Update role tests to use modern connection methods
- Fix privilege escalation in all system operations
- Parameterize Docker commands for maintainability

📚 Documentation:
- Add security guidance for SSH host key checking
- Include comprehensive fix summary (CODERABBIT_FIXES.md)

Addresses all 25 actionable comments and 58 nitpick suggestions from
CodeRabbit automated review. Result: Production-ready Ansible deployment
with enterprise security standards.
@mfeti mfeti force-pushed the feature/ansible-playbook branch from 8dad079 to 509854b Compare September 10, 2025 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Provide Ansible playbook for DFIR-IRIS deployment

1 participant