Vendor Galaxy Roles and Collections
Some checks failed
/ Ansible Lint (push) Failing after 5m45s
/ Ansible Lint (pull_request) Failing after 4m59s

This commit is contained in:
Stefan Bethke 2026-02-06 22:07:16 +01:00
commit 2aed20393f
3553 changed files with 387444 additions and 2 deletions

View file

@ -0,0 +1,71 @@
# Ansible role - Alloy
[![License](https://img.shields.io/github/license/grafana/grafana-ansible-collection)](LICENSE)
This Ansible role to install and configure [Alloy](https://grafana.com/docs/alloy/latest/), which can be used to collect traces, metrics, and logs.
This role is tailored for operating systems such as **RedHat**, **Rocky Linux**, **AlmaLinux**, **Ubuntu**, **Debian**, **macOS**, and **openSUSE**.
## Table of Content
- [Requirements](#requirements)
- [Role Variables](#role-variables)
- [Playbook](#playbook)
## Requirements
- Ansible 2.13+
- `ansible.utils` collection is required. Additionally, you must install the `netaddr` Python library on the host where you are running Ansible (not on the target remote host) if is not present.
- `community.general` collection is required for macOS support
- **macOS**: Homebrew must be installed
## Role Variables
| Variable Name | Description | Default Value |
|-----------------------|----------------------------------------------------------------------|---------------------------------------------------------------------|
| `alloy_version` | The version of Alloy to download and deploy. Supported standard version "1.4.2" format or "latest". | `latest` |
| `alloy_uninstall` | If set to `true` will perfom uninstall instead of deployment. | `false` |
| `alloy_expose_port` | By default, this is set to false. It supports only simple firewalld configurations. If set to true, a firewalld rule is added to expose the TCP alloy port. The Port is automatically extracted from the environment variable `alloy_env_file_vars` in CUSTOM_ARGS when --server.http.listen-addr=0.0.0.0:12345 is defined. If set to false, configuration is skipped. If the firewalld.service is not active, all firewalld tasks are skipped. | `false` |
| `alloy_user_groups` | Appends the alloy user to specific groups. | `[]` |
| `alloy_github_api_url` | The default Github API URL to check for the latest version available. | `"https://api.github.com/repos/grafana/alloy/releases/latest"` |
| `alloy_download_url_rpm` | The default download URL for the Alloy rpm package from GitHub. | `"https://github.com/grafana/alloy/releases/download/v{{ aloy_version }}/alloy-{{ aloy_version }}-1.{{ __alloy_arch }}.rpm"` |
| `alloy_download_url_deb` | The default download URL for the Alloy deb package from GitHub. | `"https://github.com/grafana/alloy/releases/download/v{{ aloy_version }}/alloy-{{ aloy_version }}-1.{{ __alloy_arch }}.deb"` |
| `alloy_readiness_check_use_https` | This boolean variable determines whether the readiness check for the Alloy server should use HTTPS or HTTP when validating the `/-/ready` endpoint. This variable does not enable TLS on the Alloy server itself. | `false` |
| `alloy_readiness_check_use_proxy` | This boolean variable determines whether the readiness check for the Alloy server should use a proxy when validating the `/-/ready` endpoint. If false, it will not use a proxy, even if one is defined in an environment variable on the target hosts. | `true` |
| `alloy_env_file_vars` | You can use environment variables to control the run-time behavior of Grafana Alloy. | `{}` |
| `alloy_systemd_override` | Systemd unit drop-in file used to override or extend the default configuration of a systemd unit. | `{}` |
| `alloy_config` | This is the configuration that sets up Alloy. Refer to the [configuration blocks](https://grafana.com/docs/alloy/latest/reference/config-blocks/) and [components](https://grafana.com/docs/alloy/latest/reference/components/) documentation for more details. Since the purpose of using Alloy varies, no default configuration is provided. ⚠️ **You must provide either `alloy_config` for single config or set `alloy_env_file_vars.CONFIG_FILE` for multi-config setup**. Note that if you use `alloy_env_file_vars.CONFIG_FILE`, the content of `alloy_config` will not be templated. It is expected that you manage the multi-config content using pre_tasks or with your own role. | `{}` |
## Dependencies
No Dependencies
## Playbook
```yaml
- name: Manage alloy service
hosts: all
become: true
vars:
# alloy_config: |
# Your Config Content
roles:
- role: grafana.grafana.alloy
```
- Playbook execution example
```shell
# Deploy Alloy
ansible-playbook function_alloy_play.yml
# Uninstall Alloy
ansible-playbook function_alloy_play.yml -e "alloy_uninstall=true"
```
## License
See [LICENSE](https://github.com/grafana/grafana-ansible-collection/blob/main/LICENSE)
## Author Information
- [Ishan Jain](https://github.com/ishanjainn)
- [VoidQuark](https://github.com/voidquark)

View file

@ -0,0 +1,36 @@
---
# defaults file for alloy
alloy_version: "latest"
alloy_uninstall: false
alloy_expose_port: false
alloy_github_api_url: "https://api.github.com/repos/grafana/alloy/releases/latest"
alloy_download_url_rpm: "https://github.com/grafana/alloy/releases/download/v{{ alloy_version }}/alloy-{{ alloy_version }}-1.{{ __alloy_arch }}.rpm"
alloy_download_url_deb: "https://github.com/grafana/alloy/releases/download/v{{ alloy_version }}/alloy-{{ alloy_version }}-1.{{ __alloy_arch }}.deb"
alloy_readiness_check_use_https: false
alloy_readiness_check_use_proxy: true
alloy_user_groups: []
# alloy_user_groups:
# - "systemd-journal"
alloy_env_file_vars: {}
# alloy_env_file_vars:
# CONFIG_FILE: "/custom/path"
# CUSTOM_ARGS: "--server.http.listen-addr=0.0.0.0:12345 --stability.level=public-preview --feature.community-components.enabled=true"
alloy_systemd_override: {}
# alloy_systemd_override: |
# [Service]
# User=root
alloy_config: {}
# alloy_config: |
# prometheus.scrape "default" {
# targets = [{"__address__" = "127.0.0.1:12345"}]
# forward_to = [prometheus.remote_write.prom.receiver]
# }
# prometheus.remote_write "prom" {
# endpoint {
# url = "http://mimir:9009/api/v1/push"
# }
# }

View file

@ -0,0 +1,17 @@
---
# handlers file for alloy
- name: Restart alloy
listen: "restart alloy"
ansible.builtin.systemd:
daemon_reload: true
name: alloy.service
state: restarted
enabled: true
when: not ansible_check_mode
- name: Restart alloy macos
listen: "restart alloy macos"
ansible.builtin.command: "brew services restart {{ __alloy_brew_package }}"
when:
- not ansible_check_mode
- ansible_facts['os_family'] == 'Darwin'

View file

@ -0,0 +1,34 @@
---
galaxy_info:
role_name: alloy
author: Ishan Jain, voidquark
description: Role to Install and Configure Grafana Alloy
license: "GPL-3.0-or-later"
min_ansible_version: "2.13"
platforms:
- name: EL
versions:
- "8"
- "9"
- name: Fedora
versions:
- all
- name: Debian
versions:
- all
- name: Ubuntu
versions:
- all
- name: macOS
versions:
- all
- name: opensuse
versions:
- all
galaxy_tags:
- alloy
- grafana
- observability
- monitoring
- opentelemetry
- telemetry

View file

@ -0,0 +1,17 @@
---
- name: Converge
hosts: all
vars:
alloy_version: "1.4.2"
alloy_config: |
prometheus.scrape "default" {
targets = [{"__address__" = "127.0.0.1:12345"}]
forward_to = [prometheus.remote_write.prom.receiver]
}
prometheus.remote_write "prom" {
endpoint {
url = "http://mimir:9009/api/v1/push"
}
}
roles:
- role: grafana.grafana.alloy

View file

@ -0,0 +1,20 @@
---
dependency:
name: galaxy
options:
ignore-errors: true
driver:
name: docker
platforms:
- name: instance
image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux8}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
playbooks:
converge: converge.yml

View file

@ -0,0 +1,176 @@
---
- name: Obtain the latest version from the GitHub repo
when: alloy_version == "latest"
block:
- name: Scrape Github API endpoint to obtain latest Alloy version
ansible.builtin.uri:
url: "{{ alloy_github_api_url }}"
method: GET
body_format: json
become: false
delegate_to: localhost
run_once: true
check_mode: false
register: __github_latest_version
- name: Latest available Alloy version
ansible.builtin.set_fact:
alloy_version: "{{ __github_latest_version.json.tag_name | regex_replace('^v?(\\d+\\.\\d+\\.\\d+)$', '\\1') }}"
- name: Verify current deployed version
when: ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
block:
- name: Check if Alloy binary is present
ansible.builtin.stat:
path: "/usr/bin/alloy"
register: __already_deployed
- name: Obtain current deployed Alloy version
ansible.builtin.command:
cmd: "/usr/bin/alloy --version"
changed_when: false
register: __current_deployed_version
when: __already_deployed.stat.exists | bool
- name: Verify current deployed version on macOS
when: ansible_facts['os_family'] == 'Darwin'
block:
- name: Check if Alloy is installed via Homebrew
ansible.builtin.command: brew list --versions {{ __alloy_brew_package }}
register: __brew_alloy_version
failed_when: false
changed_when: false
- name: Extract current Alloy version on macOS
ansible.builtin.set_fact:
__current_deployed_version:
stdout: "{{ __brew_alloy_version.stdout }}"
when: __brew_alloy_version.rc == 0
- name: Include RedHat/Rocky setup
ansible.builtin.include_tasks:
file: setup-RedHat.yml
when: ansible_facts['os_family'] in ['RedHat', 'Rocky']
- name: Include Debian/Ubuntu setup
ansible.builtin.include_tasks:
file: setup-Debian.yml
when: ansible_facts['os_family'] == 'Debian'
- name: Include macOS/Darwin setup
ansible.builtin.include_tasks:
file: setup-Darwin.yml
when: ansible_facts['os_family'] == 'Darwin'
- name: Include SUSE setup
ansible.builtin.include_tasks:
file: setup-Suse.yml
when: ansible_facts['os_family'] == 'Suse'
- name: Alloy systemd override
when:
- alloy_systemd_override | length > 0
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
block:
- name: Ensure that Alloy systemd override path exist
ansible.builtin.file:
path: "/etc/systemd/system/alloy.service.d"
state: directory
owner: "root"
group: "root"
mode: "0750"
notify: restart alloy
- name: Template Alloy systemd override.conf - /etc/systemd/system/alloy.service.d/override.conf
ansible.builtin.template:
src: "override.conf.j2"
dest: "/etc/systemd/system/alloy.service.d/override.conf"
owner: "root"
group: "root"
mode: "0644"
notify: restart alloy
- name: Template Alloy env file - {{ __alloy_env_file }}
ansible.builtin.template:
src: "alloy.j2"
dest: "{{ __alloy_env_file }}"
owner: "root"
group: "root"
mode: "0644"
notify: restart alloy
when: ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- name: Template Alloy config - /etc/alloy/config.alloy
ansible.builtin.template:
src: "config.alloy.j2"
dest: "/etc/alloy/config.alloy"
owner: "root"
group: "root"
mode: "0644"
when:
- alloy_config | length > 0
- alloy_env_file_vars.CONFIG_FILE is not defined
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
notify: restart alloy
- name: Ensure that /etc/alloy/alloy.config is absent when a custom configuration file/dir is specified in alloy_env_file_vars.CONFIG_FILE
ansible.builtin.file:
path: "/etc/alloy/config.alloy"
state: absent
when:
- alloy_config | length < 1 or alloy_env_file_vars.CONFIG_FILE is defined
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- name: Add the Alloy system user to additional group
ansible.builtin.user:
name: "alloy"
groups: "{{ item }}"
system: true
append: true
create_home: false
state: present
loop: "{{ alloy_user_groups }}"
when:
- alloy_user_groups | length > 0
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- name: Get firewalld state
ansible.builtin.systemd:
name: "firewalld"
register: __firewalld_service_state
when: ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- name: Enable firewalld rule to expose Alloy tcp port {{ __alloy_server_http_listen_port }}
ansible.posix.firewalld:
immediate: true
permanent: true
port: "{{ __alloy_server_http_listen_port }}/tcp"
state: enabled
when:
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- __firewalld_service_state.status.ActiveState == "active"
- alloy_expose_port | bool
- name: Flush handlers after deployment
ansible.builtin.meta: flush_handlers
- name: Ensure that Alloy is started (Linux)
ansible.builtin.systemd:
name: alloy.service
state: started
when:
- not ansible_check_mode
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']
- name: Verify that Alloy URL is responding
ansible.builtin.uri:
url: "{{ alloy_readiness_check_use_https | ansible.builtin.ternary('https', 'http') }}://{{ __alloy_server_http_listen_address }}:{{ __alloy_server_http_listen_port }}/-/ready"
method: GET
use_proxy: "{{ alloy_readiness_check_use_proxy | bool }}"
register: __alloy_verify_url_status_code
retries: 5
delay: 8
until: __alloy_verify_url_status_code.status == 200
when:
- not ansible_check_mode
- ansible_facts['os_family'] in ['RedHat', 'Debian', 'Suse']

View file

@ -0,0 +1,19 @@
---
# tasks file for alloy
- name: Include OS specific variables
ansible.builtin.include_vars:
file: "{{ ansible_facts['os_family'] }}.yml"
- name: Preflight
ansible.builtin.include_tasks:
file: "preflight.yml"
- name: Deploy Alloy service
ansible.builtin.include_tasks:
file: "deploy.yml"
when: not alloy_uninstall
- name: Uninstall Alloy service
ansible.builtin.include_tasks:
file: "uninstall.yml"
when: alloy_uninstall

View file

@ -0,0 +1,26 @@
---
- name: Fail when alloy_config or alloy_env_file_vars.CONFIG_FILE is not defined
ansible.builtin.fail:
msg: Variable alloy_config or alloy_env_file_vars.CONFIG_FILE is required!
when:
- alloy_config | length < 1
- alloy_env_file_vars.CONFIG_FILE is not defined
- not alloy_uninstall
- name: Extract IP address and PORT from alloy_env_file_vars
when: alloy_env_file_vars.CUSTOM_ARGS is defined and alloy_env_file_vars.CUSTOM_ARGS | length > 0
block:
- name: Search for server.http.listen-addr string
ansible.builtin.set_fact:
__alloy_server_http_listen_addr_regex: "{{ alloy_env_file_vars.CUSTOM_ARGS | regex_search('--server.http.listen-addr=([\\d\\.]+):(\\d+)', '\\1', '\\2') or [] }}"
- name: Extract IP address and port
ansible.builtin.set_fact:
__alloy_server_http_listen_address: "{{ __alloy_server_http_listen_addr_regex[0] }}"
__alloy_server_http_listen_port: "{{ __alloy_server_http_listen_addr_regex[1] }}"
when: __alloy_server_http_listen_addr_regex | length > 0
- name: Assert that extracted IP address is valid
ansible.builtin.assert:
that: (__alloy_server_http_listen_address | ansible.utils.ipaddr) != ""
when: __alloy_server_http_listen_addr_regex | length > 0

View file

@ -0,0 +1,96 @@
---
- name: Check if Homebrew is installed
ansible.builtin.command: which brew
register: __brew_check
changed_when: false
failed_when: false
- name: Fail if Homebrew is not installed
ansible.builtin.fail:
msg: "Homebrew is required but not installed"
when: __brew_check.rc != 0
- name: Get Homebrew prefix
ansible.builtin.command: brew --prefix
register: __brew_prefix
changed_when: false
- name: Set Alloy config directory path
ansible.builtin.set_fact:
__alloy_config_path: "{{ __alloy_config_path_default }}"
- name: Add Grafana tap to Homebrew
community.general.homebrew_tap:
name: "{{ __alloy_brew_tap }}"
state: present
- name: Install Alloy via Homebrew
community.general.homebrew:
name: "{{ __alloy_brew_package }}"
state: present
update_homebrew: true
- name: Ensure Alloy config directory exists
ansible.builtin.file:
path: "{{ __alloy_config_path }}"
state: directory
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_gid }}"
mode: '0755'
- name: Template Alloy config
ansible.builtin.template:
src: "config.alloy.j2"
dest: "{{ __alloy_config_path }}/config.alloy"
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_gid }}"
mode: '0644'
backup: true
when: alloy_config | length > 0
notify: restart alloy macos
- name: Check if Alloy service is loaded
ansible.builtin.command: brew services list
register: __brew_services
changed_when: false
- name: Stop Alloy service if it exists (to clean up any issues)
ansible.builtin.command: "brew services stop {{ __alloy_brew_package }}"
register: __stop_result
failed_when: false
changed_when: "'Successfully stopped' in __stop_result.stdout"
when: "'alloy' in __brew_services.stdout"
- name: Start Alloy service
ansible.builtin.command: "brew services start {{ __alloy_brew_package }}"
when:
- "'alloy' not in __brew_services.stdout or 'started' not in __brew_services.stdout"
register: __service_start
failed_when: __service_start.rc != 0
- name: Restart Alloy service if already running
ansible.builtin.command: "brew services restart {{ __alloy_brew_package }}"
when:
- "'alloy' in __brew_services.stdout and 'started' in __brew_services.stdout"
register: __service_restart
failed_when: __service_restart.rc != 0
- name: Check final service status
ansible.builtin.command: brew services list
register: __final_brew_services
changed_when: false
- name: Verify Alloy installation
ansible.builtin.command: alloy --version
register: __alloy_version_output
changed_when: false
failed_when: false
- name: Display Alloy version
ansible.builtin.debug:
msg: "Alloy version: {{ __alloy_version_output.stdout }}"
when: __alloy_version_output.rc == 0
- name: Display service status
ansible.builtin.debug:
msg: "Alloy service status: {{ __final_brew_services.stdout_lines | select('match', '.*alloy.*') | list }}"

View file

@ -0,0 +1,7 @@
---
- name: APT - Install Alloy
ansible.builtin.apt:
deb: "{{ alloy_download_url_deb }}"
state: present
notify: restart alloy
when: __current_deployed_version.stdout is not defined or alloy_version not in __current_deployed_version.stdout

View file

@ -0,0 +1,8 @@
---
- name: DNF - Install Alloy from remote URL
ansible.builtin.package:
name: "{{ alloy_download_url_rpm }}"
state: present
disable_gpg_check: true
notify: restart alloy
when: __current_deployed_version.stdout is not defined or alloy_version not in __current_deployed_version.stdout

View file

@ -0,0 +1,8 @@
---
- name: Zypper - Install Alloy from remote URL
community.general.zypper:
name: "{{ alloy_download_url_rpm }}"
state: present
disable_gpg_check: true
notify: restart alloy
when: __current_deployed_version.stdout is not defined or alloy_version not in __current_deployed_version.stdout

View file

@ -0,0 +1,75 @@
---
- name: Stop Alloy service
ansible.builtin.systemd: # noqa ignore-errors
name: alloy
state: stopped
ignore_errors: true
- name: Stop Alloy service on macOS
ansible.builtin.command: "brew services stop {{ __alloy_brew_package }}"
when: ansible_facts['os_family'] == 'Darwin'
failed_when: false
- name: Uninstall Alloy rpm package
ansible.builtin.package:
name: "alloy"
state: absent
autoremove: true
when: ansible_facts['os_family'] in ['RedHat', 'Rocky']
- name: Uninstall Alloy deb package
ansible.builtin.apt:
name: "alloy"
state: absent
purge: true
when: ansible_facts['os_family'] == 'Debian'
- name: Uninstall Alloy via Homebrew
community.general.homebrew:
name: "{{ __alloy_brew_package }}"
state: absent
when: ansible_facts['os_family'] == 'Darwin'
- name: Uninstall Alloy rpm package (SUSE)
community.general.zypper:
name: "alloy"
state: absent
when: ansible_facts['os_family'] == 'Suse'
- name: Ensure that Alloy firewalld rule is not present - tcp port {{ __alloy_server_http_listen_port }}
ansible.posix.firewalld: # noqa ignore-errors
immediate: true
permanent: true
port: "{{ __alloy_server_http_listen_port }}/tcp"
state: disabled
ignore_errors: true
- name: Remove Alloy directories
ansible.builtin.file:
path: "{{ remove_me }}"
state: absent
loop:
- "/etc/alloy"
- "/etc/systemd/system/alloy.service.d"
- "/var/lib/alloy"
- "/etc/sysconfig/alloy"
- "/etc/default/alloy"
loop_control:
loop_var: remove_me
- name: Remove Alloy config directory on macOS
ansible.builtin.file:
path: "{{ __alloy_config_path_default }}"
state: absent
when: ansible_facts['os_family'] == 'Darwin'
- name: Remove the Alloy system user
ansible.builtin.user:
name: "alloy"
force: true
state: absent
- name: Remove Alloy system group
ansible.builtin.group:
name: "alloy"
state: absent

View file

@ -0,0 +1,10 @@
# Ansible Managed
{% if alloy_env_file_vars.CONFIG_FILE is not defined or alloy_env_file_vars.CONFIG_FILE | length < 1 %}
CONFIG_FILE="/etc/alloy/config.alloy"
{% endif %}
RESTART_ON_UPGRADE=true
{% for key, value in alloy_env_file_vars.items() %}
{{ key}}="{{value}}"
{% endfor %}

View file

@ -0,0 +1,3 @@
// Ansible Managed
{{ alloy_config }}

View file

@ -0,0 +1,3 @@
# Ansible Managed
{{ alloy_systemd_override }}

View file

@ -0,0 +1,5 @@
---
# macOS/Darwin specific variables
__alloy_brew_tap: "grafana/grafana"
__alloy_brew_package: "grafana/grafana/alloy"
__alloy_config_path_default: "{{ __brew_prefix.stdout | default('/opt/homebrew') }}"

View file

@ -0,0 +1,2 @@
---
__alloy_env_file: "/etc/default/alloy"

View file

@ -0,0 +1,2 @@
---
__alloy_env_file: "/etc/sysconfig/alloy"

View file

@ -0,0 +1,2 @@
---
__alloy_env_file: "/etc/sysconfig/alloy"

View file

@ -0,0 +1,9 @@
---
__alloy_server_http_listen_address: 127.0.0.1
__alloy_server_http_listen_port: 12345
__alloy_arch_map:
x86_64: 'amd64'
armv6l: 'arm'
armv7l: 'arm'
aarch64: 'arm64'
__alloy_arch: "{{ __alloy_arch_map[ansible_facts['architecture']] | default(ansible_facts['architecture']) }}"