Posting ini mencakup modul loop yang mungkin berikut: with_items, with_nested, with_subelements, with_dict.
Semua ini dengan * sudah tidak digunakan lagi dan direkomendasikan untuk menggunakan loop.
Salah satu peran saya di Chromatic adalah sebagai anggota tim DevOps. Antara lain, ini termasuk bekerja dengan server kami dan server klien kami. Ini, pada gilirannya, berarti saya menghabiskan banyak waktu bekerja dengan Ansible , alat populer untuk menyediakan, mengonfigurasi, dan menerapkan server dan aplikasi.
Sederhananya, mesin yang menjalankan Ansible menjalankan perintah di komputer lain melalui SSH. Perintah ini ditetapkan secara deklaratif (opsional) menggunakan bagian kecil YAML yang disebut tugas. TASKS ini memanggil modul Ansible yang berspesialisasi dalam menjalankan opsi pada komponen tertentu seperti file, database, dll.
Misalnya, tugas berikut menggunakan modul File ( dokumentasi , kode ) untuk membuat direktori tertentu jika belum ada, dan mengubah atributnya jika belum disetel dengan benar:
- file:
path: /home/jenkins/.ssh
state: directory
owner: jenkins
group: jenkins
mode: 700
Beberapa tugas yang terkait dengan satu tugas dikelompokkan menjadi beberapa peran, dan beberapa peran dapat dikelompokkan ke dalam buku pedoman. Anda kemudian dapat menggunakan pedoman tersebut untuk melakukan langkah-langkah konfigurasi yang persis sama pada sejumlah server pada waktu yang sama.
Apakah Ansible declarative?
TASKS Ansible , , TASKS. , , , . , Ansible Copy, . Ansible , :
- name: Copy SSH config file into Aliceβs .ssh directory.
copy:
src: files/config
dest: /home/alice/.ssh/config
owner: alice
group: alice
mode: 0600
, , bash, scp, chown chmod. Ansible , .
, , β , , .
, Ansible, β TASKS . , Ansible , , β PHP, .
, Ansible. Loops , Β«loops _ + lookup(), Β». (Lookups) β Ansible, Β« Ansible Β», Loops Ansible Github, .
Ansible Β« Β», , . Ansible, , , .
Ansible
TASKS, , , , , ( : , , , , !)
:
, :
alice,bob,caroldan.
, :
.ssh/loops.
, . , alice :
/home/alice/
βββ .ssh/
βββ bob/
βββ carol/
βββ dan/
βββ loops/
1. WITH_ITEMS
Ansible , chuck , :
- name: Remove user βChuckβ from the system.
user:
name: chuck
state: absent
remove: yes
β , Chuck Craig β with_items. with_items ( ), ( ):
- name: Remove users βChuckβ and βCraigβ from the system.
user:
name: "{{ item }}"
state: absent
remove: yes
with_items:
- chuck
- craig
, with_items , alice bob:
users_with_items:
- name: "alice"
personal_directories:
- "bob"
- "carol"
- "dan"
- name: "bob"
personal_directories:
- "alice"
- "carol"
- "dan"
TASKS
- name: "Loop 1: create users using 'with_items'."
user:
name: "{{ item.name }}"
with_items: "{{ users_with_items }}"
Ansible User users_with_items. , , , , personal_directories ( , personal_directories β ).
Ansible ( Ansible ): TASKS , . , , personal_directories TASKS (. . User, File).
with_items , PHP:
<?php
foreach ($users_with_items as $user) {
// Do something with $user...
}
, , :
β’ item.name .
β’ with_items, .
, Ansible item, item.property.
/home/
βββ alice/
βββ bob/
2: , WITH_NESTED
: 2 , 1. chown failed: failed to look up user
, users_with_items 1, , common_directories, , . , ( PHP), -, :
<?php
foreach ($users_with_items as $user) {
foreach ($common_directories as $directory) {
// Create $directory for $user...
}
}
Ansible with_nested. with_nested , :
users_with_items:
- name: "alice"
personal_directories:
- "bob"
- "carol"
- "dan"
- name: "bob"
personal_directories:
- "alice"
- "carol"
- "dan"
common_directories:
- ".ssh"
- "loops
TASKS
# Note that this does not set correct permissions on /home/{{ item.x.name }}/.ssh!
- name: "Loop 2: create common users' directories using 'with_nested'."
file:
dest: "/home/{{ item.0.name }}/{{ item.1 }}"
owner: "{{ item.0.name }}"
group: "{{ item.0.name }}"
state: directory
with_nested:
- "{{ users_with_items }}"
- "{{ common_directories }}"
, with_nested , item.0 ( users_with_items) item.1 ( common_directories) . , , /home/alice/.ssh .
/home/
βββ alice/
β βββ .ssh/
β βββ loops/
βββ bob/
βββ .ssh/
βββ loops/
3: , WITH_SUBELEMENTS
: 3 , 1. chown failed: failed to look up user
with_subelements , users_with_items 1. PHP :
<?php
foreach ($users_with_items as $user) {
foreach ($user['personal_directories'] as $directory) {
// Create $directory for $user...
}
}
, $users_with_items $user['personal_directories'] .
users_with_items:
- name: "alice"
personal_directories:
- "bob"
- "carol"
- "dan"
- name: "bob"
personal_directories:
- "alice"
- "carol"
- "dan"
TASKS
- name: "Loop 3: create personal users' directories using 'with_subelements'."
file:
dest: "/home/{{ item.0.name }}/{{ item.1 }}"
owner: "{{ item.0.name }}"
group: "{{ item.0.name }}"
state: directory
with_subelements:
- "{{ users_with_items }}"
- personal_directories
with_subelements , with_nested, , , β personal_directories. 2, ( ) /home/alice/bob.
/home/
βββ alice/
β βββ .ssh/
β βββ bob/
β βββ carol/
β βββ dan/
β βββ loops/
βββ bob/
βββ .ssh/
βββ alice/
βββ carol/
βββ dan/
βββ loops/
4: WITH_DICT
3 , alice bob, , , carol dan. users_with_dict Ansible with_dict.
, (dict dictionary β Python ); with_dict , . , Ansible, PHP :
<?php
foreach ($users_with_dict as $user => $properties) {
// Create a user named $user...
}
users_with_dict:
carol:
common_directories: "{{ common_directories }}"
dan:
common_directories: "{{ common_directories }}"
TASKS
- name: "Loop 4: create users using 'with_dict'."
user:
name: "{{ item.key }}"
with_dict: "{{ users_with_dict }}"
with_dict . , , , dict with_dict (, , with_dict ).
/home/
βββ alice/
β βββ .ssh/
β βββ bob/
β βββ carol/
β βββ dan/
β βββ loops/
βββ bob/
β βββ .ssh/
β βββ alice/
β βββ carol/
β βββ dan/
β βββ loops/
βββ carol/
βββ dan/
5: ,
users_with_dict, Ansible, -. alice, bob, carol dan, with_nested /home/. , , , TASKS:
- Ansible
- Ansible
- Jinja2 ()
- Jinja2 ()
common_directories:
- ".ssh"
- "loops"
TASKS
- name: "Get list of extant users."
shell: "find * -type d -prune | sort"
args:
chdir: "/home"
register: "home_directories"
changed_when: false
- name: "Loop 5: create personal user directories if they don't exist."
file:
dest: "/home/{{ item.0 }}/{{ item.1 }}"
owner: "{{ item.0 }}"
group: "{{ item.0 }}"
state: directory
with_nested:
- "{{ home_directories.stdout_lines }}"
- "{{ home_directories.stdout_lines | union(common_directories) }}"
when: "'{{ item.0 }}' != '{{ item.1 }}'"
TASKS: shell find , file .
/home find \ -type d -prune | sort ( shell) , /home, , , .
home_directories register: "home_directories" . , , :
"stdout_lines": [
"alice",
"bob",
"carol",
"dan",
],
( ) with_nested , :
-
with_nested:
- "{{ home_directories.stdout_lines | union(common_directories) }}"
,
whenTASKS:
when: "'{{ item.0 }}' != '{{ item.1 }}'"
. with_nested Jinja2 TASKS ( home_directories.stdout_lines). Jinja:
- (
home_directories.stdout_lines) - (
|) - , (
union (common_directories))
, home_directories.stdout_lines common_directories :
item:
- .ssh
- alice
- bob
- carol
- dan
- loops
, with_nested home_directories.stdout_lines ( with_nested) , .
, β , , , ! (, /home/alice/alice, /home/bob/bob . .) Ansible β when β :
when: "'{{ item.0 }}' != '{{ item.1 }}'"
, home_directories.stdout_lines home_directories.stdout_lines ( Ansible Loops, Β«β¦ when with_items ( ), when Β»). PHP , , :
<?php
$users = ['alice', 'bob', 'carol', 'dan'];
$common_directories = ['.ssh', 'loops'];
$directories = $user + $common_directories;
foreach ($users as $user) {
foreach ($directories as $directory) {
if ($directory != $user) {
// Create the directoryβ¦
}
}
}
, , .
/home/
βββ alice/
β βββ .ssh/
β βββ bob/
β βββ carol/
β βββ dan/
β βββ loops/
βββ bob/
β βββ .ssh/
β βββ alice/
β βββ carol/
β βββ dan/
β βββ loops/
βββ carol/
β βββ .ssh/
β βββ alice/
β βββ bob/
β βββ dan/
β βββ loops/
βββ dan/
βββ .ssh/
βββ alice/
βββ bob/
βββ carol/
βββ loops/
Ansible . ( Ansible), , (with_nested? with_subitems?) .
, , TASKS, ( , array_filter, array_reduce, array_map , ). , , β β .
Semoga posting ini akan membantu Anda menyingkirkan kesulitan awal saya. Untuk tujuan ini, saya membuat mesin virtual Vagrant (Vagrant secara native mendukung menggunakan Ansible untuk penyediaan) dan buku pedoman Ansible yang saya gunakan untuk membuat dan menguji contoh-contoh ini). Cukup ikuti petunjuk di README untuk menjalankan contoh dari posting ini atau coba sendiri. Jika Anda memiliki pertanyaan atau komentar, silakan tweet di @chromaticHQ!