From 8c9ad606027214018f954d0b415cb76a3be0b3f7 Mon Sep 17 00:00:00 2001 From: Jose Date: Sat, 7 Feb 2026 07:22:24 +0100 Subject: [PATCH] Initial commit --- .ansible-lint | 31 ++++++ .continue/.markdownlint.json | 3 + .continue/rules/ansible.md | 127 +++++++++++++++++++++++ .continue/rules/repo-readme.md | 159 +++++++++++++++++++++++++++++ .gitea/workflows/AiReviewPR.yaml | 42 ++++++++ .gitea/workflows/ansible-lint.yml | 34 ++++++ .gitea/workflows/gitleaks.yml | 35 +++++++ .gitea/workflows/markdown-lint.yml | 24 +++++ .gitea/workflows/stale.yml | 72 +++++++++++++ .gitignore | 39 +++++++ .markdownlintignore | 2 + .yamllint | 23 +++++ LICENSE | 21 ++++ README.md | 88 ++++++++++++++++ defaults/main.yml | 38 +++++++ handlers/main.yml | 45 ++++++++ meta/main.yml | 20 ++++ tasks/backup.yml | 28 +++++ tasks/main.yml | 14 +++ tasks/monitoring.yml | 22 ++++ vars/main.yml | 2 + 21 files changed, 869 insertions(+) create mode 100644 .ansible-lint create mode 100644 .continue/.markdownlint.json create mode 100644 .continue/rules/ansible.md create mode 100644 .continue/rules/repo-readme.md create mode 100644 .gitea/workflows/AiReviewPR.yaml create mode 100644 .gitea/workflows/ansible-lint.yml create mode 100644 .gitea/workflows/gitleaks.yml create mode 100644 .gitea/workflows/markdown-lint.yml create mode 100644 .gitea/workflows/stale.yml create mode 100644 .gitignore create mode 100644 .markdownlintignore create mode 100644 .yamllint create mode 100644 LICENSE create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 handlers/main.yml create mode 100644 meta/main.yml create mode 100644 tasks/backup.yml create mode 100644 tasks/main.yml create mode 100644 tasks/monitoring.yml create mode 100644 vars/main.yml diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..85ac1ac --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,31 @@ +--- + +# .ansible-lint + +exclude_paths: + - .gitea + +# Ansible-lint does not automatically load rules that have the 'opt-in' tag. + +# You must enable opt-in rules by listing each rule 'id' below. + +enable_list: + - args + - empty-string-compare # opt-in + - no-log-password # opt-in + - no-same-owner # opt-in + - name[prefix] # opt-in + - galaxy-version-incorrect # opt-in +# add yaml here if you want to avoid ignoring yaml checks when yamllint +# library is missing. Normally its absence just skips using that rule. + - yaml +# List of additional kind:pattern to be added at the top of the default +# match list, first match determines the file kind. +kinds: + - playbook: "**/playbooks/*.{yml,yaml}" + - roles: "**/roles/*.{yml,yaml}" + # - galaxy: "**/folder/galaxy.yml" + - tasks: "**/tasks/*.yml" + - vars: "**/vars/*.yml" + - meta: "**/meta/main.yml" + - yaml: "**/*.yaml-too" diff --git a/.continue/.markdownlint.json b/.continue/.markdownlint.json new file mode 100644 index 0000000..3eb7f83 --- /dev/null +++ b/.continue/.markdownlint.json @@ -0,0 +1,3 @@ +{ + "MD041": false +} diff --git a/.continue/rules/ansible.md b/.continue/rules/ansible.md new file mode 100644 index 0000000..4833106 --- /dev/null +++ b/.continue/rules/ansible.md @@ -0,0 +1,127 @@ +--- +name: Ansible Best Practices +description: Ansible best practices and conventions +alwaysApply: false +globs: + - "**/*.yml" + - "**/*.yaml" +--- + +You are an expert Ansible automation engineer. + +When working with Ansible content, always follow these rules: + +## General + +- Prefer **idempotent** solutions; tasks must be safe to run multiple times. +- Use **Ansible built-in modules** instead of shell or command whenever possible. +- Do not assume root access; use `become: true` only when required. +- Avoid hard-coded values; prefer variables, defaults, and group/host vars. +- Use clear, descriptive task names. +- Ensure all YAML is valid, properly indented, and ansible-lint compliant. +- Favor clarity and maintainability over cleverness. +- Add README files to complex directories. +- Document complex algorithms and business rules. +- Maintain up-to-date dependencies list. + +## Security Hardening + +- **Never embed secrets** directly in playbooks, roles, or templates. +- Use **Ansible Vault**, external secret managers, or injected variables for secrets. +- Mark sensitive tasks with: + + ```yaml + no_log: true + ``` + +- Avoid leaking secrets via debug, register, or error messages. +- Use least privilege: + - Avoid running entire plays as root. + - Scope become to individual tasks where possible. +- Set secure file permissions explicitly: + + ```yaml + mode: "0640" + owner: root + group: root + ``` + +- Validate downloaded files using checksums. +- Avoid ignore_errors for security-sensitive operations. +- Do not disable SSL/TLS validation unless explicitly required and documented. +- Prefer validate_certs: true for network modules. +- Assume hosts may be compromisedβ€”do not trust remote state blindly. + +## Playbooks + +- Use `hosts`, `gather_facts`, and `become` explicitly. +- Keep playbooks minimal; delegate logic to roles. +- Apply tags consistently for safe partial execution. +- Use serial for rolling updates to reduce blast radius. +- Avoid large monolithic plays. + +## Roles + +- Follow the standard role structure: + (`tasks/`, `handlers/`, `defaults/`, `vars/`, `templates/`, `files/`). +- Put overridable values in `defaults/main.yml`. +- Put non-overridable or internal values in `vars/main.yml`. +- Namespace all role variables (role_name_variable). +- Use meta/main.yml to define role dependencies. +- Use handlers only when a change requires a follow-up action. + +## Tasks + +- Always name tasks clearly and descriptively. +- Use `state: present/absent/latest` explicitly. +- Register variables only when they are actually used. +- Use `changed_when` and `failed_when` to ensure correct task status. +- Avoid `ignore_errors` unless absolutely necessary. +- Avoid shell unless absolutely unavoidable; document why if used. +- Prefer creates and removes when using command-like tasks. +- Avoid unnecessary loops; simplify logic where possible. + +## Variables & Templates + +- Use snake_case for variable names. +- Quote variables in YAML to prevent parsing issues. +- Namespace role variables (e.g., `nginx_port`, not `port`). +- Avoid complex logic in templatesβ€”use when instead. +- Use Jinja2 filters safely and defensively (default, bool, int). +- Do not reference undefined variables without defaults. + +## Conditionals & Loops + +- Use when for conditionals. +- Prefer `loop` over deprecated `with_*`. +- Use `ansible_facts` instead of shell commands for system data. +- Avoid deeply nested conditionals. + +## Error Handling & Validation + +- Fail fast on critical errors. +- Use assert to validate assumptions. +- Use check_mode compatibility whenever possible. +- Ensure tasks behave correctly in --diff and --check. + +## Linting & Compatibility + +- Code must comply with ansible-lint. +- Write code compatible with recent Ansible versions. +- Avoid deprecated modules and syntax. +- Do not rely on undefined behavior or undocumented features. + +## Performance & Reliability (Tips & Tricks) + +- Use gather_facts: false if facts are not needed. +- Use run_once and delegate_to when appropriate. +- Cache facts when operating at scale. +- Avoid repeated expensive operations. +- Prefer block for grouping related tasks and error handling. + +## Output Expectations + +- Generated YAML must be valid and properly indented. +- Provide minimal but sufficient comments when clarity is needed. +- Do not include explanations unless explicitly requested. +- Assume production usage and security-sensitive environments. diff --git a/.continue/rules/repo-readme.md b/.continue/rules/repo-readme.md new file mode 100644 index 0000000..139f3ac --- /dev/null +++ b/.continue/rules/repo-readme.md @@ -0,0 +1,159 @@ +--- +name: Project README Standards +globs: "**/README.md" +alwaysApply: false +description: Guidelines for creating comprehensive project README files +tags: + - readme + - documentation + - markdown + - project-setup + - best-practices +--- + +You are an expert in: + +- technical documentation +- open source best practices +- developer experience. + +## README Structure + +A well-structured README should include these sections in order: + +1. Project Title and Description +2. Badges (build status, version, license) +3. Key Features +4. Screenshots/Demo (if applicable) +5. Quick Start +6. Installation +7. Usage Examples +8. API Reference (or link to docs) +9. Configuration +10. Contributing +11. License + +## Essential Sections + +### Project Header + +```markdown +# Project Name + +> One-line description of what this project does + +[![Build Status](https://img.shields.io/github/actions/workflow/status/user/repo/ci.yml)](https://github.com/user/repo/actions) +[![npm version](https://img.shields.io/npm/v/package-name)](https://www.npmjs.com/package/package-name) +[![License](https://img.shields.io/github/license/user/repo)](LICENSE) + +Brief paragraph explaining the project's purpose, main features, +and why someone would want to use it. +``` + +### Quick Start + +```markdown +## Quick Start + +Get up and running in less than 5 minutes: + +\`\`\`bash +npm install package-name +npm run dev +\`\`\` + +Visit http://localhost:3000 to see the application. +``` + +### Installation + +```markdown +## Installation + +### Prerequisites + +- Node.js 18+ +- PostgreSQL 14+ +- Redis 6.2+ + +### Install from npm + +\`\`\`bash +npm install package-name +\`\`\` + +### Install from source + +\`\`\`bash +git clone https://github.com/user/repo.git +cd repo +npm install +npm run build +\`\`\` +``` + +### Usage Examples + +```markdown +## Usage + +### Basic Example + +\`\`\`javascript +import { Widget } from 'package-name'; + +const widget = new Widget({ +apiKey: 'your-api-key', +theme: 'dark' +}); + +widget.render('#app'); +\`\`\` + +### Advanced Example + +\`\`\`javascript +// Custom configuration with error handling +const widget = new Widget({ +apiKey: process.env.API_KEY, +theme: 'dark', +onError: (error) => { +console.error('Widget error:', error); +} +}); + +// Add custom event handlers +widget.on('ready', () => { +console.log('Widget is ready'); +}); + +widget.render('#app'); +\`\`\` +``` + +## Best Practices + +- Keep the README focused and concise +- Use clear, simple language +- Include code examples that actually work +- Add visuals when they help understanding +- Link to more detailed documentation +- Keep examples up-to-date with the code +- Test your installation instructions regularly + +## Common Mistakes to Avoid + +- Don't assume reader knowledge +- Don't skip the Quick Start section +- Don't use jargon without explanation +- Don't forget to update version numbers +- Don't include sensitive information + +## Formatting Tips + +- Use consistent heading levels +- Include a table of contents for long READMEs +- Use code blocks with language highlighting +- Add alt text to images +- Use tables for comparing options +- Include emoji sparingly and purposefully diff --git a/.gitea/workflows/AiReviewPR.yaml b/.gitea/workflows/AiReviewPR.yaml new file mode 100644 index 0000000..0eee976 --- /dev/null +++ b/.gitea/workflows/AiReviewPR.yaml @@ -0,0 +1,42 @@ +--- +# https://github.com/kekxv/AiReviewPR +name: ai-reviews + +on: + pull_request: + types: [opened, synchronize] + +jobs: + review: + name: Review PR + runs-on: ubuntu-latest + + steps: + + - name: Check OLLAMA host + run: | + curl -v ${{ 'http://192.168.2.233:11435' || vars.OLLAMA_HOST }} || exit 1 + + - name: Checkout code + uses: actions/checkout@v6 + with: + # Number of commits to fetch. 0 indicates all history for all + # branches and tags. + # Default: 1 + fetch-depth: 0 + # The base URL for the GitHub instance that you are trying to clone + # from, will use environment defaults to fetch from the same instance + # that the workflow is running from unless specified. + # Example URLs are https://github.com or + # https://my-ghes-server.example.com + github-server-url: ${{ vars.GIT_SERVER_URL }} + + - name: Review code + uses: kekxv/AiReviewPR@v0.1.2 + with: + model: ${{ vars.OLLAMA_MODEL }} + host: ${{ 'http://192.168.2.233:11435' || vars.OLLAMA_HOST }} + # host: ${{ vars.OLLAMA_HOST }} + # ai_token: ${{ secrets.AI_TOKEN }} + REVIEW_PULL_REQUEST: true + LANGUAGE: English diff --git a/.gitea/workflows/ansible-lint.yml b/.gitea/workflows/ansible-lint.yml new file mode 100644 index 0000000..f1fd650 --- /dev/null +++ b/.gitea/workflows/ansible-lint.yml @@ -0,0 +1,34 @@ +--- +# .gitea/workflows/ansible-lint.yml +name: ansible-lint + +on: [pull_request, issues, push] + +jobs: + build: + name: Ansible Lint + # Naming the build is important to use it as a status check + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + github-server-url: ${{ vars.GIT_SERVER_URL }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + - name: Install ansible-lint + run: | + python -m pip install --upgrade pip + pip install ansible ansible-lint yamllint + + - name: Run yamllint + run: | + yamllint . + + - name: Run ansible-lint + run: | + ansible-lint diff --git a/.gitea/workflows/gitleaks.yml b/.gitea/workflows/gitleaks.yml new file mode 100644 index 0000000..56f1ac1 --- /dev/null +++ b/.gitea/workflows/gitleaks.yml @@ -0,0 +1,35 @@ +--- +name: Gitleaks Scan + +on: + push: + pull_request: + +jobs: + gitleaks: + runs-on: ubuntu-latest + + steps: + - name: Install Gitleaks + run: | + curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz \ + | tar -xz + sudo mv gitleaks /usr/local/bin/ + + - name: Checkout code + uses: actions/checkout@v6 + with: + github-server-url: ${{ vars.GIT_SERVER_URL }} + + - name: Run Gitleaks + run: | + gitleaks dir . \ + --redact=10 \ + --verbose \ + --exit-code 1 + # gitleaks detect \ + # --source . \ + # --no-git \ + # --redact=20 \ + # --verbose \ + # --exit-code 1 diff --git a/.gitea/workflows/markdown-lint.yml b/.gitea/workflows/markdown-lint.yml new file mode 100644 index 0000000..80a6846 --- /dev/null +++ b/.gitea/workflows/markdown-lint.yml @@ -0,0 +1,24 @@ +--- +# .gitea/workflows/markdown-lint.yml +name: Markdown Lint + +on: [pull_request, issues, push] + +jobs: + build: + name: markdown-lint + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + github-server-url: ${{ vars.GIT_SERVER_URL }} + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Run markdownlint + run: npx markdownlint-cli2 "**/*.md" "#node_modules" diff --git a/.gitea/workflows/stale.yml b/.gitea/workflows/stale.yml new file mode 100644 index 0000000..3007d7a --- /dev/null +++ b/.gitea/workflows/stale.yml @@ -0,0 +1,72 @@ +--- +# This workflow warns and then closes issues and PRs that have +# had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '21 3 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs + + steps: + # - name: Checkout code + # uses: actions/checkout@v4 + # with: + # # Number of commits to fetch. 0 indicates all history for all branches + # # and tags. + # # Default: 1 + # fetch-depth: 0 + # # The base URL for the GitHub instance that you are trying to clone from, + # # will use environment defaults to fetch from the same instance that the + # # workflow is running from unless specified. + # # Example URLs are https://github.com or + # # https://my-ghes-server.example.com + # github-server-url: ${{ vars.GIT_SERVER_URL }} + + # The 90 day stale policy + # Used for: + # - Issues & PRs + # - No PRs marked as no-stale or pinned + # - No issues marked as no-stale, help-wanted or pinned + - name: 90 days stale issues & PRs policy + uses: actions/stale@v9.1.0 + with: + # repo-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + days-before-stale: 90 + days-before-close: 7 + operations-per-run: 150 + remove-stale-when-updated: true + stale-issue-label: "stale" + exempt-issue-labels: "no-stale,help-wanted,pinned,enhancement" + stale-issue-message: > + There hasn't been any activity on this issue recently. To keep our + backlog manageable we have to clean old issues, as many of them have + already been resolved with the latest updates. + + Please make sure to update to the latest version and check if that + solves the issue. Let us know if that works for you by adding a + comment πŸ‘ + + This issue has now been marked as stale and will be closed if no + further activity occurs. Thank you for your contributions. + + stale-pr-label: "stale" + exempt-pr-labels: "no-stale,pinned" + stale-pr-message: > + There hasn't been any activity on this pull request recently. This + pull request has been automatically marked as stale because of that + and will be closed if no further activity occurs within 7 days. + + Thank you for your contributions. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4075c27 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +--- +# Ansible specific (optional - ignore temporary output or secrets) +*.retry +*.vault +*.vault_pass +*.secret +*.log + +# VSCode settings +.vscode/ +*.code-workspace +.trunk/ + +# Windows system files +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ +*.lnk + +# Backup files +*~ +*.bak +*.swp +*.swo +*.tmp + +# Python +__pycache__/ +*.py[cod] +*$py.class + +# Environment files +.env +.env.local +.env.development.local +.env.test +.env.production +.env.production.local diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 0000000..587e4e3 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,2 @@ +# ignore files completely +.continue/rules/**/*.md diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..46f6f50 --- /dev/null +++ b/.yamllint @@ -0,0 +1,23 @@ +--- +# This is my first, very own configuration file for yamllint! +# It extends the default conf by adjusting some options. + +extends: default + +rules: + comments-indentation: disable # don't bother me with this rule + truthy: + allowed-values: ['true', 'false', 'yes', 'no', 'on', 'off'] + comments: + min-spaces-from-content: 1 + + braces: + max-spaces-inside: 1 + + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + + line-length: + max: 120 + allow-non-breakable-words: true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14529e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright Β© 2026 joseraj + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the β€œSoftware”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a044a1a --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# ansible-role-template + +> A reusable Ansible role template for deploying and managing +> applications/services with security best practices. + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![Ansible Version](https://img.shields.io/badge/Ansible-2.12+-blue)](https://www.ansible.com/) +[![Platforms](https://img.shields.io/badge/Platforms-Debian-blue)](https://www.debian.org/) + +## πŸ“Œ Key Features + +βœ… **Idempotent** - Safe to run multiple times +βœ… **Security Hardened** - Follows Ansible security best practices +βœ… **Modular** - Clear separation of concerns +βœ… **Documented** - Comprehensive README and variable documentation +βœ… **Tested** - Includes example playbook for validation + +## πŸ“‚ Directory Structure + +```text +ansible-role-template/ +β”œβ”€β”€ README.md # This file +β”œβ”€β”€ defaults/ # Default role variables +β”‚ └── main.yml +β”œβ”€β”€ handlers/ # Role handlers +β”‚ └── main.yml +β”œβ”€β”€ files/ # Static files to deploy +β”œβ”€β”€ meta/ # Role metadata +β”‚ └── main.yml +β”œβ”€β”€ tasks/ # Main role tasks +β”‚ β”œβ”€β”€ backup.yml # Backup-related tasks +β”‚ β”œβ”€β”€ main.yml # Core tasks +β”‚ └── monitoring.yml # Monitoring setup +β”œβ”€β”€ templates/ # Jinja2 templates +└── vars/ # Non-overridable variables + └── main.yml +``` + +## πŸ› οΈ Development + +### Prerequisites + +- Ansible 2.12+ +- Python 3.8+ + +## πŸ”§ Configuration + +## Default Variables (`defaults/main.yml`) + +```yaml +# Default values for role variables +role_template_service_name: "default_service" +role_template_service_port: 80 +role_template_backup_enabled: false +role_template_service_backup_dir: "/var/backups/{{ role_template_service_name }}" +role_template_monitoring_enabled: false +``` + +## Example usage + +### Example Playbook (`example-playbook.yml`) + +```yaml +--- +- hosts: all + roles: + - role: yourorg.ansible-role-template + vars: + role_template_service_name: "myapp" + role_template_service_port: 8080 +``` + +### 3. Run the Playbook + +```bash +ansible-playbook -i inventory.ini example-playbook.yml +``` + +## πŸ“„ License + +This project is licensed under the MIT License +See the [LICENSE](LICENSE) file for details. + +## TODO + +☐ refactor +☐ debug +☐ docs diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..3595bb4 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,38 @@ +--- +# ansible-role-template/defaults/main.yml +# Default values for role variables +# =================================== + +# Service configuration +role_template_service_name: "default_service" +role_template_service_port: 80 + +# User and permissions +role_template_service_user: "nobody" +role_template_service_group: "nogroup" +role_template_service_uid: 65534 +role_template_service_gid: 65534 +role_template_service_mode: "0755" + +# Directory structure +role_template_service_dir: "/opt/{{ role_template_service_name }}" +role_template_service_backup_dir: "/var/backups/{{ role_template_service_name }}" + +# Systemd configuration (if applicable) +role_template_systemd_enabled: false +role_template_systemd_override_dir: "/etc/systemd/system/{{ role_template_service_name }}.d" + +# Security +role_template_validate_certs: true +role_template_ssl_ciphers: "HIGH:!aNULL:!MD5" +role_template_ssl_protocols: "TLSv1.2:TLSv1.3" + +# Backup +role_template_backup_enabled: false +role_template_backup_retention: 7 +role_template_backup_archive_path: "/var/backups/{{ role_template_service_name }}/archive" + +# Monitoring (optional) +role_template_monitoring_enabled: false +role_template_monitoring_interval: 60 +role_template_monitoring_notify_email: "admin@example.com" diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..9d6ad3b --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,45 @@ +--- +# ansible-role-template/handlers/main.yml +# Handlers for role +# ================== + +# Service handlers +- name: Restart {{ role_template_service_name }} + ansible.builtin.service: + name: "{{ role_template_service_name }}" + state: restarted + listen: "restart {{ role_template_service_name }}" + when: role_template_service_enabled + +- name: Reload systemd + ansible.builtin.systemd: + daemon_reload: true + listen: "restart {{ role_template_service_name }}" + when: role_template_systemd_enabled + +# Configuration handlers +- name: Reload nginx + ansible.builtin.service: + name: nginx + state: reloaded + listen: "reload nginx" + when: "'nginx' in role_template_service_name" + +# Backup handlers +- name: Rotate logs + ansible.builtin.command: logger -p local0.info "Rotating logs for {{ role_template_service_name }}" + changed_when: true + listen: "rotate logs" + +# Monitoring handlers +- name: Notify monitoring + ansible.builtin.uri: + url: "{{ role_template_monitoring_webhook_url }}" + method: POST + body_format: json + body: "{{ lookup('template', 'monitoring_notification.json.j2') }}" + status_code: 200 + delegate_to: localhost + run_once: true + listen: "notify monitoring" + when: role_template_monitoring_enabled diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..58608a5 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,20 @@ +--- +# ansible-role-template/meta/main.yml +galaxy_info: + role_name: ansible_role_template # if absent directory name hosting role is used instead + namespace: joseraj # if absent, author is used instead + author: joseraj + description: > + A reusable Ansible role template for deploying and managing applications/services + with security best practices, modularity, and idempotency. + license: MIT + min_ansible_version: "2.12" + platforms: + - name: Debian + versions: + - buster + - bullseye + - bookworm + - trixie + galaxy_tags: + - automation diff --git a/tasks/backup.yml b/tasks/backup.yml new file mode 100644 index 0000000..04998aa --- /dev/null +++ b/tasks/backup.yml @@ -0,0 +1,28 @@ +--- +# # ansible-role-template/tasks/backup.yml +# Backup tasks +# ============ + +- name: backup | Ensure backup directory exists + ansible.builtin.file: + path: "{{ role_template_backup_dir }}" + state: directory + mode: "0750" + owner: root + group: root + +- name: backup | Create backup script + ansible.builtin.template: + src: templates/backup_script.sh.j2 + dest: /usr/local/bin/backup_{{ role_template_service_name }} + mode: "0755" + owner: root + group: root + +- name: backup | Create cron job for backups + ansible.builtin.cron: + name: "Backup {{ role_template_service_name }}" + user: root + minute: "0" + hour: "3" + job: "/usr/local/bin/backup_{{ role_template_service_name }}" diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..4742445 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,14 @@ +--- +# ansible-role-template/tasks/main.yml +# Main tasks for role +# =================== + +# Import backup tasks +- name: Import backup tasks + ansible.builtin.import_tasks: backup.yml + when: role_template_backup_enabled + +# Import monitoring tasks +- name: Import monitoring tasks + ansible.builtin.import_tasks: monitoring.yml + when: role_template_monitoring_enabled diff --git a/tasks/monitoring.yml b/tasks/monitoring.yml new file mode 100644 index 0000000..5c524d0 --- /dev/null +++ b/tasks/monitoring.yml @@ -0,0 +1,22 @@ +--- +# # ansible-role-template/tasks/monitoring.yml +# Monitoring tasks +# ================ + +- name: monitoring | Ensure monitoring directory exists + ansible.builtin.file: + path: "/var/log/monitoring/{{ role_template_service_name }}" + state: directory + mode: "0755" + +- name: monitoring | Create monitoring configuration + ansible.builtin.template: + src: templates/monitoring_config.yml.j2 + dest: "/etc/monitoring/{{ role_template_service_name }}.yml" + mode: "0640" + +- name: monitoring | Ensure monitoring service is running + ansible.builtin.service: + name: monitoring-service + state: started + enabled: yes diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..075a9a6 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,2 @@ +--- +# ansible-role-template/vars/main.yml