Skip to content

Feat/ansible perf#1917

Merged
m-brando merged 15 commits into
masterfrom
feat/ansible-perf
Jan 9, 2026
Merged

Feat/ansible perf#1917
m-brando merged 15 commits into
masterfrom
feat/ansible-perf

Conversation

@m-brando

@m-brando m-brando commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

This PR addresses issue #1831.

Improvements:

  • Removed unnecessary fact gathering.
  • Replaced loops with blockinfile where applicable.
  • Introduced async with poll: 0 to run non-blocking tasks, combined with later state checks using async_status.
  • Reorganized tasks and play structure for more efficient execution.

overall speedup of execution is ~20%

The WireGuard playbook remains the slowest part of the workflow. It could be parallelized further, but doing so would require synchronizing host facts, particularly the public key values used when rendering the WireGuard template in this task:

- name: Template wireguard config file to a node
  ansible.builtin.template:
    src: "{{ 'wg-static.conf.j2' if 'static' in group_names else 'wg-dynamic.conf.j2' }}"
    dest: "{{ wg_conf_dir.path }}/wg0.conf"

Summary by CodeRabbit

  • Performance Improvements

    • More background package operations and reduced fact gathering to speed playbook runs.
  • Stability & Reliability

    • Consolidated kernel, sysctl and systemd limits with a single reload for consistent node limits.
    • Centralized proxy environment management via block updates and standardized drop-in dirs.
    • Safer WireGuard key handling and idempotent interface/IP management; unattended-upgrades now masked.
  • Refactor

    • Merged and simplified related tasks for cleaner, more consistent playbooks.
  • Chores

    • Updated ansibler image tag.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Consolidates and generalizes multiple Ansible playbooks: combines multi-package apt installs into single async tasks with async_status checks; consolidates sysctl and limit files into looped/blocked tasks and a single sysctl reload; centralizes proxy env management with blockinfile and adds strategy/gather_facts adjustments; refactors WireGuard to use slurp/base64 decoding and more idempotent checks; updates an image tag.

Changes

Cohort / File(s) Summary
Async package installs & uninstall
services/ansibler/server/ansible-playbooks/longhorn-req.yml, services/ansibler/templates/uninstall-nginx.goyml
Merge separate package installs into one apt task using a package list run with async/poll: 0 and register/async_status polling; add async/poll: 0 to apt uninstall task.
Node limits & sysctl consolidation
services/ansibler/server/ansible-playbooks/node-limits.yml
Replace multiple per-setting sysctl and separate lineinfile tasks with looped lineinfile tasks for PAM/systemd and a single blockinfile writing consolidated kernel parameters to /etc/sysctl.d/99-claudie-custom.conf; add sysctl --system reload.
Proxy envs & drop-in dirs
services/ansibler/server/ansible-playbooks/proxy/populate-proxy-envs.yml, services/ansibler/server/ansible-playbooks/proxy/remove-proxy-envs.yml, services/ansibler/server/ansible-playbooks/proxy/commit-proxy-envs-changes.yml
Set strategy: free; create apt and systemd drop-in directories via loops; manage proxy variables in /etc/environment with blockinfile (marker-based addition/removal); change plays to gather_facts: false.
WireGuard tasks & templates
services/ansibler/server/ansible-playbooks/wireguard.yml, .../wireguard/tasks/configure.yml, .../wireguard/tasks/kill_unattended_upgrades.yml, .../wireguard/tasks/main.yml, .../wireguard/templates/wg-dynamic.conf.j2, .../wireguard/templates/wg-static.conf.j2
Remove explicit pre-task fact gathering; make key generation idempotent (creates), read keys with slurp and use `*.content
Ansible fact adjustments
services/ansibler/templates/deploy-envoy.goyml, services/ansibler/server/ansible-playbooks/proxy/commit-proxy-envs-changes.yml, services/ansibler/server/ansible-playbooks/wireguard.yml
Normalize gather_facts usage: change yes/no forms to true/false and in one play add gather_subset for distribution facts.
Kustomize manifest
manifests/claudie/kustomization.yaml
Update ghcr.io/berops/claudie/ansibler image newTag to a new value.

Possibly related PRs

Suggested labels

test-set-ordinary, test-set-proxy

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Feat/ansible perf' is vague and uses non-descriptive terms that don't clearly convey what the changeset accomplishes. Consider a more specific title like 'Optimize Ansible playbooks for performance' or 'Improve Ansible execution speed with async tasks and fact gathering reduction'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00e7cbe and 7f8597c.

📒 Files selected for processing (1)
  • manifests/claudie/kustomization.yaml

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
services/ansibler/server/ansible-playbooks/node-limits.yml (1)

52-53: Improve idempotency handling for sysctl --system.

Using the command module without idempotency guards will likely report the task as changed every run, even when no actual sysctl state changes occur. Since the configuration is already written to /etc/sysctl.d/99-claudie-custom.conf, consider marking this task as not changed:

  - name: Reload sysctl at once with new settings
    ansible.builtin.command: sysctl --system
+   changed_when: false

Alternatively, make the task conditional to run only when the config file changes (using a handler triggered by the blockinfile task) for finer control.

services/ansibler/server/ansible-playbooks/proxy/populate-proxy-envs.yml (1)

37-37: Minor inconsistency: use create: true instead of create: yes.

For consistency with line 3 of deploy-envoy.goyml (which changed yes to true), use the boolean true instead of yes.

Apply this diff:

-        create: yes
+        create: true
services/ansibler/templates/uninstall-nginx.goyml (1)

22-23: Add async_status check to verify completion.

The async apt task runs in the background with poll: 0, but there's no subsequent async_status check to verify it completes. This is inconsistent with the PR's stated approach of using "async with poll: 0 to run non-blocking tasks, with subsequent state checks using async_status."

While the impact is lower for an uninstall playbook with ignore_errors: true, completing the async pattern ensures consistent behavior and confirms the operation finished before the playbook exits.

Apply this diff to add the async_status check:

     - name: Uninstall nginx
       apt:
         name:
           - nginx
           - nginx-common
           - libnginx-mod-stream
         state: absent
         purge: yes
         autoremove: yes
+      register: async_job
       async: 600
       poll: 0
       ignore_errors: true
 
     - name: Remove NGINX configuration directory
       file:
         path: /etc/nginx
         state: absent
       ignore_errors: true
 
     - name: Remove NGINX log directory
       file:
         path: /var/log/nginx
         state: absent
       ignore_errors: true
 
     - name: Remove NGINX cache directory
       file:
         path: /var/cache/nginx
         state: absent
       ignore_errors: true
+
+    - name: Check nginx uninstall completion
+      async_status:
+        jid: "{{ async_job.ansible_job_id }}"
+      register: result
+      until: result.finished
+      retries: 30
+      delay: 5
+      ignore_errors: true
services/ansibler/server/ansible-playbooks/wireguard/tasks/kill_unattended_upgrades.yml (1)

3-9: Optional: Simplify the masking logic.

When masking a service, the state: stopped and enabled: false parameters are redundant since masking prevents the service from being started by any means. The task could be simplified to only mask the service.

Consider this simplified approach:

-- name: Mask unattended-upgrades service if it exists
-  ansible.builtin.systemd:
-    name: unattended-upgrades.service
-    state: stopped
-    enabled: false
-    masked: true
-  failed_when: false
+- name: Mask unattended-upgrades service if it exists
+  ansible.builtin.systemd:
+    name: unattended-upgrades.service
+    masked: true
+  failed_when: false
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 717ef20 and 20b732e.

📒 Files selected for processing (13)
  • services/ansibler/server/ansible-playbooks/longhorn-req.yml (3 hunks)
  • services/ansibler/server/ansible-playbooks/node-limits.yml (1 hunks)
  • services/ansibler/server/ansible-playbooks/proxy/commit-proxy-envs-changes.yml (2 hunks)
  • services/ansibler/server/ansible-playbooks/proxy/populate-proxy-envs.yml (2 hunks)
  • services/ansibler/server/ansible-playbooks/proxy/remove-proxy-envs.yml (1 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard.yml (0 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/configure.yml (2 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/kill_unattended_upgrades.yml (1 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/main.yml (1 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-dynamic.conf.j2 (1 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 (1 hunks)
  • services/ansibler/templates/deploy-envoy.goyml (1 hunks)
  • services/ansibler/templates/uninstall-nginx.goyml (1 hunks)
💤 Files with no reviewable changes (1)
  • services/ansibler/server/ansible-playbooks/wireguard.yml
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/deploy-envoy.goyml:14-16
Timestamp: 2025-06-10T08:11:39.185Z
Learning: In Ansible playbook templates within the services/ansibler/templates/ directory, relative paths for include_tasks are intentional and should not be changed to use playbook_dir variable, as the file structure is replicated inside containers to match these relative paths.
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration, the placeholder `wireguard_private_ip_replace_me` in `services/ansibler/templates/envoy.goyml` is intentionally left as a literal string. The `deploy-envoy.goyml` Ansible playbook contains a task that uses `ansible.builtin.replace` to replace this placeholder with `{{ private_ip }}` (the actual private IP of each node) during runtime execution. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs node-specific replacements.
📚 Learning: 2025-06-10T08:08:21.087Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration, the placeholder `wireguard_private_ip_replace_me` in `services/ansibler/templates/envoy.goyml` is intentionally left as a literal string. The `deploy-envoy.goyml` Ansible playbook contains a task that uses `ansible.builtin.replace` to replace this placeholder with `{{ private_ip }}` (the actual private IP of each node) during runtime execution. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs node-specific replacements.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/tasks/configure.yml
  • services/ansibler/templates/deploy-envoy.goyml
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-dynamic.conf.j2
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
📚 Learning: 2025-06-10T08:08:21.087Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration templates, placeholders like `wireguard_private_ip_replace_me` are intentionally left as literal strings to be replaced by Ansible playbooks during runtime execution, not by Go template variables. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs string replacement with actual runtime values.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/tasks/configure.yml
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-dynamic.conf.j2
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
📚 Learning: 2025-06-10T08:11:39.185Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/deploy-envoy.goyml:14-16
Timestamp: 2025-06-10T08:11:39.185Z
Learning: In Ansible playbook templates within the services/ansibler/templates/ directory, relative paths for include_tasks are intentional and should not be changed to use playbook_dir variable, as the file structure is replicated inside containers to match these relative paths.

Applied to files:

  • services/ansibler/server/ansible-playbooks/proxy/populate-proxy-envs.yml
  • services/ansibler/server/ansible-playbooks/node-limits.yml
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/main.yml
📚 Learning: 2025-06-10T08:22:31.991Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/server/domain/usecases/setup_loadbalancers.go:112-118
Timestamp: 2025-06-10T08:22:31.991Z
Learning: In services/ansibler/server/domain/usecases/setup_loadbalancers.go, the uninstallNginx function comment about "errors will be ignored" refers specifically to the Ansible playbook tasks having ignore_errors directives for idempotency, not the Go function ignoring template generation or execution errors. The Go function should still return errors for template loading/generation failures and overall Ansible execution issues.

Applied to files:

  • services/ansibler/templates/uninstall-nginx.goyml
🔇 Additional comments (19)
services/ansibler/server/ansible-playbooks/node-limits.yml (3)

13-20: Good consolidation using loop for PAM limits.

The refactoring from separate tasks to a single looped lineinfile task reduces redundancy and improves playbook efficiency, aligning with the PR objectives for performance optimization.


22-29: Good consolidation using loop for systemd limits.

Consolidating the two systemd config files into a single looped task is effective and maintains clarity. This reduces playbook execution overhead.


35-50: Solid blockinfile consolidation for kernel parameters.

Replacing multiple individual sysctl or lineinfile tasks with a single blockinfile operation is an efficient approach. The explicit ownership, group, and mode settings (root/root/0644) are appropriate for a system config file, and create: yes ensures the file exists.

services/ansibler/templates/deploy-envoy.goyml (1)

3-6: LGTM! Good performance optimization.

Limiting fact gathering to only the required distribution facts reduces overhead while ensuring the necessary ansible_facts['distribution_release'] and ansible_facts['distribution'] are available for lines 28-29.

services/ansibler/server/ansible-playbooks/proxy/commit-proxy-envs-changes.yml (2)

47-47: LGTM! Appropriate fact gathering optimization.

The tasks in this play don't require Ansible facts, so disabling fact gathering improves performance.


72-72: LGTM! Appropriate fact gathering optimization.

The tasks in this play don't require Ansible facts, so disabling fact gathering improves performance.

services/ansibler/server/ansible-playbooks/proxy/remove-proxy-envs.yml (1)

18-22: LGTM! Cleaner block-based removal approach.

The blockinfile approach with matching marker (verified against populate-proxy-envs.yml line 38) is more maintainable than per-key lineinfile deletions.

services/ansibler/server/ansible-playbooks/proxy/populate-proxy-envs.yml (3)

2-2: LGTM! Good parallelization strategy.

The strategy: free allows each host to execute tasks independently without waiting, which is appropriate for proxy setup since there are no cross-host dependencies in this playbook.


6-15: LGTM! Cleaner task consolidation.

Using a loop to create multiple systemd drop-in directories is more maintainable than separate tasks. Note that /etc/apt/apt.conf.d/ is not explicitly created here, but it should exist by default on Debian/Ubuntu systems.


34-45: LGTM! Improved maintainability with blockinfile.

The blockinfile approach with a defined marker is more maintainable than managing individual proxy variables with lineinfile. This correctly coordinates with the removal logic in remove-proxy-envs.yml.

services/ansibler/server/ansible-playbooks/longhorn-req.yml (2)

15-26: Nice refactoring—consolidates package installation efficiently.

Combining both packages into a single async task improves efficiency and follows the async pattern correctly. The retries and delay on this task appropriately handle transient failures when starting the async job, while the separate async_status check handles failures during the actual package installation.


3-3: > Likely an incorrect or invalid review comment.

services/ansibler/server/ansible-playbooks/wireguard/templates/wg-dynamic.conf.j2 (1)

1-22: LGTM! Consistent migration to slurp-based key handling.

The template correctly migrates from stdout-based key handling to using slurp module with content | b64decode. All key references (PrivateKey, PublicKey comparisons, and peer PublicKey outputs) are consistently updated across both dynamic and static peer groups.

services/ansibler/server/ansible-playbooks/wireguard/tasks/configure.yml (6)

8-12: LGTM! Improved idempotency for key generation.

The addition of the creates parameter ensures the keypair is only generated when it doesn't exist, preventing unnecessary regeneration and improving idempotency. The umask 077 also ensures proper file permissions.


14-22: LGTM! Proper use of slurp module for reading keys.

Replacing shell cat commands with the ansible.builtin.slurp module is a best practice. The slurp module is idempotent, returns structured data, and aligns with the template changes that use content | b64decode for key handling.


24-32: LGTM! Cleaner interface existence check.

Using ansible.builtin.stat on /sys/class/net/wg0 is more reliable than parsing shell command output. The conditional logic correctly creates the interface only when it doesn't exist.


34-43: LGTM! Idempotent IP address assignment.

The task correctly checks for existing IP addresses before assignment, improving idempotency. The use of changed_when: false on the check is appropriate.

Note: The string match on line 43 (private_ip not in wg0_ip_info.stdout) assumes the IP format matches exactly. This should work correctly as long as private_ip is formatted consistently (e.g., "10.0.0.1" without CIDR notation).


58-60: LGTM! Modernized MTU setting command.

Replacing ifconfig with ip link set mtu is a good modernization. The ip command is the standard tool in modern Linux distributions.


61-70: LGTM! Improved DHCP config persistence with file creation.

Adding create: yes ensures /etc/dhcp/dhclient.conf exists before attempting to add the MTU configuration block. The insertbefore: "^request" pattern correctly targets the appropriate location in the dhclient configuration.

Comment thread services/ansibler/server/ansible-playbooks/longhorn-req.yml
Comment thread services/ansibler/server/ansible-playbooks/wireguard/tasks/main.yml Outdated
Comment thread services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 Outdated
Comment thread services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 Outdated

@Despire Despire left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think these changes are Ok, also address the comments, as you have some typos, mainly with wireguard

Comment thread services/ansibler/server/ansible-playbooks/longhorn-req.yml
Comment thread services/ansibler/server/ansible-playbooks/node-limits.yml
Matus Brandys added 3 commits December 12, 2025 08:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
services/ansibler/server/ansible-playbooks/longhorn-req.yml (1)

50-56: Async polling window now reasonably matches the async timeout (good improvement vs the earlier 10×5s wait).

🧹 Nitpick comments (3)
services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 (2)

6-14: Guard against missing key vars (async timing) and avoid repeated b64decode in loops.
If publickey / hostvars[host].publickey isn’t present yet, this template will error (or behave unexpectedly) during rendering—this seems plausible given the PR’s async/non-blocking changes and the note about needing host key synchronization. Consider precomputing local_public_key once and defaulting missing remote keys to '' to fail fast with a clearer message or safely skip.

 [Interface]
 Address = {{ private_ip }}/24
 PrivateKey = {{ privatekey.content | b64decode }}
 ListenPort = {{ wg_listen_port }}

+{% set local_public_key = (publickey.content | b64decode) %}
+
 {% for host in groups['dynamic'] %}
-{% if publickey.content | b64decode != hostvars[host].publickey.content | b64decode %}
+{% set remote_public_key = ((hostvars[host].publickey.content | default('')) | b64decode) %}
+{% if local_public_key != remote_public_key %}
 [Peer]
-PublicKey = {{ hostvars[host].publickey.content | b64decode }}
+PublicKey = {{ remote_public_key }}
 Endpoint = {{ hostvars[host].ansible_host }}:{{ wg_listen_port }}
 AllowedIps = {{ hostvars[host].private_ip }}/32
 PersistentKeepalive = 60
 {% endif %}
 {% endfor %}

 {% for host in groups['static'] %}
-{% if publickey.content | b64decode != hostvars[host].publickey.content | b64decode %}
+{% set remote_public_key = ((hostvars[host].publickey.content | default('')) | b64decode) %}
+{% if local_public_key != remote_public_key %}
 [Peer]
-PublicKey = {{ hostvars[host].publickey.content | b64decode}}
+PublicKey = {{ remote_public_key }}
 Endpoint = {{ hostvars[host].ansible_host }}:{{ wg_listen_port }}
 AllowedIps = {{ hostvars[host].private_ip }}/32
 {% endif %}
 {% endfor %}

Also applies to: 16-23


19-19: Minor: fix whitespace (b64decode }}) for consistency.

-PublicKey = {{ hostvars[host].publickey.content | b64decode}}
+PublicKey = {{ hostvars[host].publickey.content | b64decode }}
services/ansibler/server/ansible-playbooks/longhorn-req.yml (1)

15-27: Async apt install: consider adding cache_valid_time to avoid forced updates on every run.
update_cache: true can dominate runtime on repeated runs; if acceptable, prefer cache_valid_time: <seconds> for better performance while staying correct.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5cd677 and a322360.

📒 Files selected for processing (3)
  • services/ansibler/server/ansible-playbooks/longhorn-req.yml (3 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/main.yml (1 hunks)
  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/ansibler/server/ansible-playbooks/wireguard/tasks/main.yml
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration, the placeholder `wireguard_private_ip_replace_me` in `services/ansibler/templates/envoy.goyml` is intentionally left as a literal string. The `deploy-envoy.goyml` Ansible playbook contains a task that uses `ansible.builtin.replace` to replace this placeholder with `{{ private_ip }}` (the actual private IP of each node) during runtime execution. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs node-specific replacements.
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration templates, placeholders like `wireguard_private_ip_replace_me` are intentionally left as literal strings to be replaced by Ansible playbooks during runtime execution, not by Go template variables. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs string replacement with actual runtime values.
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/deploy-envoy.goyml:14-16
Timestamp: 2025-06-10T08:11:39.185Z
Learning: In Ansible playbook templates within the services/ansibler/templates/ directory, relative paths for include_tasks are intentional and should not be changed to use playbook_dir variable, as the file structure is replicated inside containers to match these relative paths.
📚 Learning: 2025-06-10T08:08:21.087Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration templates, placeholders like `wireguard_private_ip_replace_me` are intentionally left as literal strings to be replaced by Ansible playbooks during runtime execution, not by Go template variables. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs string replacement with actual runtime values.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
📚 Learning: 2025-06-10T08:08:21.087Z
Learnt from: Despire
Repo: berops/claudie PR: 1735
File: services/ansibler/templates/envoy.goyml:8-8
Timestamp: 2025-06-10T08:08:21.087Z
Learning: In Claudie's Envoy configuration, the placeholder `wireguard_private_ip_replace_me` in `services/ansibler/templates/envoy.goyml` is intentionally left as a literal string. The `deploy-envoy.goyml` Ansible playbook contains a task that uses `ansible.builtin.replace` to replace this placeholder with `{{ private_ip }}` (the actual private IP of each node) during runtime execution. This is a two-stage templating pattern where Go templates generate configs with placeholders, then Ansible performs node-specific replacements.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
📚 Learning: 2025-08-25T06:50:32.150Z
Learnt from: Despire
Repo: berops/claudie PR: 1838
File: services/terraformer/server/domain/utils/tofu/terraform.go:23-25
Timestamp: 2025-08-25T06:50:32.150Z
Learning: In the Claudie codebase, Despire prefers to use environment variable values as-is without additional runtime validation, trusting operators to configure reasonable values rather than adding defensive programming checks.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
📚 Learning: 2025-08-25T06:51:04.662Z
Learnt from: Despire
Repo: berops/claudie PR: 1838
File: services/ansibler/server/domain/usecases/usecases.go:17-19
Timestamp: 2025-08-25T06:51:04.662Z
Learning: In services/ansibler/server/domain/usecases/usecases.go, Despire prefers to use environment variable values as-is without additional validation guards for SpawnProcessLimit, trusting the deployment configuration to provide appropriate values.

Applied to files:

  • services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2
🔇 Additional comments (1)
services/ansibler/server/ansible-playbooks/wireguard/templates/wg-static.conf.j2 (1)

3-3: Good: PrivateKey now correctly uses privatekey.content | b64decode (fixes prior critical).

@m-brando m-brando requested a review from Despire January 9, 2026 06:43

@Despire Despire left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM 👍

@m-brando m-brando requested review from jakubhlavacka and removed request for jakubhlavacka January 9, 2026 12:16
@m-brando m-brando added this pull request to the merge queue Jan 9, 2026
Merged via the queue into master with commit 2b4dd13 Jan 9, 2026
5 checks passed
@m-brando m-brando deleted the feat/ansible-perf branch January 9, 2026 12:38
@m-brando m-brando mentioned this pull request Jan 9, 2026
1 task
@coderabbitai coderabbitai Bot mentioned this pull request Feb 18, 2026
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.

2 participants