diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..6462d1a --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,40 @@ +name: Lint Ansible & YAML + +on: + push: + branches: + - "feature/github-actions" + pull_request: + branches: + - main + +jobs: + lint: + name: Lint codebase + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Cache pip + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install linting tools + run: | + python -m pip install --upgrade pip + pip install ansible ansible-lint yamllint + + - name: Run Ansible Lint + working-directory: ansible + run: ansible-lint . diff --git a/Makefile b/Makefile index 36c5fb1..d2e7df1 100644 --- a/Makefile +++ b/Makefile @@ -3,13 +3,14 @@ # ========================================================== # Set variables -VENV_DIR := $(HOME)/.venvs/ansible +VENV_DIR := $(HOME)/.virtualenvs/ansible REQUIREMENTS := ansible/requirements.txt DOCKER_BUILD_SCRIPT := ./build_and_push_private.sh DOCKER_CLEAN_SCRIPT := ./cleanup_docker.sh +PRECOMMIT_CONFIG := ansible/.pre-commit-config.yaml -.PHONY: help venv init upgrade build cleanup +.PHONY: help venv init upgrade build cleanup lint # ---------------------------------------------------------- # Help commands @@ -33,8 +34,16 @@ venv: @echo "✅ Virtualenv created at $(VENV_DIR)" init: venv - @. $(VENV_DIR)/bin/activate && pip install --upgrade pip && pip install -r $(REQUIREMENTS) - @echo "✅ Dependencies installed in $(VENV_DIR)" + @echo "📦 Installing dependencies and pre-commit hooks..." + @$(VENV_DIR)/bin/pip install --upgrade pip + @$(VENV_DIR)/bin/pip install -r $(REQUIREMENTS) + @if [ -x "$(VENV_DIR)/bin/pre-commit" ]; then \ + echo "⚙️ Installing pre-commit hook (config: $(PRECOMMIT_CONFIG))..."; \ + $(VENV_DIR)/bin/pre-commit install --config $(PRECOMMIT_CONFIG); \ + else \ + echo "⚠️ pre-commit not found (check requirements.txt)"; \ + fi + @echo "✅ Environment initialized in $(VENV_DIR)" upgrade: @echo "⬆️ Mise à jour du venv et de tous les paquets..." @@ -48,6 +57,11 @@ build: @chmod +x $(DOCKER_BUILD_SCRIPT) @$(DOCKER_BUILD_SCRIPT) +lint: + @echo "🔍 Running Ansible and YAML linters..." + ~/.venvs/ansible/bin/ansible-lint ansible/ + ~/.venvs/ansible/bin/yamllint . + cleanup: @echo "Cleaning up Docker resources..." @chmod +x $(DOCKER_CLEAN_SCRIPT) diff --git a/ansible/.ansible-lint b/ansible/.ansible-lint new file mode 100644 index 0000000..07cf3d5 --- /dev/null +++ b/ansible/.ansible-lint @@ -0,0 +1,10 @@ +--- +skip_list: + - command-instead-of-module + - risky-shell-pipe + - package-latest + - var-naming + - ignore-errors +warn_list: + - jinja + - yaml diff --git a/ansible/.pre-commit-config.yaml b/ansible/.pre-commit-config.yaml new file mode 100644 index 0000000..245bd53 --- /dev/null +++ b/ansible/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +--- +repos: + - repo: https://github.com/ansible/ansible-lint + rev: v25.9.2 + hooks: + - id: ansible-lint + name: Ansible Lint + args: [--force-color, ansible/] + files: ^ansible/ diff --git a/ansible/forge-cicd.yml b/ansible/forge-cicd.yml index a539081..c7f980c 100644 --- a/ansible/forge-cicd.yml +++ b/ansible/forge-cicd.yml @@ -1,14 +1,15 @@ --- -- hosts: all - +- name: Forge CI/CD Deployment + hosts: all + # Only if you want to be prompted for Docker Hub credentials vars_prompt: - name: "docker_hub_user" prompt: "Docker Hub username" - private: no + private: false - name: "docker_hub_token" prompt: "Docker Hub Token" - private: yes + private: true roles: - postinstall diff --git a/ansible/requirements.txt b/ansible/requirements.txt index a4e4dff..fccb5c6 100644 --- a/ansible/requirements.txt +++ b/ansible/requirements.txt @@ -6,6 +6,7 @@ ansible-lint paramiko jinja2 cryptography +pre-commit # ####### # dev tools diff --git a/ansible/requirements.yml b/ansible/requirements.yml new file mode 100644 index 0000000..3aeaea3 --- /dev/null +++ b/ansible/requirements.yml @@ -0,0 +1,4 @@ +--- +collections: + - name: community.docker + version: ">=4.8.1" diff --git a/ansible/roles/docker/defaults/main.yml b/ansible/roles/docker/defaults/main.yml index 6fd38fa..bdbb85c 100644 --- a/ansible/roles/docker/defaults/main.yml +++ b/ansible/roles/docker/defaults/main.yml @@ -1,8 +1,8 @@ --- # Docker vars -docker_ansible_user: "root" +docker_ansible_user: root -docker_group: "docker" +docker_group: docker docker_ubuntu_repo: "https://download.docker.com/linux/ubuntu" diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml index 5df65c3..1c59ae1 100644 --- a/ansible/roles/docker/tasks/main.yml +++ b/ansible/roles/docker/tasks/main.yml @@ -1,9 +1,9 @@ --- - name: Add Docker GPG key - ansible.builtin.shell: | - curl -fsSL {{ docker_gpg_url }} | sudo tee /etc/apt/trusted.gpg.d/docker.asc - args: - creates: /etc/apt/trusted.gpg.d/docker.asc + ansible.builtin.get_url: + url: "{{ docker_gpg_url }}" + dest: /etc/apt/trusted.gpg.d/docker.asc + mode: "0644" - name: Add Docker repository ansible.builtin.apt_repository: @@ -13,7 +13,7 @@ - name: Update repository ansible.builtin.apt: - update_cache: yes + update_cache: true - name: Install docker ansible.builtin.apt: @@ -24,10 +24,10 @@ ansible.builtin.systemd: name: docker state: started - enabled: yes + enabled: true - name: Add user to docker group ansible.builtin.user: name: "{{ ansible_user }}" groups: "{{ docker_group }}" - append: yes + append: true diff --git a/ansible/roles/forge_cicd/meta/main.yml b/ansible/roles/forge_cicd/meta/main.yml index 8d5dee2..d8cd8e2 100644 --- a/ansible/roles/forge_cicd/meta/main.yml +++ b/ansible/roles/forge_cicd/meta/main.yml @@ -1,7 +1,8 @@ +--- galaxy_info: author: Thomas Fx description: Deploy CI/CD Forge license: MIT min_ansible_version: "2.1" galaxy_tags: [] -dependencies: [] \ No newline at end of file +dependencies: [] diff --git a/ansible/roles/forge_cicd/tasks/main.yml b/ansible/roles/forge_cicd/tasks/main.yml index 275f3a0..9e37915 100644 --- a/ansible/roles/forge_cicd/tasks/main.yml +++ b/ansible/roles/forge_cicd/tasks/main.yml @@ -5,19 +5,23 @@ owner: root group: root state: directory + mode: '0755' - name: Copy Docker Compose ansible.builtin.copy: src: ../docker-compose.yml dest: "{{ forge_cicd_docker_path }}/docker-compose.yml" - register: compose_copy + owner: root + group: root + mode: "0644" + register: forge_cicd_compose_copy - name: Copy environment file ansible.builtin.copy: src: .env dest: "{{ forge_cicd_docker_path }}/.env" mode: "600" - register: env_copy + register: forge_cicd_env_copy # Only if prompted for Docker Hub credentials and need custom images - name: Connect to Docker Hub @@ -31,23 +35,23 @@ state: present pull: always recreate: always - when: compose_copy.changed or env_copy.changed + when: forge_cicd_compose_copy.changed or forge_cicd_env_copy.changed - name: Check containers status ansible.builtin.command: docker ps --format '{% raw %}{{.Names}}{% endraw %}' - register: running_containers + register: forge_cicd_running_containers changed_when: false - name: Print running containers ansible.builtin.debug: - msg: "{{ item }} is running" - loop: "{{ running_containers.stdout_lines }}" - when: running_containers.stdout_lines is defined and running_containers.stdout_lines | length > 0 + msg: "{{ item }} is running" + loop: "{{ forge_cicd_running_containers.stdout_lines }}" + when: forge_cicd_running_containers.stdout_lines is defined and forge_cicd_running_containers.stdout_lines | length > 0 - name: Status summary ansible.builtin.debug: msg: >- - {% if compose_copy.changed or env_copy.changed %} + {% if forge_cicd_compose_copy.changed or forge_cicd_env_copy.changed %} Configuration files modified. Docker Compose has been redeployed. {% else %} No changes detected on 'docker-compose.yml' or '.env'. Deployment unchanged. diff --git a/ansible/roles/postinstall/defaults/main.yml b/ansible/roles/postinstall/defaults/main.yml index 6add21e..d1d3c41 100644 --- a/ansible/roles/postinstall/defaults/main.yml +++ b/ansible/roles/postinstall/defaults/main.yml @@ -1,11 +1,11 @@ # PostInstall role vars postinstall_extra_packages_ubuntu: -- apt-transport-https -- ca-certificates -- curl -- git -- rsyslog -- software-properties-common -- tree -- vim -- wget + - apt-transport-https + - ca-certificates + - curl + - git + - rsyslog + - software-properties-common + - tree + - vim + - wget diff --git a/ansible/roles/postinstall/tasks/main.yml b/ansible/roles/postinstall/tasks/main.yml index 28e24f1..271732a 100644 --- a/ansible/roles/postinstall/tasks/main.yml +++ b/ansible/roles/postinstall/tasks/main.yml @@ -1,9 +1,11 @@ --- +- name: Update package index + ansible.builtin.apt: + update_cache: true + - name: Upgrade all packages - ansible.builtin.package: - name: "*" - update_cache: yes - state: latest + ansible.builtin.apt: + upgrade: dist - name: Install Ubuntu packages ansible.builtin.apt: diff --git a/ansible/roles/trivy/defaults/main.yml b/ansible/roles/trivy/defaults/main.yml index 0c35d6e..f72dfdc 100644 --- a/ansible/roles/trivy/defaults/main.yml +++ b/ansible/roles/trivy/defaults/main.yml @@ -1,10 +1,10 @@ --- -forge_cicd_docker_path: /opt/docker/forge +trivy_forge_cicd_docker_path: /opt/docker/forge # PostInstall role vars trivy_requirements_packages: -- apt-transport-https -- gnupg -- gnupg2 -- lsb-release -- wget \ No newline at end of file + - apt-transport-https + - gnupg + - gnupg2 + - lsb-release + - wget diff --git a/ansible/roles/trivy/meta/main.yml b/ansible/roles/trivy/meta/main.yml index fe02748..3872d44 100644 --- a/ansible/roles/trivy/meta/main.yml +++ b/ansible/roles/trivy/meta/main.yml @@ -7,4 +7,4 @@ galaxy_info: galaxy_tags: [] -dependencies: [] \ No newline at end of file +dependencies: [] diff --git a/ansible/roles/trivy/tasks/main.yml b/ansible/roles/trivy/tasks/main.yml index 4d58d2b..aa75884 100644 --- a/ansible/roles/trivy/tasks/main.yml +++ b/ansible/roles/trivy/tasks/main.yml @@ -9,7 +9,7 @@ ansible.builtin.apt: name: "{{ trivy_requirements_packages }}" state: present - update_cache: yes + update_cache: true when: trivy_check.rc != 0 - name: Add GPG key @@ -26,35 +26,36 @@ - name: Install Trivy ansible.builtin.apt: name: trivy - state: latest + state: present update_cache: true - name: Create reports directory ansible.builtin.file: - path: "{{ forge_cicd_docker_path }}/reports" + path: "{{ trivy_forge_cicd_docker_path }}/reports" state: directory mode: "0755" - name: List Docker images ansible.builtin.command: cmd: docker compose images --format json - chdir: "{{ forge_cicd_docker_path }}" - register: docker_images + chdir: "{{ trivy_forge_cicd_docker_path }}" + register: trivy_docker_images changed_when: false - name: Scan Docker images with Trivy ansible.builtin.command: > trivy image --quiet --format template --template "@/usr/local/share/trivy/templates/html.tpl" - --output {{ forge_cicd_docker_path }}/reports/{{ item.Repository | replace('/', '_') }}_{{ item.Tag }}.html + --output {{ trivy_forge_cicd_docker_path }}/reports/{{ item.Repository | replace('/', '_') }}_{{ item.Tag }}.html {{ item.Repository }}:{{ item.Tag }} - loop: "{{ docker_images.stdout | from_json }}" + loop: "{{ trivy_docker_images.stdout | from_json }}" + register: trivy_scan changed_when: false - ignore_errors: true + failed_when: trivy_scan.rc not in [0, 1] - name: Find Trivy reports ansible.builtin.find: - paths: "{{ forge_cicd_docker_path }}/reports" + paths: "{{ trivy_forge_cicd_docker_path }}/reports" patterns: "*.html" recurse: false register: trivy_reports_to_fetch @@ -67,7 +68,7 @@ ansible.builtin.fetch: src: "{{ item.path }}" dest: ../reports/ - flat: yes + flat: true loop: "{{ trivy_reports_to_fetch.files }}" loop_control: label: "{{ item.path | basename }}"