Initial commit
This commit is contained in:
31
.ansible-lint
Normal file
31
.ansible-lint
Normal file
@@ -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"
|
||||||
3
.continue/.markdownlint.json
Normal file
3
.continue/.markdownlint.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"MD041": false
|
||||||
|
}
|
||||||
127
.continue/rules/ansible.md
Normal file
127
.continue/rules/ansible.md
Normal file
@@ -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.
|
||||||
159
.continue/rules/repo-readme.md
Normal file
159
.continue/rules/repo-readme.md
Normal file
@@ -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
|
||||||
|
|
||||||
|
[](https://github.com/user/repo/actions)
|
||||||
|
[](https://www.npmjs.com/package/package-name)
|
||||||
|
[](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
|
||||||
42
.gitea/workflows/AiReviewPR.yaml
Normal file
42
.gitea/workflows/AiReviewPR.yaml
Normal file
@@ -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
|
||||||
34
.gitea/workflows/ansible-lint.yml
Normal file
34
.gitea/workflows/ansible-lint.yml
Normal file
@@ -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
|
||||||
35
.gitea/workflows/gitleaks.yml
Normal file
35
.gitea/workflows/gitleaks.yml
Normal file
@@ -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
|
||||||
24
.gitea/workflows/markdown-lint.yml
Normal file
24
.gitea/workflows/markdown-lint.yml
Normal file
@@ -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"
|
||||||
72
.gitea/workflows/stale.yml
Normal file
72
.gitea/workflows/stale.yml
Normal file
@@ -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.
|
||||||
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -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
|
||||||
2
.markdownlintignore
Normal file
2
.markdownlintignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# ignore files completely
|
||||||
|
.continue/rules/**/*.md
|
||||||
23
.yamllint
Normal file
23
.yamllint
Normal file
@@ -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
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -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.
|
||||||
88
README.md
Normal file
88
README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# ansible-role-template
|
||||||
|
|
||||||
|
> A reusable Ansible role template for deploying and managing
|
||||||
|
> applications/services with security best practices.
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.ansible.com/)
|
||||||
|
[](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
|
||||||
38
defaults/main.yml
Normal file
38
defaults/main.yml
Normal file
@@ -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"
|
||||||
45
handlers/main.yml
Normal file
45
handlers/main.yml
Normal file
@@ -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
|
||||||
20
meta/main.yml
Normal file
20
meta/main.yml
Normal file
@@ -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
|
||||||
28
tasks/backup.yml
Normal file
28
tasks/backup.yml
Normal file
@@ -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 }}"
|
||||||
14
tasks/main.yml
Normal file
14
tasks/main.yml
Normal file
@@ -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
|
||||||
22
tasks/monitoring.yml
Normal file
22
tasks/monitoring.yml
Normal file
@@ -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
|
||||||
2
vars/main.yml
Normal file
2
vars/main.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
# ansible-role-template/vars/main.yml
|
||||||
Reference in New Issue
Block a user