SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor

Ansible playbook ve role farkı: ne zaman hangisi seçilmeli

Ansible playbook ve role yapılarının temel farklarını inceleyin. Tek dosyalık playbook ile ölçeklenebilir role dizin yapısı arasındaki geçiş kriterlerini öğrenin.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Ansible playbook ve role: fark nedir

Ansible playbook, ansible-playbook ile çalıştırdığınız dosyadır. Bir grup sunucuyu yapılması gereken işlerle eşleştirir. Ansible role ise görevleri, şablonları, işleyicileri ve varsayılan değişkenleri barındıran, sabit bir dizin yapısına sahip bir yapıdır ve bir playbook tarafından ismiyle çağrılır. Her ikisinin içindeki görev sözdizimi aynıdır, dolayısıyla bu neyi ifade edebileceğinizle ilgili bir soru değildir. Bu, yeniden kullanılabilirlik ile ilgili bir sorudur.

Düz bir playbook ile başlayın. Bir site.yml içinde tutulan bir tasks: listesi, ilk otomasyonunuz için doğru biçimdir ve çoğu kişinin beklediğinden daha uzun süre yeterli olur. Aynı görev bloğunun ikinci bir sunucu grubu için çalıştırılması gerektiğinde veya dosya yaklaşık 100 satırı geçtiğinde ve artık kaydırarak bir görevi bulamadığınızda role yapısına geçiş yapın.

Henüz bir tane yazmadıysanız, tek bir VPS üzerinde ilk playbook ile başlayın ve dosyanız büyümeye başladığında tekrar buraya dönün.

Düz bir playbook ne zaman doğru tercihtir

İşlem tek seferlikse, tek bir sunucu üzerinde gerçekleşiyorsa veya playbook başka kimse tarafından okunmayacaksa düz bir playbook kullanımı doğrudur. Tek bir uygulama sunucusunun provizyonu veya bakım penceresi öncesinde bir sistemin yamalanması gibi durumlar, bir dizin ağacı oluşturmayı gerektirmez. Bir rol; yedi dizin ve bir dolaylı katman ekler. Eğer rolü çağıran tek yer yanındaki playbook ise, bu dolaylı katman hiçbir fayda sağlamaz; aksine, gerçekte neyin çalıştığını görmek istediğiniz her seferinde fazladan bir dosya açmanıza neden olur.

Düz bir playbook'un doğru tercih olmaktan çıktığı an bellidir ve bu anı tespit etmek kolaydır. Bir görev bloğunu ikinci bir playbook'a kopyaladığınız an, o an gelmiştir. O andan itibaren her düzeltmenin iki kez yapılması gerekir ve bir gün mutlaka sadece bir kez yapılacaktır.

Bir rol dizini aslında neleri barındırır

roles/common/
  defaults/main.yml
  vars/main.yml
  tasks/main.yml
  handlers/main.yml
  templates/99-hardening.conf.j2
  files/
  meta/main.yml
  • tasks/main.yml giriş noktasıdır. Ansible, rol çağrıldığında bu dosyayı çalıştırır; diğer tüm dizinler isteğe bağlıdır.
  • defaults/main.yml, çağrı yapanın geçersiz kılması beklenen değişkenleri tutar. Ansible'da en düşük önceliğe sahip kaynak olduğu için neredeyse her şey bunun önüne geçer.
  • vars/main.yml, çağrı yapanın geçersiz kılmaması beklenen değişkenleri tutar. Öncelik açısından envanterin üzerinde yer alır ki bu oldukça güçlü bir ifadedir. Nadiren kullanın.
  • handlers/main.yml, notify tarafından tetiklenen görevleri tutar. Bir handler, kaç görev tarafından bildirilirse bildirilsin, oyunun (play) sonunda bir kez çalışır.
  • files/, copy modülü tarafından olduğu gibi kopyalanan dosyaları; templates/ ise template modülü tarafından işlenen Jinja2 şablonlarını tutar. Bir rol içerisinde her ikisine de yol belirtmeden sadece dosya adıyla referans verirsiniz, çünkü Ansible öncelikle rolün kendi dizinlerinde arama yapar.
  • meta/main.yml, rol bağımlılıklarını ve Ansible Galaxy'nin okuduğu meta verileri tanımlar.

Bu düzen bir stil tercihi değildir. Ansible tam olarak bu yollara bakar, dolayısıyla roles/common/template/ (tekil) içine koyduğunuz bir şablon asla bulunamaz.

ansible-galaxy init ile ortak rolü oluşturun

mkdir -p ~/infra/roles
cd ~/infra
ansible-galaxy init --init-path roles common

Bu komut, kullanmayacağınız dizinler ve yalnızca --- içeren main.yml taslakları dahil olmak üzere tüm iskeleti roles/common altında oluşturur. Boş bıraktıklarınızı silin. Boş bir vars/main.yml dosyası Ansible için bir sorun teşkil etmez ancak rolde hangi dosyaların gerçekten önemli olduğunu gizler.

Şimdi işlevsel dosyaları doldurun. Önce varsayılanları (defaults) tanımlayın, çünkü bunlar rolün genel arayüzüdür.

# roles/common/defaults/main.yml
---
common_packages:
  - ufw
  - fail2ban
  - unattended-upgrades
common_admin_group: admins
common_permit_root_login: "no"
common_password_authentication: "no"

"no" ve "yes" değerlerini tırnak içine alın. Ansible, YAML dosyalarını PyYAML ile ayrıştırır; bu kütüphane çıplak bir no ifadesini boolean false olarak okur. Bu durumda oluşturulan yapılandırma satırı PermitRootLogin False haline gelir ve sshd bunu reddeder. Tırnak işaretleri, değerin string olarak kalmasını sağlar.

# roles/common/tasks/main.yml
---
- name: Install the base packages
  ansible.builtin.apt:
    name: "{{ common_packages }}"
    state: present
    update_cache: true
    cache_valid_time: 3600

- name: Create the admin group
  ansible.builtin.group:
    name: "{{ common_admin_group }}"
    state: present

- name: Install the sshd hardening drop-in
  ansible.builtin.template:
    src: 99-hardening.conf.j2
    dest: /etc/ssh/sshd_config.d/99-hardening.conf
    owner: root
    group: root
    mode: "0644"
    validate: /usr/sbin/sshd -t -f %s
  notify: Restart sshd
# roles/common/handlers/main.yml
---
- name: Restart sshd
  ansible.builtin.service:
    name: ssh
    state: restarted
# roles/common/templates/99-hardening.conf.j2
# Managed by Ansible. Local edits are overwritten on the next run.
PermitRootLogin {{ common_permit_root_login }}
PasswordAuthentication {{ common_password_authentication }}

Debian ve Ubuntu sistemlerinde systemd birimi ssh olarak adlandırılırken, RHEL ailesi sistemlerde bu isim sshd şeklindedir. Yanlış ismi kullanan bir handler, yalnızca şablonda bir değişiklik yapıldığında hata verir; bu nedenle sorun genellikle haftalar sonra ortaya çıkar.

validate satırı, bu görevdeki en yararlı kısımdır. Ansible şablonu geçici bir dosyaya işler, %s yerine bu dosyanın yolunu koyar ve komutu çalıştırır. Hedef dosya, yalnızca komut 0 çıkış koduyla tamamlanırsa değiştirilir. Şablona anlamsız bir direktif ekleyip tekrar çalıştırın: görev failed to validate hatasıyla başarısız olur, gerçek /etc/ssh/sshd_config.d/99-hardening.conf dosyasına dokunulmaz ve sunucuya giriş yapmaya devam edebilirsiniz. Bu kontrolün sadece sözdiziminden (syntax) fazlasını test ettiğini unutmayın. Eğer sshd -t ana bilgisayar anahtarlarını okuyamazsa sshd: no hostkeys available -- exiting. ile çıkar ve Ansible aynı failed to validate hatasını raporlar; bu yüzden şablonu suçlamadan önce modülün msg kısmını okuyun.

Bir playbook'un rol çağırma yöntemi

# site.yml
---
- name: Base configuration for every server
  hosts: all
  become: true
  roles:
    - common
# inventory.ini
[local]
localhost ansible_connection=local
ansible-playbook -i inventory.ini site.yml

Play, özet kısmında failed=0 ile sonlanmalıdır. Parametreleri çağrı noktasında genişletilmiş biçimle geçin; bir rolün iki farklı ana makine grubuna bu şekilde hizmet vermesi sağlanır:

  roles:
    - role: common
      common_admin_group: ops
      common_permit_root_login: prohibit-password

Neredeyse herkesi şaşırtan tek bir sıralama kuralı vardır. Bir play; pre_tasks, roles, tasks ve post_tasks içerebilir ve Ansible, bunları dosyada hangi sırada yazarsanız yazın, her zaman bu sabit sırayla çalıştırır. tasks: kısmını roles: kısmının üzerine koysanız bile roller yine de ilk sırada çalışır. Bu nedenle, bir işlemin rolden önce gerçekleşmesi gerekiyorsa, bu işlem tasks: dosyasının en üstünde değil, pre_tasks: içinde yer almalıdır.

- name: Ordering demonstration
  hosts: local
  gather_facts: false
  pre_tasks:
    - name: Runs first
      ansible.builtin.debug:
        msg: pre
  roles:
    - common
  tasks:
    - name: Runs after the role
      ansible.builtin.debug:
        msg: task
  post_tasks:
    - name: Runs last
      ansible.builtin.debug:
        msg: post

Bir rolü roles: anahtarı yerine görev listesi içinden çağırmak için import_role veya include_role kullanın.

  tasks:
    - name: Static, read when the playbook is parsed
      ansible.builtin.import_role:
        name: common

    - name: Dynamic, resolved when the task runs
      ansible.builtin.include_role:
        name: postgres
      when: "'db' in group_names"

import_role statiktir. Ansible rolü ayrıştırma (parse) aşamasında okur ve görevleri play'in bir parçası haline getirir; bu nedenle ansible-playbook --list-tasks site.yml bu görevleri listeler ve import işlemine eklenen bir etiket, rol içindeki her göreve uygulanır. include_role dinamiktir. Görev çalışana kadar hiçbir şey okunmaz; bu da rol ismini bir değişken veya döngü ile belirlemenize olanak tanır. Bunun bedeli ise, söz konusu görevlerin --list-tasks ve --start-at-task tarafından görülememesidir.

Burada bir tuzak mevcuttur. Bir include_role görevi üzerindeki when:, dahil edilen rolün defaults/main.yml kapsamına girmeden önce değerlendirilir. when: common_packages | length > 0 ifadesini include üzerine yazarsanız, söz konusu değişken tam olarak dahil ettiğiniz rolün içinde tanımlanmış olsa bile çalışma 'common_packages' is undefined hatasıyla durur. Bunun çözümü, anahtarı rolün dışına taşımaktır: değişkeni, her yerde kapsam dahilinde olan group_vars/all.yml içine yerleştirin ve rolün kendi varsayılanlarını, rolün bizzat tükettiği değerler için bırakın.

Hangi değişken önceliklidir: defaults, group_vars, vars, extra vars

Ansible, yirmiden fazla değişken öncelik seviyesi tanımlar. Bunlardan dördü, pratikteki hemen hemen tüm çakışmaları çözer; aşağıda en zayıftan en güçlüye doğru sıralanmıştır.

  • roles/<name>/defaults/main.yml hiyerarşinin en alt kısımlarında yer alır. Başka herhangi bir yerde tanımladığınız hemen hemen her şey bunun önüne geçer; bu nedenle bir rolün ayarlanabilir parametreleri için en doğru yer burasıdır.
  • group_vars/ ve host_vars/ orta seviyededir. Sitenize özgü değerler burada yer almalı ve rol varsayılanlarını temiz bir şekilde geçersiz kılmalıdır.
  • roles/<name>/vars/main.yml, host_vars seviyesinin üzerindedir. Buraya yazdığınız bir değer, envanter üzerinden geçersiz kılınamaz. Burayı, rolün kendi içinde tutarlı kalması gereken durumlar için ayırın; örneğin, servis ismiyle eşleşmesi zorunlu olan bir paket ismi gibi.
  • Çağrı noktasında iletilen bir rol parametresi vars/main.yml değerini yener; komut satırındaki -e ise rol parametreleri dahil her şeyin önüne geçer.

Bu öncelik sırasının nasıl işlediğini bir dakika içinde gözlemleyebilirsiniz. Küçük bir role bir varsayılan ve bir rol değişkeni atayın, ardından aynı isimleri host_vars içinde tanımlayın.

# roles/prec/defaults/main.yml
---
prec_tunable: from-defaults
prec_internal: from-defaults
# roles/prec/vars/main.yml
---
prec_internal: from-rolevars
# host_vars/localhost.yml
---
prec_tunable: from-hostvars
prec_internal: from-hostvars
# roles/prec/tasks/main.yml
---
- name: Show which value survived
  ansible.builtin.debug:
    msg: "tunable={{ prec_tunable }} internal={{ prec_internal }}"
ansible-playbook -i inventory.ini prec.yml
ansible-playbook -i inventory.ini prec.yml -e prec_internal=from-cli

İlk çalıştırma tunable=from-hostvars internal=from-rolevars değerini yazdırır. Envanter, rol varsayılanını yener ancak rol değişkenine karşı kaybeder. İkinci çalıştırma internal=from-cli değerini yazdırır, çünkü extra vars en tepededir ve altındaki hiçbir şey bunu değiştiremez. -e kullanımının tek seferlik işlemler için uygun, ancak kalıcı bir betik için yanlış olmasının nedeni de budur: deponuzdaki tüm planlanmış yapılandırmaları sessizce geçersiz kılar.

Çalışma kuralı şudur: Bir değerin değiştirilebilir olmasını istiyorsanız, onu defaults/ içine koyun. Değeri vars/ içine yerleştirmek, rolü kullanacak herkese envanterin bu değeri değiştiremeyeceğini bildirir. Bu bazen amaçlanan bir durum olsa da, genellikle bir hatadır.

Rolün idempotent olduğunu kanıtlayın: iki kez çalıştırın

Güvenilir bir Ansible çalışması, ikinci kez çalıştırıldığında aynı sonucu üretir ve hiçbir değişiklik yapmadığını raporlar. Playbook'u iki kez çalıştırın ve özet raporu inceleyin.

ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.yml

İkinci özet raporu şu şekilde görünmelidir:

PLAY RECAP *********************************************************************
localhost   : ok=4  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0

changed=0, hiçbir görevin değişiklik bildirmediği anlamına gelir. apt, template ve group gibi modüller için bu, mevcut durumun gerçek bir kontrolüdür; ancak bu sayı, her görevin değişiklik raporlama doğruluğu kadar güvenilirdir: changed_when: false içeren bir görev, aslında ne yapmış olursa olsun değişmemiş olarak sayılır. İkinci çalıştırmada changed=2 görülmesi, iki görevin tekrar değişiklik bildirdiği anlamına gelir. Bu durum, tekrarlanan gerçek bir işlem, yeniden yazılan bir dosya veya her çalıştırmada yeniden başlatılan bir servis olabileceği gibi, hiçbir değişiklik yapmadığını belirtme imkanı olmayan salt okunur bir komut da olabilir. Her iki durumda da özet raporu, sunucuda sapma olup olmadığını size söylemeyi bırakmıştır. Bunun yaygın nedeni command veya shell kullanımıdır, çünkü Ansible rastgele bir komutun ne yaptığını bilemez.

# traps.yml
---
- name: Command modules do not know what they changed
  hosts: local
  gather_facts: false
  tasks:
    - name: This appends a line on every run
      ansible.builtin.shell: "echo run >> /tmp/grow.txt"

    - name: This appends a line only once
      ansible.builtin.shell: "echo run >> /tmp/guarded.txt"
      args:
        creates: /tmp/guarded.txt

Bu playbook'u iki kez çalıştırın ve ardından wc -l /tmp/grow.txt /tmp/guarded.txt içeren satırları sayın. /tmp/grow.txt iki satır, /tmp/guarded.txt ise bir satır içerir. İkinci çalıştırmada korumalı görev hiç yürütülmez: creates modüle önce bakması gereken görünür bir ürün sağladığı için, görev Did not run command since '/tmp/guarded.txt' exists mesajıyla ok raporlar. Bir komut böyle bir ürün bırakmadığında, çıktısını kaydedin ve changed_when ile kararı kendiniz verin.

ansible-playbook --check --diff site.yml, değişiklikleri yapmadan tahmin eder ve --diff, bir şablonun yeniden yazacağı tam satırları yazdırır. Çıktıyı tek bir uyarıyı göz önünde bulundurarak okuyun: düz bir shell veya command görevi kontrol modunda atlanır (creates veya removes ile yalnızca çalışıp çalışmayacağını raporlar) ve check_mode: false olarak işaretlenmiş bir görev, --check altında bile gerçek anlamda çalışır. Bu nedenle temiz görünen bir plan yine de iş gizleyebilir ve kuru çalıştırma (dry run) her zaman kuru olmayabilir.

Özet rapordaki bir sütun daha aynı özeni hak eder: Ansible'ın bağlanamadığı bir sunucu failed yerine unreachable altında sayılır ve görevlerinin hiçbiri çalışmaz; bu nedenle bu rolü birkaç makineden fazlasına yönlendirmeden önce erişilemeyen bir sunucunun tüm çalışmayı durdurup durdurmayacağına önceden karar verin.

Ansible neden rolün bulunamadığını söylüyor

Ansible, roles/ dizinini playbook dosyasının hemen yanında, ardından roles_path içinde arar. Arama işlemi shell dizininize göre değil, playbook dosyasının konumuna göre yapılır.

[ERROR]: The role 'common' was not found in: /home/deploy/lonely/roles:/home/deploy/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:/home/deploy/lonely

Bu mesaj, site.yml ve roles/ dosyalarının birbirinden koptuğu anlamına gelir; Ansible denediği yolları yardımcı olması için yazdırır. Bu ifade ansible-core 2.21 sürümüne aittir; daha eski sürümler the role 'common' was not found in ifadesini küçük harfle ve iki nokta olmadan yazdırır, bu yüzden was not found in üzerinden eşleştirme yapın. İkisini aynı dizinde tutun. Üst dizinden çalıştırmak sorun yaratmaz, çünkü önemli olan playbook yoludur:

ansible-playbook -i infra/inventory.ini infra/site.yml

Aynı sorunun daha sessiz bir versiyonu daha vardır. Ansible, mevcut dizin herkes tarafından yazılabilir (world writable) olduğunda buradaki ansible.cfg dosyasını görmezden gelir. Bunun nedeni, sunucudaki herhangi bir kullanıcının buraya bir yapılandırma dosyası bırakarak çalışmanızı değiştirebilme riskidir.

[WARNING]: Ansible is being run in a world writable directory (/tmp/infra), ignoring it as an ansible.cfg source. For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir

Bu durumda roles_path ve inventory ayarlarınız sessizce devre dışı kalır ve rol arama işlemi, rollerle hiçbir ilgisi olmayan bir nedenden dolayı başarısız olur. ansible --version komutu, yüklenen config file dosyasını yazdırır; ansible-config dump --only-changed ise yerleşik varsayılanlardan farklı olan tüm ayarları listeler. Bir çalışma, yapılandırmanız yokmuş gibi davranıyorsa her ikisini de kontrol edin.

Rolleri paylaşma: requirements.yml ve sabitlenmiş sürüm

Başkasının yazdığı bir rol kopyalanmaz, kurulur. Bunu bir kez tanımlayın:

# requirements.yml
---
roles:
  - name: postgres
    src: https://github.com/example/ansible-role-postgres
    scm: git
    version: v1.4.0
ansible-galaxy install -r requirements.yml -p galaxy_roles

Her zaman version ayarını yapın. Bu ayar olmadan, komutu çalıştırdığınız gün varsayılan dalda ne varsa onu alırsınız; bu da geçen ay çalışan bir dağıtımın, kendi deponuzda hiçbir değişiklik yapmasanız bile bozulmasına neden olur. roles_path değerini indirme dizinine yönlendirin ve bu dizini git dışında tutun:

# ansible.cfg
[defaults]
inventory = inventory.ini
roles_path = ./galaxy_roles

Playbook'un yanındaki roles/ dizininde bulunan roller yine de bulunur, çünkü bu yol roles_path dizinine ek olarak her zaman aranır. Böylece kendi rolleriniz commit edilip gözden geçirilebilir durumda kalırken, üçüncü taraf roller yeniden üretilebilir ve bir etikete sabitlenmiş indirmeler olarak yönetilir.

Rollerin çözüm olmaktan çıktığı noktalar

Bir rol, tek bir Ansible çalışması içindeki yeniden kullanılabilirlik birimidir. Sağlayıcınız üzerinde sunucu veya DNS kaydı oluşturmaz; bunu yapmaya çalışmak, playbook'ların kimsenin bakımını yapmak istemediği bir yapıya dönüşmesine neden olur. Başlamadan önce Ansible ve Terraform arasındaki iş bölümü konusunu okumak faydalıdır. Bir rol, envanter tasarımının yerini de tutmaz: birkaç makineyi geçtikten sonra, sunucuları nasıl gruplandırdığınız ve onlara nasıl eriştiğiniz, görevlerin nasıl dosyalandığından daha önemli hale gelir.

Bu common rolünün kurduğu sıkılaştırma (hardening) işlemleri de kendi içinde özel kararlar gerektirir. Yukarıdaki ek yapılandırma yalnızca iki direktif ayarlar; bu nedenle, sahip olduğunuz her ana makine için role nelerin dahil edilmesi gerektiğine karar vermeden önce hangi SSH ayarlarının değiştirilmeye değer olduğu ve Ubuntu'nun güvenlik güncellemelerini nasıl otomatik uygulayacağı konularını inceleyin.

FAQ

Bir Ansible playbook'unu ne zaman role haline getirmeliyim?

Aynı görev bloğunun ikinci bir play içinde veya ikinci bir host grubuna karşı çalıştırılması gerektiğinde. Görevleri playbook'lar arasında kopyalamak bir uyarı işaretidir; çünkü o andan itibaren her düzeltmenin iki kez uygulanması gerekir ve bir gün mutlaka sadece birine uygulanacaktır. Yaklaşık 100 satırın altında olan ve sadece tek bir grubu hedefleyen bir playbook, role yapısından bir kazanç sağlamaz; aksine fazladan dizinler okunabilirliği zorlaştırır.

Role'ler, aynı play içindeki görevlerden önce mi çalışır?

Evet. Ansible önce pre_tasks, ardından roles: altında listelenen her şeyi, sonra tasks: ve en son post_tasks: kısmını çalıştırır; bu anahtarların dosyanızda hangi sırada göründüğünü dikkate almaz. tasks: kısmını roles: üzerinde yazmak, o görevlerin önce çalışmasını sağlamaz. Bir işlemin role'den önce gerçekleşmesi gerekiyorsa, bunu pre_tasks: içine yerleştirin.

Neden group_vars değerim role içindeki değeri geçersiz kılmıyor?

Değişkenin defaults/main.yml yerine role'ün vars/main.yml dizininde tanımlanıp tanımlanmadığını kontrol edin. vars/, Ansible'ın öncelik sıralamasında group_vars ve host_vars üzerinde yer alır, bu nedenle envanter dosyası bunu geçersiz kılamaz. Değişkeni, öncelik sıralamasının en alt kısımlarında yer alan ve çağrıyı yapanın değiştirebilmesi gereken her şey için doğru yer olan defaults/main.yml içine taşıyın. Sorunun bir yazım hatası değil de öncelik sıralaması olduğunu doğrulamak için, diğer tüm kaynaklardan daha üstün olan -e name=value ile bir kez çalıştırın.

Ansible neden role'ün bulunamadığını söylüyor?

Arama işlemi playbook dosyasının yanında başlar, bu nedenle site.yml ve roles/ aynı dizinde bulunmalıdır. Hata mesajı, The role 'common' was not found in: /home/deploy/lonely/roles ile başlayarak denediği yolları yazdırır. Playbook'u bir üst dizinden çalıştırmak sorun yaratmaz, çünkü arama işlemi shell'inizin çalışma dizinini değil, playbook'un yolunu takip eder. Eğer ansible.cfg içindeki roles_path dosyasına bağımlıysanız, bu dosyanın ansible --version ile yüklendiğini doğrulayın; çünkü herkesin yazabileceği (world writable) bir çalışma dizini, Ansible'ın bu dosyayı görmezden gelmesine neden olur.

Bir role oluşturmak için ansible-galaxy init kullanmam gerekir mi?

Hayır. Bir role sadece beklenen isimlere sahip dizinlerden ibarettir; dolayısıyla mkdir -p roles/common/tasks ve bir tasks/main.yml zaten çalışan bir role'dür. ansible-galaxy init --init-path roles common, yazım yükünü azaltır ve meta/main.yml ile bir README taslağı dahil olmak üzere tam bir iskelet sunar. Boş bıraktığınız dizinleri silin; çünkü boş bir vars/main.yml, role içindeki hangi dosyaların gerçekten bir işlev gördüğünü gizler.

#ansible#roles#playbook#structure#automation