i have created a saltstack template file where i want to replace a variable with the servers ipv4 address:
in my test.template file i have:
Address {{ grains['fqdn_ip4'] }}
in my init.sls i have:
/opt/test/test.conf:
file.managed:
- source: salt://test/test.template
- template: jinja
- user: root
- group: root
- mode: 0644
so the problem is, that the variable is replaced with the correct ip address but not in the correct format:
Address ['111.111.111.111']
instead of:
Address 111.111.111.111
so my question: how can i remove the [' and '] form the replacement?
Solution:
Address {{ grains['fqdn_ip4'][0] }}
Result:
Address 111.111.111.111
Related
I am trying to using Salt state files to configure network devices. I will briefly describe my current setup:
I have pillar ntp.sls file saved as /etc/salt/pillar/ntp.sls and it looks like this:
ntp.servers:
- 11.1.1.1
- 2.2.2.2
Then I have Jinja template saved as /etc/salt/states/ntp/templates/ntp.jinja and looks like this:
{%- for server in servers %}
ntp {{ server }}
{%- endfor %}
Finally I have state file saved as /etc/salt/states/ntp/init.sls as this:
ntp_example:
netconfig.managed:
- template_name: salt://ntp/templates/ntp.jinja
- debug: true
- servers: {{ salt.pillar.get('ntp.servers') }}
I am getting the following error while trying to run the command: sudo salt sw state.sls ntp, where sw is the proxy minion, so here is the error:
sw:
Data failed to compile:
ID ntp.servers in SLS ntp is not a dictionary
Command to get data from pillar is working, command: sudo salt sw pillar.get ntp.servers
Output:
sw:
- 11.1.1.1
- 2.2.2.2
Any suggetions what could be wrong and how to fix it?
Thanks
I think you should declare in /etc/salt/pillar/ntp.sls something like:
ntp-servers:
- 11.1.1.1
- 2.2.2.2
and than load these values with:
- servers: {{ salt.pillar.get('ntp-servers') }}
The . is a directory separator in SaltStack.
I am currently trying to deploy Log-rhythm out into our environment that consists of 100+ Servers with the help of SaltStack:
While I am able to copy files over to a Windows minion with the use of file.managed, I am facing some difficulty in the process getting the IP Address of the minion server and adding this both to the .ini file and cmd.run file.
I would like to be able to do this for each minion that is connected to Salt:
While running salt -G 'roles:logging' state.apply. I seem to be getting the following error:
Rendering SLS 'base:pacakage-logrhythm' failed: Jinja variable 'dict object' has no attribute 'fqdn_ip4':
UPDATE:
I was able to resolve the issue within the ini files: by placing the following
ClientAddress={{ grains['fqdn_ip4'][0] }}
currently having issues with passing grains into the cmd.run section of the program:
create_dir:
file.directory:
- name: C:\logrhythm
/srv/salt/logrhythm/proxy1.ini:
file.managed:
- source: salt://logrhythm/proxy1.ini
- name: c:\logrhythm\proxy1.ini
- template: jinja
/srv/salt/logrhythm/proxy2.ini:
file.managed:
- source: salt://logrhythm/proxy2.ini
- name: c:\logrhythm\proxy2.ini
- tempalte: jinja
LRS_File:
file.managed:
- name: c:\logrhythm\LRSystemMonitor_64_7.4.2.8003.exe
- source: salt://logrhythm/LRSystemMonitor_64_7.4.2.8003.exe
LRS_Install:
cmd.run:
- name: 'LRSystemMonitor_64_7.4.2.8003.exe /s /v" /qn ADDLOCAL=System_Monitor,RT_FIM_Driver HOST=<> SERVERPORT=443 CLIENTADDRESS={{ grains[''fqdn_ip4''][0] }} CLIENTPORT=0"'
- cwd: C:\logrhythm
I think it should work. You may have a problem with the multiple quotes you use: simple then double then simple. Trying removing the simple quotes englobing all the command and the two simple for accessing the grains dict.
- name: LRSystemMonitor_64_7.4.2.8003.exe /s /v" /qn ADDLOCAL=System_Monitor,RT_FIM_Driver HOST=<> SERVERPORT=443 CLIENTADDRESS={{ grains['fqdn_ip4'][0] }} CLIENTPORT=0"
Having this structure in /srv/salt/pillar/servers.sls
servers:
# Monitors
- m1:
- roles: [ monitor ]
- ips: [ 192.168.0.1 ]
- b2:
- roles: [ monitor ]
- ips: [ 192.168.0.2 ]
# BPs
- w2:
- roles:
- webserver:
- type: [ apache ]
- ips: [ 192.168.0.3 ]
I want to use that information in my top.sls file.
How can I select for instance the servers that have the monitor role? Or the servers that have type apache?
base:
'*':
- common
{% Filter the servers that have the rol monitor %}
- mon
{% endfor %}
{% Filter the servers that have the type apache %}
- web_apache
{% endfor %}
According to the documentation, this works:
# Any minion for which the pillar key 'somekey' is set and has a value
# of that key matching 'abc' will have the 'xyz.sls' state applied.
'somekey:abc':
- match: pillar
- xyz
...but I don't think it suits your use case. Your "roles" item is a list, and I'm guessing you want something more like "if any item in that list is "monitor", apply state X. That won't work this way.
I'm pretty sure your approach is flawed. Instead of using a pillar file to map servers to roles and from there to states, just do it directly in top:
base:
'*':
- common
'm*':
- mon
'w*':
- web_apache
That's top's intended purpose, after all. If your minion IDs don't fit nicely into globs, look into nodegroups as an alternative.
I need to access custom grains in my config files using Jinja templating. Here are my files.
[root#localhost salt]# cat my_config.conf
{{ grains['ip'] }}
[root#localhost salt]# cat test_jinja.sls
/root/my_config.conf:
file.managed:
- source: salt://my_config.conf
- user: root
- group: root
- mode: '0644'
- makedirs: True
- force: True
- template: jinja
[root#localhost salt]# salt-ssh 'my-ip' state.sls test_jinja
10.225.253.134:
----------
ID: /root/test
Function: file.managed
Result: False
Comment: Unable to manage file: Jinja variable 'dict object' has no attribute 'ip'
Started: 12:57:49.301697
Duration: 33.039 ms
Changes:
[root#localhost salt]# cat /etc/salt/roster
my-ip: # The id to reference the target system with
host: xx.xx.xx.133 # The IP address or DNS name of the remote host
user: root # The user to log in as
passwd: teledna # The password to log in with
grains:
ip: 'xx.xx.xx.133'
How to access the grains in the config files using salt-ssh???
This looks like this is a bug in salt, where the grains from the roster aren't shipped over to the minion, can you try this PR?
https://github.com/saltstack/salt/pull/40775
The reason is that there is no 'ip' grain.
To list all grains use salt '*' grains.items
Is salt caching /etc/hosts?
I'm in a situation where I change /etc/hosts such that the FQDN points to the external IP address instead of 127.0.0.1
The problem is that in the first run, the fqdn_ipv4 stays 127.0.0.1 and I need to rerun salt '*' state.highstate to get the right values. This leads to problems like this, which cost me a lot of time.
Is salt rendering everything before execution (or caches DNS)? How do I address this problem?
The state file looks like this:
127.0.0.1:
host.absent:
- name: {{ nodename }}
- ip: 127.0.0.1
127.0.1.1:
host.absent:
- name: {{ nodename }}
- ip: 127.0.1.1
{% for minion, items in salt['mine.get']('environment:' + environment, 'grains.item', expr_form='grain')|dictsort %}
{{ minion }}:
host.present:
- ip: {{ items['ip_addr'] }}
- names:
- {{ minion }}
- {{ minion.split('.')[0] }}
{% endfor %}
And the code that uses the IP looks like this:
{% set ipv4 = salt['config.get']('fqdn_ip4') -%}
# IP Address that Agent should listen on
listening_ip={{ ipv4[0] }}
Salt is caching the values of grains. Therfore the salt['config.get']('fqdn_ip4') will retrieve the value from the beginning of the script.
Use the following in your state file to refresh the grain information:
refreshgrains:
module.run:
- name: saltutil.sync_grains
Salt will render the state before executing it, so you might not be able to use any new grain information inside the state file itself.
But you will be able to use the new grain values in Jinja templates for files. I assume the second code snippet is from a template that is used by Salt's file.managed, so you should be safe here.