Neden Network Otomasyonunda Ansible Kullanıyorum?

Neden Network Otomasyonunda Ansible Kullanıyorum?

Uzun bir süredir network otomasyonu ve Ansible ile ilgili farklı şirketlerle çalışıyorum ve bu alanda eğitimler de veriyorum. Bu aşamalarda alternatifleri arasından, Ansible’ın neden benim ve birçok şirketin tercihi olduğunu, network otomasyonunda neden tercih edileceğini ve sağladıklarını bu yazı ile özetlemeye çalışıyorum. Bu yazı dizisinin ilerleyen bölümlerinde yine Ansible ile ilgili ağ otomasyonu tarafında teknik olan-olmayan birçok konudan bahsedeceğim.

Network sistemlerinin büyümesi cihaz sayısının artmasıyla sonuçlanırken, çok sayıda cihazın yönetimi aynı işin bir kişi tarafından tekrar tekrar yapılmasıyla sonuçlanabiliyor. Bu bariz bir şekilde zaman kaybı olabilirken, üstüne bir de ayarları yapan operatörün onlarca/yüzlerce, hatta bazen de binlerce cihaza aynı/benzer ayarları girerken kafasının karışabileceği, dikkatinin dağılabileceği gibi insani etkenler girince bütün cihazlara aynı işlem yapılsa bile aralarından bir tanesinde eksik, fazla veya yanlış ayar girilince farklılık oluşması mümkün oluyor. Bu farkların bulunması da bazı durumlarda tüm cihazların kontrolünü dahi gerektirebileceği için mühendislerin çok fazla zamanını alabiliyor. Tüm bu hata bulma ve çözme süreçleri sırasında, sözkonusu hata bir kesintiye yol açtıysa başa gelebilecek zararlar ise birçok ekibi değişiklik yapmaktan çekinir hale getirebiliyor.

Bazen tüm ayarlar doğru yapılsa bile, yapılan bazı değişiklikler istenen sonucu vermeyebiliyor veya günü kurtarmak için/geçici değişiklikler olabiliyor. Bu değişikliklerin de daha sonra geriye alınması gerekiyor. Geriye alma işlemi sırasında da, biraz önce bahsettiğimiz tüm riskler tekrar ortaya çıkıyor. Bazen de, “Dün a.b.c.d IP adresine ICMP echo isteği (ping) gönderip cevap alırken bugün onu dahi yapamıyorum” gibi istekler geldiğinde, son 1 gün içinde hangi network operatörünün hangi değişiklikleri yaptığını detaylıca görmek, sorunun kaynağını bulmayı ve çözmeyi oldukça hızlandırabiliyor. Ayrıca, ilgili gün ve saate ait ayarı seçerek tüm network altyapısını o anki ayarlara döndürme şansı da böyle durumlar için sistemi kurtarıcı işlev görebiliyor.

Ansible’ın Sağladıkları

Ağ içerisinde bulunan cihaz sayısı çok arttığında, yapıdan ve yöneten kişilerden bağımsız olarak bu cihazların yönetimi veya bazen sadece bir güvenlik/bugfix güncellemesi dahi ciddi zamanlar alabildiği için, enerjisini tamamen aynı işe harcayan daha fazla insanın bu iş üzerinde çalışması gerekebiliyor. Orkestrasyon, bu işlemlerin birden çok sayıda cihaza yapılmasıyla gerçekleştiği için, 100 cihaz için de 1000 cihaz için de aynı sayıda mühendis bir Ansible komutuyla tüm cihazlarda aynı değişikliği başlatabiliyor. Cihazları isterse gruplar halinde, 5’er 5’er veya 10’ar 10’ar da güncelleyebiliyor.

Networkler üzerinde yer alan cihazların teker teker uğraşmadan, ortak bir noktadan kontrol edilebilmesi; istenen komutların çalıştırılabilmesi ve çıktılarının alınabilmesi gibi süreçlerde network otomasyon araçları devreye giriyor. Bunların arasında açık kaynaklı ve GPL-3.0 lisanslı olan Ansible sık kullanılan çözümler arasında geliyor. Ansible’ın declarative yapısı sayesinde desteklenen çok sayıda cihaz ve komutta, aynı ayarları tekrar tekrar uygulasak bile Ansible cihazlara bağlanıp çalışan config’e bakıyor, eğer elinde yer alan ayarlarla aynıysa hiçbir işlem yapmadan diğer cihazlara geçiyor. Bir farklılık görürse de düzeltiyor. Bu sayede, herhangi bir sebepten ayarları bozulan/değiştirilen bir cihaz olduğunda içinde neler değişmiş diye elle kontrol etmekle uğraşmadan, işi Ansible’a bırakarak hızlıca önceki çalışır haline döndürülebiliyor. Tüm bunlara ek olarak, yeni bir cihaz alındığında base configuration dahil olmak üzere tüm ayarların tek bir Ansible komutu ile o cihaza da girilmesi sağlanabiliyor.

Ansible birçok kişi tarafından sistem yöneticilerinin kullandığı bir araç olarak bilinse de, özellikle son yıllarda Ansible için network otomasyonu ile sistem otomasyonu arasında pek fark kalmamış durumda. Bu tarafta yapılan çalışmalar ve işbirlikleri, networklerin de sistemlerle benzer şekilde otomasyona tutulabilmesini, orkestrasyonunu, konfigürasyon yönetimini yapabilmemizi ve bunları hem declarative hem de bir sürüm kontrol sistemi üzerinde yapabilmemize imkan sağlıyor.

Ansible, birçok network cihazı üzerindeki entegrasyonu, anlaşılması basit ve güzel duran YAML formatı kullanılması sebebiyle kolay yazımı, template desteği ile de dinamik olarak dosya üretimini destekliyor. Ayrıca, bağlanacağı cihazlar üzerinde bir agent gerektirmediği için karşı taraftaki cihazlara herhangi bir kurulum gerekmiyor. Normalde bağlantısını SSH üzerinden yapsa da, istersek (tercih etmesek de) Ansible’ı telnet veya farklı bağlantı yöntemleri üzerinden network cihazlarına bağlanıp istediklerimizi yapması üzerine ayarlayabiliyoruz.

Network otomasyonu, orkestrasyonu ve konfigürasyon yönetimi, bahsettiğimiz özellikleri yazdığımız dosyalarla sağlanabildiği için bu dosyaları yedeklemek de bir kopyala-yapıştır sürecinden ibaret oluyor. Hatta bu dosyaları git gibi bir sürüm kontrol sistemine vererek, kimin hangi tarih ve saatte hangi dosyada hangi değişikliği yaptığını tutmak ve istenen sürüme geri dönmek oldukça kolay ve takip edilebilir bir hal alıyor.

Arayüz ve Sonuç

Tüm bu süreçleri bir web arayüzü üzerinden kontrol etmek, rol bazlı erişim kontrolü (RBAC), kimin ne zaman hangi işi çalıştırdığı ve daha detaylı süreç takibi gibi birçok ekstra özellik için Ansible Tower veya onun açık kaynaklı ve Apache-2.0 lisanslı upstream’i olan AWX projesi kullanılarak yönetilebilir, ölçeklenebilir, izlenebilir, dağıtık versiyon kontrolüne sahip, otomatize edilmiş bir sistem elde edilebiliyor.

Sonraki yazılarda, bu yazıdaki bazı kavramların açıklamalarına, önemine ve neden hayatımızda yer alması gerektiğine değinerek teknik örneklere doğru ilerleyeceğiz. Güncellemeler ve detaylar için Twitter üzerinden @gurayyildirimTR hesabından bana ulaşabilirsiniz. Ansible ve network otomasyonu ile ilgili paylaşmak istediğiniz tecrübeleriniz varsa onları da dinlemek isterim.

TODO: declarative network konfigürasyonu nedir? imperative nedir? ne farkı var? Hangisini ne zaman tercih etmeliyiz? Şu anki network ayar yönteminden neden kaçmalısınız?

MPLS VPN ile multi tenancy saglanabiliyor. Ayni cografi olarak dagitik network uzerinden birden cok firma izole olarak haberlestirilebiliyor. Arkada BGP kullaniyor. Route ekleyerek birini tum networke eristirmeden sadece belirli kullanicilara eristirmek de mumkun.

Ansible’in temel bileseenleri

Ansible kurulumu direkt paket yoneticinden veya pip ile yapilabilir. Son surum icin geeneelde pip kurulumu veya kaynaktan kurulum onerilir.

/etc/ansible/ansible.cfg dosyasi uzerinden ayarlar yapiliyor. Projenin bulundugu dizinde ansible.cfg ismiyle ozel ayarlar da yapilabilir. Hem butunluk saglar hem versiyonlama kolaylasir. gathering=explicit -> otomatik gathering kapatilir, setup modulu ile zaman kaybi eengellenir cunku networkte istegi yapan cihazddan fact alacak ve ona ihtiyac yok. Sureci de kisaltmis olur. inventory=inv.yml -> varsayilanda hosts, burdan default deger degistirilebilir -> https://docs.ansible.com/ansible/latest/plugins/inventory/yaml.html retry_files_enabled=False -> Cok fazla cihaz olmadigi surece asiri zaman almadigi icin kapatilabilir.

Inventory yeni surumlerde YAML formatinda olabiliyor, eski surumlerde INI formatindaydi.

group_vars dizini ozel bir isimde, bunun icinden degiskenler otomatik olarak alinacak. Mesela routers.yml dosyasi otomatik olarak routers grubundaki hostlara uygulanir.

Cihazlardan network VPN config alip ekranda gosterecek playbook;

---
- name: "PLAY 1: aciklamasi"
  hosts: routers
  connection: network_cli
  tasks:
    - name: "TASK 1: Get VRF configuration"
      ios_command:
        commands: "show running-config | section vrf definition"
      register: cli_result
    
    - name: "TASK 2: Print information"
      debug:
        msg: "{{ cli_result }}"

Ansible doc ile sitedekiyle aynı şekilde ve offline olarak da dokümantasyonlar görüntülenebilir;

ansible-doc ios_command

Return values kısmından stdout kullanılarak çıktılar JSON’dan daha düzenli olarak liste şeklinde de alınabilir. cli_result.stdout veya cli_result['stdout'] şeklinde ulaşılabilir.

Dosyaya düzgün çıktı alabilmek için üstteki playbookta yer alan playlere ekleme yapılır:

    - name: "Create outputs directory"
      file:
        path: "outputs"
        state: directory
      run_once: true

Sonda yer alan run_once, dizin oluşturmanın her host için tekrar tekrar çalışmasını önler. Çıktıyı dosyaya kopyalamak için de:

    - name: "Put output to a file"
      copy:
        content: "{{ cli_result.stdout[0] }}\n"
        dest: "outputs/{{ inventory_hostname }}.txt"

inventory_hostname ismi özel bir değişken ve o an çalışılan hostu yerine yazar.

Infrastructure as Code üzerindeki önemli avantajlardan biri de soyutlama. Her marka ve model için ayrı komut satırı arayüzleri öğrenmeden az veya fazla bir soyutlama ile ortak bir erişim ve yönetim arayüzü sağlamalı.

network_clı modülü kullanılarak marka-model bağımsız olarak ona sadece komutlar verilip çalıştırması ve idempotency takibi yapması istenebilir. Bağlandığı cihazın hangi OS’e sahip olduğunu ansible_network_os değişkeninden anlar.

Ansible içinde bulunan lookup fonksiyonu ile template rendering otomatik yapılmayan yerlerde elle rendering tetiklenebilir. Örnek

  cli_config:
    config: "{{ lookup('template', vpn_paths) }}"

ios_vrp gibi modüller Jinja2 kullanımını ortadan kaldırıp bir değişken yapısını alarak kendileri config üretebiliyor. Bunlar işi daha da kolaylaştırıp rahatlatıyor.

Python ile Ansible üzerine özel filtre yazabilmek için yazılan dosyaların konumu ansible.cfg dosyasında filter_plugins ile belirtilir. plugins/filter bunun geleneksel hali. Bunun içindeki Python kodunda bir sınıf içinde @staticmethod kullanılabilir çünkü bu işlem için sınıfın başlatılması gerekmez. filters methodu ile kullanılacak filtreler tanımlanır ve o methodlardaki filtreler Ansible içerisinde kullanılabilir hale gelir.

Ansible üzerinde hem network cihazları hem de normal işlemlerde, assert ve that kullanılarak unit test gerçekleştirilebilir. Özellikle elle yazılan custom filters için unit testlerin yazılması hataların önlenmesi için kritik önem taşıyor.

Desired state-current state ayrımı yapılırken Python’un set yapısı kullanılabilir.

Ansible Galaxy üzerinde yer alan projelere role deniyor ve roles/ dizini altına kuruluyor. ansible-network.network-engine rolü yüklenirse network ile ilgili birçok özelliği direkt getiriyor ve çoğu yerde filtre yazmaktan kurtulmayı sağlıyor.

ansible-lint ile Ansible üzerinde stil kontrolü yapılabiliyor. Make komutuyla birleştirilebilir, bu komut içerisinde linting, unit test ve en son da run işlemi yapılabilir. Bunların ayrı ayrı çalıştırılması da mümkün olur.

>>> topics = r.html.find(selector='body > div.content > div.forum > ul')[0]
>>> basliklar = [entry.find('h3')[0].text for entry in entries if entry.find('h3')]
>>> t = entries[10]
>>> t.text
'MİGROS Kampanya ve Fırsatları -ANA KONU-\nsrdrgkdmr, 1 dk.\nSon Mesaja Git\nFavorilere Ekle\n�ikayet Et```\nYanıtla\nKonuyu Gizle'

1 apk updatee 2 apk update 3 apk add python3 py3-pip 4 pip3 install telegram 5 pip3 install requests-html 6 apk add gcc libxml2-deev 7 apk add gcc libxml2-dev 8 pip3 install requests-html 9 apk add musl-dev 10 pip3 install requests-html 11 apk add python-dev 12 apk add python3-dev 13 pip3 install requests-html 14 apk add libxml-dev 15 apk add xmllib-dev 16 apk search libxml 17 apk add libxml2-dev 18 pip3 install requests-html 19 apk add libxml1 20 apk add libxml 21 apk add libxml2 22 apk add py3-libxml2 23 pip3 install requests-html 24 apk add libxslt-dev 25 pip3 install requests-html 26 histo 27 history