Ansible dinamik envanter
Dinamik envanter?
Ansible host dosyasını sistemlerimizdeki her değişiklikte güncelleyeceksek işimiz iş demektir. Ancak Ansible bizim için bu durumu da öngörmüş ve çeşitli imkanlar sağlamış. Tabi biz her zaman AWS (ya da benzeri bir yapı) ile çalışacak değiliz.
Özelleştirilmiş?
Özelleştirilmişten kasıt kendi üretimimiz, el emeğimiz, python scriptimiz (ya da istediğiniz bir dil) olacak. Aslında çok basit, Ansible envanter olarak spesifik bir formata uygun json çıktısı bekliyor. Jeff Geerling bloğunda bu beklentiyi karşılamanın yolunu şöyle göstermiş:
{
"group": {
"hosts": [
"192.168.28.71",
"192.168.28.72"
],
"vars": {
"ansible_ssh_user": "johndoe",
"ansible_ssh_private_key_file": "~/.ssh/mykey",
"example_variable": "value"
}
},
"_meta": {
"hostvars": {
"192.168.28.71": {
"host_specific_var": "bar"
},
"192.168.28.72": {
"host_specific_var": "foo"
}
}
}
}
Sonra bu basit iş için aşırı kompleks bir kod önerisinde bulunmuş - ki bence hiç gerek yok. Biz daha sadesini üreteceğiz. Unutmayın, ihtiyacımız yukarıdaki gibi bir çıktı almak.
#!/home/gunhan/anaconda3/bin/python
from collections import defaultdict
import pandas as pd
import json
# envantere ait bilgiler
df = pd.DataFrame(
{'equipip': {0: '10.0.0.1', 1: '10.0.0.2', 2: '10.0.0.3', 3: '10.0.0.4', 4: '10.0.0.5'},
'username': {0: 'admin', 1: 'admin', 2: 'root', 3: 'admin', 4: 'admin'},
'pwd': {0: 'Hu@w31', 1: 'Actelis1', 2: 'ETZ', 3: 'Hu@w31', 4: 'Hu@w31'},
'hostname': {0: 'sw01', 1: 'dslam01', 2: 'msan01', 3: 'sw02', 4: 'sw03'},
'vend': {0: 'Huawei', 1: 'Actelis', 2: 'ZTE', 3: 'Huawei', 4: 'Huawei'}}
)
# bir iki döngü ile sözlüğü dolduruyoruz
env = defaultdict(dict)
for make in df.vend.unique():
env[make]['hosts'] = df[df.vend == make].equipip.tolist()
env[make]['vars'] = {"ansible_ssh_user": df[df.vend == make]['username'].unique()[0]}
env["_meta"]["hostvars"] = defaultdict(dict)
for ind, row in df.iterrows():
env["_meta"]["hostvars"][row['equipip']]["password"] = row['pwd']
# sonra da sözlüğü ekrana json formatına uygun bir şekilde yazdırıyoruz
print(json.dumps(env))
Yukarıdaki örnekte pandas kullanmamın sebebi cihazlarla ilgili bilgileri bir yerden (örn excel dosyası ya da sql sorgusu) çektiğimizi farzetmem. DataFrame içeriği sql ile çekilmiş veriler de olabilirdi:
pd.read_sql("select top 10 * from devicetable", pymssql.connect(*args))
df içeriği aşağıdaki gibi gözüküyor:
>>> df
equipip hostname pwd username vend
0 10.0.0.1 sw01 Hu@w31 admin Huawei
1 10.0.0.2 dslam01 Actelis1 admin Actelis
2 10.0.0.3 msan01 ETZ root ZTE
3 10.0.0.4 sw02 Hu@w31 admin Huawei
4 10.0.0.5 sw03 Hu@w31 admin Huawei
Burada önemli olan envanter dosyası çalıştırıldığında yeni bilgileri alıp sözlük içine atması.
Scripti yazdıktan sonra dosyanın çalıştırılabilir olmasına dikkat edelim. chmod +x inventory.py
Sonra da ansible’ı çalıştıralım:
/usr/bin/ansible -i inventory.py Huawei -m ping
Sonuç:
10.0.0.4 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.4 port 22: Connection timed out\r\n",
"unreachable": true
}
10.0.0.5 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.5 port 22: Connection timed out\r\n",
"unreachable": true
}
10.0.0.1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.1 port 22: Connection timed out\r\n",
"unreachable": true
}
Leave a comment