| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
Co-authored-by: Cursor <cursoragent@cursor.com>
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
There was a problem hiding this comment.
Looks like a solid role. Looking forward for some changed requested elsewhere, then we can merge it. The CI test failures are due to an issue with the sudo role, already fixed by a different PR.
Sorry, something went wrong.
| - name: Restart cloudflared tunnels | ||
| ansible.builtin.systemd: | ||
| name: 'cloudflared@{{ item.name }}.service' | ||
| state: 'restarted' | ||
| loop: '{{ cloudflared__combined_tunnels }}' | ||
| loop_control: | ||
| label: '{{ item.name }}' | ||
| when: cloudflared__enabled | d(False) | bool and | ||
| item.state | d('present') == 'present' |
There was a problem hiding this comment.
Using role-scoped variables here will break the entire global_handlers role when the cloudflared role is not included in a playbook. Move this handler into the cloudflared role to avoid that.
Sorry, something went wrong.
| # .. envvar:: cloudflared__enabled [[[ | ||
| # | ||
| # Enable or disable the ``cloudflared`` role. | ||
| cloudflared__enabled: True | ||
|
|
||
| # ]]] |
There was a problem hiding this comment.
The role is not part of the common.yml playbook, so adding this variable is probably superfluous.
Sorry, something went wrong.
| # systemd configuration [[[ | ||
| # ------------------------- | ||
|
|
||
| # .. envvar:: cloudflared__systemd_restart_policy [[[ | ||
| # | ||
| # The restart policy for cloudflared systemd service instances. | ||
| cloudflared__systemd_restart_policy: 'on-failure' | ||
|
|
||
| # ]]] | ||
| # .. envvar:: cloudflared__systemd_restart_sec [[[ | ||
| # | ||
| # The time to wait between restarts of cloudflared service instances. | ||
| cloudflared__systemd_restart_sec: '5' | ||
|
|
||
| # ]]] | ||
| # .. envvar:: cloudflared__systemd_after [[[ | ||
| # | ||
| # The ``After=`` directive in cloudflared systemd service units. | ||
| cloudflared__systemd_after: 'network-online.target' | ||
| # ]]] | ||
| # ]]] |
There was a problem hiding this comment.
These options could probably be set directly in the systemd unit files deployed by this role, especially the cloudflared__systemd_after variable. The options can be overridden via the systemd role if needed using the systemd-level override files, and most likely will be more useful per-instance, for example to order different tunnels after different services are started.
Sorry, something went wrong.
| # | ||
| # Address and port to expose Prometheus metrics. Set to empty string to | ||
| # disable. Example: ``127.0.0.1:2000``. | ||
| cloudflared__metrics: '' |
There was a problem hiding this comment.
The default could be enabled by default on localhost instead of being a proposal via comment - less work during deployment. A nice QoL would be adding an etc_services entry for this port when enabled. Also, is there an upstream default for Prometheus metrics used by cloudflared? Port 2000 seems to be already reserved for Cisco SCCP service, I would pick a different one.
Sorry, something went wrong.
The 'Restart vmagent instances' handler in global_handlers referenced vmagent__combined_instances without a safe default, unconditionally imported from global_handlers/handlers/main.yml - the same pattern flagged by review on the cloudflared role (PR debops#2702), which breaks global_handlers evaluation on hosts where the vmagent role is not part of the playbook. The handler was also never notified anywhere: manage_instance.yml already restarts the per-instance systemd unit directly (with '# noqa no-handler') when its config/env/secret/binary changes, so the global_handlers copy was dead code left over from following the cloudflared role as a template. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_vmagent inventory group, so a role-wide enable/disable switch is redundant. Other roles imported into layer/agent.yml (telegraf, filebeat, metricbeat, zabbix_agent) have no comparable __enabled variable either; __deploy_state alone controls present/absent state. Generated-By: LLM (Claude Sonnet 5 via Cursor)
…variable Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_prometheus_exporter inventory group, so a role-wide enable/disable switch is redundant. Individual exporters already carry their own per-item 'state' (present/absent) handled in manage_exporter.yml. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Complete PR debops#2702 review comment debops#3: the full 'systemd configuration' section (restart_policy, restart_sec, after) was flagged as being better set directly in the unit file, with systemd_after called out as the primary example. The previous fix only hardcoded 'After=network-online.target' and left cloudflared__systemd_restart_policy / cloudflared__systemd_restart_sec as role-wide variables. Hardcode 'Restart=on-failure' / 'RestartSec=5' directly in cloudflared@.service.j2 as well, and drop both variables; per-instance overrides remain available via debops.systemd drop-in files. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared, comment debops#3): role-wide vmagent__systemd_after / vmagent__systemd_restart_policy / vmagent__systemd_restart_sec are better hardcoded directly in the vmagent@.service template unit, since they're expected to be uniform across instances; per-instance overrides remain available via debops.systemd drop-in files. vmagent__systemd_timeout_stop_sec and vmagent__systemd_limit_nofile are left as role-wide variables since they document legitimate workload-scaling use cases (queue flush time, open file limits for busy aggregators), unlike ordering/restart policy. Generated-By: LLM (Claude Sonnet 5 via Cursor)
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
- Remove the unused 'Restart cloudflared tunnels' handler from global_handlers. It referenced cloudflared__combined_tunnels without a safe default and was unconditionally imported from global_handlers/handlers/main.yml, which would break global_handlers evaluation on hosts where the cloudflared role is not part of the playbook. The handler was also never notified anywhere: manage_tunnel.yml already restarts the per-tunnel systemd unit directly (with '# noqa no-handler') on config/env/credentials changes, so it was dead code. - Hardcode 'After=network-online.target' directly in the cloudflared@.service.j2 systemd template instead of exposing cloudflared__systemd_after as a role-wide variable - the ordering is expected to be identical for every tunnel instance. Per-instance overrides should go through the debops.systemd role's drop-in override files instead. - Enable cloudflared__metrics by default (bound to loopback) instead of only proposing it via a comment example. Port 2000 is avoided as the default since it's already reserved for the Cisco SCCP service on many systems; use 127.0.0.1:20241 instead. - Add cloudflared__etc_services__dependent_list and wire the debops.etc_services role into the cloudflared playbook so the metrics port gets a /etc/services entry when enabled, following the same pattern used by docker_registry, dhcpd and other roles. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Per PR debops#2702 review: the role is not part of the common.yml playbook (it only runs on hosts in the debops_service_cloudflared inventory group via its own playbook), so a role-wide enable/disable switch is redundant - membership in that group already controls whether the role runs at all. This matches the pattern used by other standalone service roles such as docker_registry, dhcpd and mosquitto, which have no comparable __enabled variable and rely solely on their __deploy_state variable for present/absent state. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Complete PR debops#2702 review comment debops#3: the full 'systemd configuration' section (restart_policy, restart_sec, after) was flagged as being better set directly in the unit file, with systemd_after called out as the primary example. The previous fix only hardcoded 'After=network-online.target' and left cloudflared__systemd_restart_policy / cloudflared__systemd_restart_sec as role-wide variables. Hardcode 'Restart=on-failure' / 'RestartSec=5' directly in cloudflared@.service.j2 as well, and drop both variables; per-instance overrides remain available via debops.systemd drop-in files. Generated-By: LLM (Claude Sonnet 5 via Cursor)
The 'Restart vmagent instances' handler in global_handlers referenced vmagent__combined_instances without a safe default, unconditionally imported from global_handlers/handlers/main.yml - the same pattern flagged by review on the cloudflared role (PR debops#2702), which breaks global_handlers evaluation on hosts where the vmagent role is not part of the playbook. The handler was also never notified anywhere: manage_instance.yml already restarts the per-instance systemd unit directly (with '# noqa no-handler') when its config/env/secret/binary changes, so the global_handlers copy was dead code left over from following the cloudflared role as a template. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_vmagent inventory group, so a role-wide enable/disable switch is redundant. Other roles imported into layer/agent.yml (telegraf, filebeat, metricbeat, zabbix_agent) have no comparable __enabled variable either; __deploy_state alone controls present/absent state. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared, comment debops#3): role-wide vmagent__systemd_after / vmagent__systemd_restart_policy / vmagent__systemd_restart_sec are better hardcoded directly in the vmagent@.service template unit, since they're expected to be uniform across instances; per-instance overrides remain available via debops.systemd drop-in files. vmagent__systemd_timeout_stop_sec and vmagent__systemd_limit_nofile are left as role-wide variables since they document legitimate workload-scaling use cases (queue flush time, open file limits for busy aggregators), unlike ordering/restart policy. Generated-By: LLM (Claude Sonnet 5 via Cursor)
…variable Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_prometheus_exporter inventory group, so a role-wide enable/disable switch is redundant. Individual exporters already carry their own per-item 'state' (present/absent) handled in manage_exporter.yml. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Introduce debops.cloudflared role that installs and configures cloudflared on Debian/Ubuntu servers. Features: - Installation from upstream Cloudflare APT repository via debops.keyring - Two tunnel modes: token (remotely managed) and local (config file) - Multiple tunnel instances via systemd template units (cloudflared@.service) - Secret management using standard debops.secret mechanism - Full support for ingress rules, origin request, WARP routing, post-quantum cryptography and Prometheus metrics - Documentation: getting-started, defaults-detailed, nginx integration guide, Docker integration guide - Global handler for tunnel restarts - Role added to Networking category in role-index
- The Cloudflare APT signing key changed from cloudflare-main.gpg (fingerprint A5FC51C5...) to cloudflare-public-v2.gpg (fingerprint CC94B39C...) and the repository now uses the universal 'any' distribution component. - Add empty pre_main.yml / post_main.yml placeholders under tasks/cloudflared/ so the include_tasks lookups in tasks/main.yml do not fail when no project-level override is provided. - Drop the redundant 'Restart cloudflared tunnels' handler notification from the 'Cloudflare APT repository preferences' task. Changing apt preferences does not affect running tunnel instances.
cloudflared is an outbound agent connecting the host to the Cloudflare Zero Trust edge -- semantically it belongs in layer/agent.yml alongside Filebeat, Metricbeat, GitLab Runner, Telegraf and Zabbix Agent. Placed first so the tunnel comes up before observability agents start emitting traffic that may be relayed through services exposed via the tunnel (and so a freshly bootstrapped host can be reached via 'cloudflared tunnel run' immediately after 'debops run site'). The service/cloudflared.yml playbook was added in commit f5ffc5e ('Add cloudflared role for managing Cloudflare Tunnel instances') but was never wired into site.yml, so it had to be invoked explicitly.
ansible-lint requires Jinja templates to appear only at the end of a
task's 'name' field; otherwise log lines emitted by Ansible can become
ambiguous when the rendered name contains additional text after the
template.
All 14 tasks in the per-tunnel include file referenced '{{ tunnel.name }}'
in the middle of their human-readable description. Rewrite each name as
'<verb> <description> for cloudflared tunnel {{ tunnel.name }}' so the
template lands at the end of the string. The behaviour of every task
is unchanged.
Fixes 10 'name[template]' violations reported by ansible-lint in CI for
PR debops#2702.
The CI documentation/debops-sdist/debops-wheel/docker-image jobs all
failed with the same warning (treated as error by '-W' in test-docs and
test-man Makefile targets):
Warning, treated as error:
/.../docs/ansible/roles/cloudflared/defaults-detailed.rst:document
isn't included in any toctree
The DebOps documentation root toctree (docs/ansible/roles/index.rst)
globs '*/index' for every role directory, and conf.py iterates the same
directory list to register manpages from each role's 'man_index.rst' or
'index.rst'. The cloudflared role shipped neither, so its existing
.rst files (defaults-detailed, getting-started, guide-*) were treated
as orphaned documents.
Add the standard set of role documentation index files following the
established DebOps convention (cf. docs/ansible/roles/slapd/ for the
'guide-*.rst' variant of the layout):
- docs/ansible/roles/cloudflared/index.rst -- main entry, declares the
'.. _debops.cloudflared:' label and lists the role's RST documents in
a toctree (getting-started, guide-docker-integration,
guide-nginx-integration, defaults/main, defaults-detailed).
- docs/ansible/roles/cloudflared/man_description.rst -- short prose
description used by both the HTML index and the Sphinx manpage
builder (':start-line: 7' import in index.rst).
- docs/ansible/roles/cloudflared/man_index.rst -- ':orphan:' entry
point used when conf.py registers 'debops.cloudflared(5)' as a
manpage target.
- docs/ansible/roles/cloudflared/man_synopsis.rst -- standard
'debops run/check service/cloudflared' invocation synopsis.
- ansible/roles/cloudflared/COPYRIGHT -- conf.py reads the role's
COPYRIGHT to populate manpage description and authors.
Update docs/ansible/role-index.rst to use ':ref:`debops.cloudflared`'
instead of the literal '``debops.cloudflared``' (now that the label
exists), matching every other entry in the role catalogue.
Fixes the CI 'documentation', 'debops-sdist', 'debops-wheel' and
'docker-image' job failures reported on PR debops#2702.
The role was originally created with help of an AI assistant that
hallucinated a fictional author identity ('Marcin Sciborski'
<marcin@sciborski.com>) in the copyright headers and meta/main.yml.
The actual author of all commits in this role is Patryk Ściborek
<patryk@sciborek.com>; no contributor named 'Marcin Sciborski' has
ever existed in the git history of this repository.
Replace the bogus attribution in all 23 affected files (role tasks,
templates, defaults, meta, global handler, COPYRIGHT, service
playbook, and the role documentation) with the correct identity.
This avoids misleading copyright/authorship claims in the upstream
PR and aligns the meta/main.yml 'author' field with reality.
No functional change.
- Remove the unused 'Restart cloudflared tunnels' handler from global_handlers. It referenced cloudflared__combined_tunnels without a safe default and was unconditionally imported from global_handlers/handlers/main.yml, which would break global_handlers evaluation on hosts where the cloudflared role is not part of the playbook. The handler was also never notified anywhere: manage_tunnel.yml already restarts the per-tunnel systemd unit directly (with '# noqa no-handler') on config/env/credentials changes, so it was dead code. - Hardcode 'After=network-online.target' directly in the cloudflared@.service.j2 systemd template instead of exposing cloudflared__systemd_after as a role-wide variable - the ordering is expected to be identical for every tunnel instance. Per-instance overrides should go through the debops.systemd role's drop-in override files instead. - Enable cloudflared__metrics by default (bound to loopback) instead of only proposing it via a comment example. Port 2000 is avoided as the default since it's already reserved for the Cisco SCCP service on many systems; use 127.0.0.1:20241 instead. - Add cloudflared__etc_services__dependent_list and wire the debops.etc_services role into the cloudflared playbook so the metrics port gets a /etc/services entry when enabled, following the same pattern used by docker_registry, dhcpd and other roles. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Per PR debops#2702 review: the role is not part of the common.yml playbook (it only runs on hosts in the debops_service_cloudflared inventory group via its own playbook), so a role-wide enable/disable switch is redundant - membership in that group already controls whether the role runs at all. This matches the pattern used by other standalone service roles such as docker_registry, dhcpd and mosquitto, which have no comparable __enabled variable and rely solely on their __deploy_state variable for present/absent state. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Complete PR debops#2702 review comment debops#3: the full 'systemd configuration' section (restart_policy, restart_sec, after) was flagged as being better set directly in the unit file, with systemd_after called out as the primary example. The previous fix only hardcoded 'After=network-online.target' and left cloudflared__systemd_restart_policy / cloudflared__systemd_restart_sec as role-wide variables. Hardcode 'Restart=on-failure' / 'RestartSec=5' directly in cloudflared@.service.j2 as well, and drop both variables; per-instance overrides remain available via debops.systemd drop-in files. Generated-By: LLM (Claude Sonnet 5 via Cursor)
The 'Restart vmagent instances' handler in global_handlers referenced vmagent__combined_instances without a safe default, unconditionally imported from global_handlers/handlers/main.yml - the same pattern flagged by review on the cloudflared role (PR debops#2702), which breaks global_handlers evaluation on hosts where the vmagent role is not part of the playbook. The handler was also never notified anywhere: manage_instance.yml already restarts the per-instance systemd unit directly (with '# noqa no-handler') when its config/env/secret/binary changes, so the global_handlers copy was dead code left over from following the cloudflared role as a template. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_vmagent inventory group, so a role-wide enable/disable switch is redundant. Other roles imported into layer/agent.yml (telegraf, filebeat, metricbeat, zabbix_agent) have no comparable __enabled variable either; __deploy_state alone controls present/absent state. Generated-By: LLM (Claude Sonnet 5 via Cursor)
Same pattern flagged by drybjed on PR debops#2702 (cloudflared, comment debops#3): role-wide vmagent__systemd_after / vmagent__systemd_restart_policy / vmagent__systemd_restart_sec are better hardcoded directly in the vmagent@.service template unit, since they're expected to be uniform across instances; per-instance overrides remain available via debops.systemd drop-in files. vmagent__systemd_timeout_stop_sec and vmagent__systemd_limit_nofile are left as role-wide variables since they document legitimate workload-scaling use cases (queue flush time, open file limits for busy aggregators), unlike ordering/restart policy. Generated-By: LLM (Claude Sonnet 5 via Cursor)
…variable Same pattern flagged by drybjed on PR debops#2702 (cloudflared): the role is not part of common.yml and its playbook already restricts execution to the debops_service_prometheus_exporter inventory group, so a role-wide enable/disable switch is redundant. Individual exporters already carry their own per-item 'state' (present/absent) handled in manage_exporter.yml. Generated-By: LLM (Claude Sonnet 5 via Cursor)
| Back | FazBrowse Home | New Git URL |
Summary
Adds a new debops.cloudflared role that installs and configures the
cloudflared daemon (Cloudflare Tunnel client) on Debian-family hosts, with
support for multiple concurrent tunnel instances managed via a single systemd
template unit. Wires the new playbook into layer/agent.yml so that
debops run site configures Cloudflare Tunnels alongside other outbound
agents (Filebeat, Metricbeat, Telegraf, Zabbix Agent).
cloudflared maintains outbound-only encrypted connections from the host to
the Cloudflare edge, eliminating the need for inbound firewall ports or a
public IP on the origin server. This makes it a natural building block for
Zero Trust homelab and self-hosted deployments where the public-facing
attack surface should be minimised.
Motivation
Cloudflare Tunnel deployments in DebOps environments today rely on either
(a) manual apt-get install cloudflared plus hand-rolled systemd units
and config.yml files, or (b) running cloudflared inside a container,
which adds an unnecessary network namespace between the daemon and the
host services it proxies to.
A dedicated DebOps role offers:
named tunnel instances (cloudflared@web.service,
cloudflared@admin.service, …) sharing one binary and one APT repo, with
per-tunnel credentials, configuration, and lifecycle.
Ansible-managed (local) tunnel configurations are first-class, with
validation at playbook time so misconfigured tunnels fail fast.
secret/cloudflared/tunnels/<name>/{token,credentials.json} on the
Ansible Controller, never in cleartext in inventory.
TimeoutStopSec greater than the in-flight grace period so the kernel
doesn't SIGKILL the daemon mid-drain.
its credentials/config/env file changed, not on every playbook run.
Design
Systemd template unit
A single cloudflared@.service template unit drives all tunnel instances.
Per-tunnel state lives in two files under /etc/cloudflared:
mode containing only token-file references.
or absent in local mode.
This means adding a new tunnel is a one-line YAML addition; removing one is
state: 'absent' with full cleanup of unit/config/credentials.
Tunnel modes
Both modes use the standard DebOps secret mechanism. The main_env
pre-task computes the list of required secret/ directories per host and
passes it to the secret role via secret_directories.
Validated tunnel definitions
Each tunnel passes through an assert in manage_tunnel.yml before any
files are deployed:
…so a typo in mode: or a missing name: fails the play immediately with
a clear message, rather than silently deploying broken units.
Restart semantics
The role registers separate change variables for credentials, config, and
env files, and only restarts a tunnel when one of its own files changed:
Changes to a different tunnel on the same host don't disturb running
tunnels — important when a single host hosts multiple production tunnels
and you only want to roll one of them.
Hardened systemd unit
cloudflared in tunnel-run mode only needs outbound TCP/UDP to the
Cloudflare edge and loopback access for the metrics endpoint, so the
hardened defaults are safe. The unit applies ProtectSystem=strict,
PrivateTmp, capability dropping, namespace isolation, and a
TimeoutStopSec of 45s (greater than the default grace_period: '30s')
to allow graceful connection draining without SIGKILL. Extra
restrictions (e.g. IPAddressAllow=) can be appended via
cloudflared__systemd_hardening_extra without forking the role.
Hook points
tasks/cloudflared/{pre_main,post_main}.yml are empty placeholders that
project-level overrides can populate via the standard
debops.debops.task_src lookup. Useful for hooks like "wait for tunnel
to be /ready" or "register Prometheus scrape target after deploy".
What this PR adds
global_handlers
unit, loop over cloudflared__combined_tunnels
cloudflared__secret_directories for the secret role
validation and selective restart
catch-all rule, ingress with origin-request options
systemd template unit
exposing installed version + tunnel inventory
with Reload service manager and Restart cloudflared tunnels handlers,
imported from global_handlers/handlers/main.yml.
cloudflared__secret_directories
APT key) → cloudflared (main role)
tunnel comes up before observability agents start emitting traffic
that may be relayed through services exposed via the tunnel.
modes, secret management, minimal example, available tags
Compose services on the same host
nginx reverse proxy with origin SSL
cloudflare-main.gpg (fingerprint A5FC51C5...) to
cloudflare-public-v2.gpg (fingerprint CC94B39C77AE7342A68B89628A682D308D4E5E73),
and the repository now uses the universal any distribution component
instead of per-codename pools.
tasks/cloudflared/{pre_main,post_main}.yml files so the
include_tasks lookups in tasks/main.yml don't fail when no
project-level override is provided.
running tunnel instances, so the Restart cloudflared tunnels
handler notification was dropped from that task.
Dependencies
Independent — depends only on master. No coupling with any other PR
in flight.
Testing
Tested in a homelab DebOps deployment running Debian 13 (trixie) on
unprivileged Proxmox LXC containers, behind a Cloudflare Zero Trust
account with multiple tunnels:
Immich) provisioned via OpenTofu using the
cloudflare_zero_trust_tunnel_cloudflared resource. The token is
written to secret/cloudflared/tunnels/<name>/token by
local_sensitive_file and consumed by this role on the next
debops run site.
(cloudflared@public.service + cloudflared@admin.service) for
different ingress audiences. Verified that modifying ingress on one
tunnel via Cloudflare dashboard doesn't disturb the other (no restart
on debops run).
changed=0 for the role; cloudflared.fact reports the running
version unchanged. Modifying a tunnel's config.yml via the inventory
triggers exactly one restart of that tunnel.
unit stopped + disabled, config/env/credentials files removed,
journalctl -u cloudflared@<name>.service shows clean shutdown.
that the unit has Exposure level: 1.x SAFE rating with the default
hardening block enabled.
TimeoutStopSec: '45s', in-flight HTTP requests complete during a
config-triggered restart instead of being killed mid-stream.
Compatibility
same Cloudflare APT repo with the any distribution component.
is the path most Cloudflare Zero Trust workflows now use).
older systemd versions silently ignore unknown directives, but the
hardening will be partial).
Checklist
cloudflared__ variable namespace, [ 'role::cloudflared', 'skip::cloudflared' ] tags, become: True on the playbook level)
(pre_task computes dependent vars, then secret → keyring →
main role)
started, defaults-detailed, two integration guides, all listed in
role-index.rst)
provided so default-config users don't need to create empty files
(CC94B39C77AE7342A68B89628A682D308D4E5E73)
kernel doesn't SIGKILL mid-drain