Automating Zabbix Agent and Redis Deployments with SaltStack

Deploying the Zabbix Monitoring Agent

Establish the required directory hierarchy within the Salt base environment to separate system initialization tasks from application-specific configurations.

mkdir -p /srv/salt/base/{init/zabbix_epel,zabbix_agent/templates}

Configure the EPEL repository to ensure dependency resolution works correctly. Download the repository definition, place it in the designated files directory, and reference it in a state file.

cat > /srv/salt/base/init/zabbix_epel/repo_setup.sls << 'EOF'
epel_repository:
  file.managed:
    - name: /etc/yum.repos.d/epel.repo
    - source: salt://init/zabbix_epel/files/epel-7.repo
    - user: root
    - group: root
    - mode: '0644'
EOF

Prepare the Zabbix agent configuration template. Utilize Jinja variables to dynamically inject the monitoring server address and client hostname during deployment, replacing static entries.

sed -i 's/^Server=.*/Server={{ MONITOR_HOST }}/' /srv/salt/base/zabbix_agent/templates/zabbix_agentd.conf.j2
sed -i 's/^Hostname=.*/Hostname={{ CLIENT_FQDN }}/' /srv/salt/base/zabbix_agent/templates/zabbix_agentd.conf.j2

The deployment state handles RPM installation, package resolution, configuration templating, and service management in a sequential execution chain.

cat > /srv/salt/base/zabbix_agent/deploy.sls << 'EOF'
install_zabbix_release:
  file.managed:
    - name: /tmp/zabbix-release-4.0-2.el7.noarch.rpm
    - source: salt://zabbix_agent/files/zabbix-release-4.0-2.el7.noarch.rpm
    - makedirs: True
  cmd.run:
    - name: rpm -ivh /tmp/zabbix-release-4.0-2.el7.noarch.rpm --force
    - require:
      - file: install_zabbix_release

setup_zabbix_agent:
  pkg.installed:
    - name: zabbix-agent
    - require:
      - cmd: install_zabbix_release

configure_zabbix_agent:
  file.managed:
    - name: /etc/zabbix/zabbix_agentd.conf
    - source: salt://zabbix_agent/templates/zabbix_agentd.conf.j2
    - user: zabbix
    - group: zabbix
    - mode: '0644'
    - template: jinja
    - defaults:
        MONITOR_HOST: 192.168.5.18
        CLIENT_FQDN: {{ grains['fqdn'] }}
    - require:
      - pkg: setup_zabbix_agent

start_zabbix_agent:
  service.running:
    - name: zabbix-agent
    - enable: True
    - watch:
      - file: configure_zabbix_agent
      - pkg: setup_zabbix_agent
EOF

Validate the configuration syntax before applying changes to a target minion:

salt 'node-1' state.sls zabbix_agent.deploy test=True
salt 'node-1' state.sls zabbix_agent.deploy

Provisioning Redis Instances

For production workloads, switch to the prod Salt environment. Organize the module structure to support scalable service orchestration.

mkdir -p /srv/salt/prod/{modules/redis,redis_cluster/templates}

Create a foundatoinal state to ensure the Redis package is available across all target hosts.

cat > /srv/salt/prod/modules/redis/base_install.sls << 'EOF'
redis_package:
  pkg.installed:
    - name: redis
EOF

Define the master node orchestration state. This file extends the base installation, applies a customized configuration template, and ensures the service is active and persistent across reboots.

cat > /srv/salt/prod/redis_cluster/master_node.sls << 'EOF'
include:
  - modules.redis.base_install

apply_redis_config:
  file.managed:
    - name: /etc/redis.conf
    - source: salt://redis_cluster/templates/redis_master.conf.j2
    - user: redis
    - group: redis
    - mode: '0644'
    - template: jinja
    - defaults:
        MAX_RAM_LIMIT: 100M
        LISTEN_PORT: 6001
        NODE_IPV4: {{ grains['fqdn_ip4'][0] }}
    - require:
      - pkg: redis_package

enable_redis_service:
  service.running:
    - name: redis
    - enable: True
    - watch:
      - file: apply_redis_config
EOF

The accompanying configuration template strips unnecessary comments and maps critical parameters to the Jinja variables defined in the state file.

cat > /srv/salt/prod/redis_cluster/templates/redis_master.conf.j2 << 'EOF'
bind {{ NODE_IPV4 }}
protected-mode yes
port {{ LISTEN_PORT }}
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6001.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory {{ MAX_RAM_LIMIT }}
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
EOF

Because the state resides in the production environment rather than the default base directory, explicitly declare the saltenv parameter during execution.

salt 'node-1' state.sls redis_cluster.master_node saltenv=prod test=True
salt 'node-1' state.sls redis_cluster.master_node saltenv=prod

Tags: SaltStack zabbix-agent Redis configuration-management jinja-templating

Posted on Wed, 20 May 2026 06:30:43 +0000 by gatoruss