ยกเลิกรหัสสไตล์
เฮ้! ชื่อของฉันคือ
คู่มือนี้นำเสนอวิธีการจัดระเบียบตัวแปรในการปรับใช้ คู่มือนี้ออกแบบมาสำหรับผู้ที่ใช้บทบาทใน playbooks และอ่านอยู่แล้ว
- เมื่อพบตัวแปรในรหัสแล้วจะไม่สามารถเข้าใจได้ทันทีว่ามีหน้าที่รับผิดชอบอะไร
- มีหลายบทบาทและตัวแปรจำเป็นต้องเชื่อมโยงกับค่าเดียว แต่ไม่ได้ผล
- มีปัญหาในการอธิบายให้ผู้อื่นทราบว่าตรรกะของตัวแปรใน playbooks ทำงานอย่างไร
เราพบปัญหาเหล่านี้ในโครงการในบริษัทของเรา ซึ่งเป็นผลมาจากกฎสำหรับการจัดรูปแบบตัวแปรใน playbooks ของเรา ซึ่งแก้ปัญหาเหล่านี้ได้ในระดับหนึ่ง
ตัวแปรในบทบาท
บทบาทเป็นวัตถุระบบการปรับใช้ที่แยกต่างหาก เช่นเดียวกับอ็อบเจกต์อื่นๆ ของระบบ มันต้องมีอินเตอร์เฟสสำหรับการโต้ตอบกับส่วนที่เหลือของระบบ ตัวแปรบทบาทเป็นอินเทอร์เฟซดังกล่าว
ยกตัวอย่างเช่นบทบาท api
ซึ่งติดตั้งแอปพลิเคชัน Java บนเซิร์ฟเวอร์ มันมีตัวแปรอะไรบ้าง?
ตัวแปรบทบาทแบ่งตามประเภทได้ 2 ประเภทคือ
1. Свойства
a) независимые от среды
б) зависимые от среды
2. Связи
a) слушатели
б) запросы внутри системы
в) запросы в среду
คุณสมบัติตัวแปร เป็นตัวแปรที่กำหนดพฤติกรรมของบทบาท
ตัวแปรแบบสอบถาม เป็นตัวแปรที่มีค่าใช้เพื่อกำหนดทรัพยากรภายนอกบทบาท
ผู้ฟังตัวแปร เป็นตัวแปรที่มีค่าใช้เพื่อสร้างตัวแปรคิวรี
ในทางกลับกัน 1a, 2a, 2b เป็นตัวแปรที่ไม่ขึ้นอยู่กับสภาพแวดล้อม (iron, ทรัพยากรภายนอก ฯลฯ) และสามารถเติมด้วยค่าเริ่มต้นในบทบาทเริ่มต้น อย่างไรก็ตาม ตัวแปรเช่น 1.b และ 2.c ไม่สามารถเติมค่าอื่นนอกเหนือจาก 'example' ได้ เนื่องจากตัวแปรเหล่านี้จะเปลี่ยนจาก stand เป็น stand ขึ้นอยู่กับสภาพแวดล้อม
สไตล์รหัส
- ชื่อของตัวแปรต้องขึ้นต้นด้วยชื่อบทบาท สิ่งนี้จะทำให้ง่ายต่อการเข้าใจในอนาคตว่าตัวแปรมาจากบทบาทใดและมีหน้าที่รับผิดชอบอะไร
- เมื่อใช้ตัวแปรในบทบาท คุณต้องแน่ใจว่าได้ปฏิบัติตามหลักการห่อหุ้มและใช้ตัวแปรที่กำหนดไว้ในบทบาทเองหรือในบทบาทที่ขึ้นอยู่กับตัวแปรปัจจุบัน
-
หลีกเลี่ยงการใช้พจนานุกรมสำหรับตัวแปร Ansible ไม่อนุญาตให้คุณแทนที่ค่าแต่ละค่าในพจนานุกรมได้อย่างสะดวก
ตัวอย่างของตัวแปรที่ไม่ดี:
myrole_user: login: admin password: admin
ที่นี่ การเข้าสู่ระบบคือตัวแปรมัธยฐาน และรหัสผ่านคือตัวแปรตาม แต่
เนื่องจากรวมกันเป็นพจนานุกรม คุณจะต้องระบุให้ครบถ้วน
เสมอ. ซึ่งไม่สะดวกมาก วิธีนี้ดีกว่า:myrole_user_login: admin myrole_user_password: admin
ตัวแปรใน playbooks การปรับใช้
เมื่อรวบรวม playbook การปรับใช้งาน (ต่อไปนี้จะเรียกว่า playbook) เราปฏิบัติตามกฎว่าควรวางไว้ในที่เก็บแยกต่างหาก เช่นเดียวกับบทบาท: แต่ละคนอยู่ในที่เก็บ git ของตัวเอง สิ่งนี้ช่วยให้คุณตระหนักว่าบทบาทและ playbook เป็นวัตถุอิสระที่แตกต่างกันของระบบการปรับใช้ และการเปลี่ยนแปลงในวัตถุหนึ่งไม่ควรส่งผลกระทบต่อการทำงานของอีกวัตถุหนึ่ง สิ่งนี้ทำได้โดยการเปลี่ยนค่าเริ่มต้นของตัวแปร
เมื่อรวบรวม playbook เพื่อสรุป คุณสามารถแทนที่ค่าเริ่มต้นของตัวแปรบทบาทในสองตำแหน่ง: ในตัวแปร playbook และในตัวแปรสินค้าคงคลัง
mydeploy # Каталог деплоя
├── deploy.yml # Плейбук деплоя
├── group_vars # Каталог переменных плейбука
│ ├── all.yml # Файл для переменных связи всей системы
│ └── myapi.yml # Файл переменных свойств группы myapi
└── inventories #
└── prod # Каталог окружения prod
├── prod.ini # Инвентори файл
└── group_vars # Каталог для переменных инвентори
└── myapi #
├── vars.yml # Средозависимые переменные группы myapi
└── vault.yml # Секреты (всегда средозависимы) *
ข้อแตกต่างคือตัวแปร playbook จะใช้เสมอเมื่อเรียก playbooks ซึ่งอยู่ในระดับเดียวกันกับมัน ซึ่งหมายความว่าตัวแปรเหล่านี้เหมาะสำหรับการเปลี่ยนค่าเริ่มต้นของตัวแปรที่ไม่ขึ้นอยู่กับสภาพแวดล้อม ในทางกลับกัน ตัวแปรสินค้าคงคลังจะใช้สำหรับสภาพแวดล้อมหนึ่งๆ เท่านั้น ซึ่งเหมาะสำหรับตัวแปรเฉพาะสภาพแวดล้อม
สิ่งสำคัญคือต้องทราบว่าลำดับความสำคัญของตัวแปรจะไม่อนุญาตให้คุณกำหนดตัวแปรใหม่ก่อนในตัวแปร playbook แล้วจึงแยกจากกันในคลังเดียวกัน
ซึ่งหมายความว่าในขั้นตอนนี้คุณต้องตัดสินใจว่าตัวแปรนั้นขึ้นอยู่กับสภาพแวดล้อมหรือไม่ และวางไว้ในตำแหน่งที่ถูกต้อง
ตัวอย่างเช่น ในโครงการหนึ่ง ตัวแปรที่รับผิดชอบในการเปิดใช้งาน SSL นั้นขึ้นอยู่กับสภาพแวดล้อมเป็นเวลานาน เนื่องจากเราไม่สามารถเปิดใช้งาน SSL ได้ด้วยเหตุผลที่อยู่นอกเหนือการควบคุมของเรา ณ จุดใดจุดหนึ่ง หลังจากที่เราแก้ไขปัญหานี้แล้ว มันกลายเป็นสื่ออิสระอิสระและย้ายไปที่ตัวแปร playbook
ตัวแปรคุณสมบัติสำหรับกลุ่ม
มาขยายโมเดลของเราในรูปที่ 1 โดยเพิ่มเซิร์ฟเวอร์ 2 กลุ่มที่มีแอปพลิเคชัน Java ต่างกัน แต่มีการตั้งค่าต่างกัน
ลองจินตนาการว่า playbook จะมีลักษณะอย่างไรในกรณีนี้:
- hosts: myapi
roles:
- api
- hosts: bbauth
roles:
- auth
- hosts: ghauth
roles:
- auth
เรามีสามกลุ่มใน playbook ดังนั้นขอแนะนำให้สร้างไฟล์กลุ่มในตัวแปรคลัง group_vars และตัวแปร playbook พร้อมกัน ไฟล์กลุ่มหนึ่งในกรณีนี้คือคำอธิบายขององค์ประกอบหนึ่งของแอปพลิเคชันของคุณใน playbook เมื่อคุณเปิดไฟล์กลุ่มในตัวแปร playbook คุณจะเห็นความแตกต่างทั้งหมดจากลักษณะการทำงานเริ่มต้นของบทบาทที่กำหนดให้กับกลุ่มในทันที ในตัวแปรสินค้าคงคลัง: ความแตกต่างของพฤติกรรมกลุ่มจากบูธหนึ่งไปยังอีกบูธหนึ่ง
รหัสสไตล์
- พยายามอย่าใช้ตัวแปร host_vars เลย เนื่องจากไม่ได้อธิบายระบบ แต่เป็นเพียงกรณีพิเศษ ซึ่งในระยะยาวจะนำไปสู่คำถาม: "ทำไมโฮสต์นี้จึงแตกต่างจากที่เหลือ" คำตอบคือ หาไม่ง่ายเสมอไป
ลิงค์ตัวแปร
อย่างไรก็ตาม นั่นเป็นเรื่องของตัวแปรคุณสมบัติ แต่ตัวแปรของลิงค์ล่ะ?
ความแตกต่างของพวกเขาคือพวกเขาต้องมีค่าเท่ากันในกลุ่มต่างๆ
ตอนต้นก็มี
hostvars[groups['bbauth'][0]]['auth_bind_port']
แต่ถูกละทิ้งทันที
เพราะมันมีข้อบกพร่อง ประการแรกความใหญ่โต ประการที่สอง การพึ่งพาโฮสต์เฉพาะในกลุ่ม ประการที่สาม จำเป็นต้องรวบรวมข้อเท็จจริงจากโฮสต์ทั้งหมดก่อนที่จะเริ่มการปรับใช้ หากเราไม่ต้องการรับข้อผิดพลาดของตัวแปรที่ไม่ได้กำหนด
ด้วยเหตุนี้จึงตัดสินใจใช้ตัวแปรลิงก์
ลิงค์ตัวแปร เป็นตัวแปรที่เป็นของ playbook และจำเป็นสำหรับการเชื่อมโยงวัตถุของระบบ
ตัวแปรของลิงก์ถูกเติมในตัวแปรระบบทั่วไป group_vars/all/vars
และเกิดขึ้นจากการลบตัวแปร Listener ทั้งหมดออกจากแต่ละกลุ่ม และเพิ่มชื่อของกลุ่มที่เอา Listener ออกไปที่จุดเริ่มต้นของตัวแปร
ดังนั้นจึงมั่นใจได้ถึงความสม่ำเสมอและไม่ตัดกันของชื่อ
มาลองผูกตัวแปรจากตัวอย่างด้านบน:
ลองนึกภาพว่าเรามีตัวแปรที่พึ่งพาซึ่งกันและกัน:
# roles/api/defaults:
# Переменная запроса
api_auth1_address: "http://example.com:80"
api_auth2_address: "http://example2.com:80"
# roles/auth/defaults:
# Переменная слушатель
auth_bind_port: "20000"
ใส่ไว้ในตัวแปรร่วม group_vars/all/vars
ผู้ฟังทั้งหมด และเพิ่มชื่อของกลุ่มเป็นชื่อ:
# group_vars/all/vars
bbauth_auth_bind_port: "20000"
ghauth_auth_bind_port: "30000"
# group_vars/bbauth/vars
auth_bind_port: "{{ bbauth_auth_bind_port }}"
# group_vars/ghauth/vars
auth_bind_port: "{{ ghauth_auth_bind_port }}"
# group_vars/myapi/vars
api_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"
api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"
ตอนนี้โดยการเปลี่ยนค่าของตัวเชื่อมต่อ เราจะแน่ใจว่าคำขอจะไปที่พอร์ตเดียวกัน
รหัสสไตล์
- เนื่องจากบทบาทและกลุ่มเป็นอ็อบเจ็กต์ที่แตกต่างกันในระบบ คุณจึงต้องมีชื่อที่แตกต่างกัน ดังนั้นตัวแปรของลิงก์จะแสดงอย่างถูกต้องว่าพวกเขาอยู่ในกลุ่มของเซิร์ฟเวอร์เฉพาะ ไม่ใช่ของบทบาทในระบบ
ไฟล์สภาพแวดล้อม
บทบาทสามารถใช้ไฟล์ที่แตกต่างกันในแต่ละสภาพแวดล้อม
ใบรับรอง SSL เป็นตัวอย่างของไฟล์ดังกล่าว จัดเก็บเป็นข้อความ
ในตัวแปรไม่สะดวกมาก แต่จะสะดวกที่จะเก็บเส้นทางไว้ภายในตัวแปร
เช่น เราใช้ตัวแปร api_ssl_key_file: "/path/to/file"
.
เนื่องจากเห็นได้ชัดว่าใบรับรองคีย์จะเปลี่ยนจากสภาพแวดล้อมหนึ่งไปยังอีกสภาพแวดล้อมหนึ่ง นี่เป็นตัวแปรที่ขึ้นกับสภาพแวดล้อม ซึ่งหมายความว่าควรอยู่ในไฟล์
group_vars/myapi/vars
สินค้าคงคลังของตัวแปรและมีค่า 'ตัวอย่าง'
วิธีที่สะดวกที่สุดในกรณีนี้คือการวางไฟล์คีย์ในที่เก็บ playbook ตามเส้นทาง
files/prod/certs/myapi.key
แล้วค่าของตัวแปรจะเป็น:
api_ssl_key_file: "prod/certs/myapi.key"
. ความสะดวกสบายอยู่ที่ข้อเท็จจริงที่ว่าผู้ที่รับผิดชอบในการปรับใช้ระบบบนแท่นวางเฉพาะยังมีพื้นที่เฉพาะของตนเองในที่เก็บข้อมูลเพื่อจัดเก็บไฟล์ ในขณะเดียวกัน ก็ยังคงสามารถระบุเส้นทางที่แน่นอนไปยังใบรับรองบนเซิร์ฟเวอร์ได้ ในกรณีที่ใบรับรองนั้นมาจากระบบอื่น
ขาตั้งหลายตัวในสภาพแวดล้อมเดียว
บ่อยครั้งที่มีความจำเป็นต้องปรับใช้แท่นวางที่เกือบจะเหมือนกันหลายแท่นในสภาพแวดล้อมเดียวกันโดยให้มีความแตกต่างน้อยที่สุด ในกรณีนี้ เราแบ่งตัวแปรที่ขึ้นอยู่กับสภาพแวดล้อมออกเป็นตัวแปรที่ไม่เปลี่ยนแปลงภายในสภาพแวดล้อมนี้และตัวแปรที่เปลี่ยนแปลง และเรานำส่วนหลังไปไว้ในไฟล์สินค้าคงคลังโดยตรง หลังจากการจัดการนี้ จะเป็นไปได้ที่จะสร้างสินค้าคงคลังอื่นโดยตรงในไดเร็กทอรีสภาพแวดล้อม
มันจะใช้สินค้าคงคลัง group_vars ซ้ำและยังสามารถกำหนดตัวแปรบางตัวใหม่ได้โดยตรงสำหรับตัวมันเอง
โครงสร้างไดเร็กทอรีขั้นสุดท้ายสำหรับโปรเจ็กต์การปรับใช้:
mydeploy # Каталог деплоя
├── deploy.yml # Плейбук деплоя
├── files # Каталог для файлов деплоя
│ ├── prod # Католог для средозависимых файлов стенда prod
│ │ └── certs #
│ │ └── myapi.key #
│ └── test1 # Каталог для средозависимых файлов стенда test1
├── group_vars # Каталог переменных плейбука
│ ├── all.yml # Файл для переменных связи всей системы
│ ├── myapi.yml # Файл переменных свойств группы myapi
│ ├── bbauth.yml #
│ └── ghauth.yml #
└── inventories #
├── prod # Каталог окружения prod
│ ├── group_vars # Каталог для переменных инвентори
│ │ ├── myapi #
│ │ │ ├── vars.yml # Средозависимые переменные группы myapi
│ │ │ └── vault.yml # Секреты (всегда средозависимы)
│ │ ├── bbauth #
│ │ │ ├── vars.yml #
│ │ │ └── vault.yml #
│ │ └── ghauth #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ └── prod.ini # Инвентори стенда prod
└── test # Каталог окружения test
├── group_vars #
│ ├── myapi #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ ├── bbauth #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ └── ghauth #
│ ├── vars.yml #
│ └── vault.yml #
├── test1.ini # Инвентори стенда test1 в среде test
└── test2.ini # Инвентори стенда test2 в среде test
สรุป
หลังจากจัดระเบียบตัวแปรตามบทความ: แต่ละไฟล์ที่มีตัวแปรมีหน้าที่รับผิดชอบเฉพาะงาน และเนื่องจากไฟล์มีงานบางอย่าง จึงเป็นไปได้ที่จะกำหนดผู้รับผิดชอบสำหรับความถูกต้องของแต่ละไฟล์ ตัวอย่างเช่น ผู้พัฒนาการปรับใช้ระบบจะเป็นผู้รับผิดชอบในการกรอกตัวแปร playbook ที่ถูกต้อง ในขณะที่ผู้ดูแลระบบซึ่งมีจุดยืนอธิบายไว้ในคลัง มีหน้าที่รับผิดชอบโดยตรงในการกรอกตัวแปรในคลัง
บทบาทกลายเป็นหน่วยการพัฒนาในตัวเองที่มีอินเทอร์เฟซของตนเอง ทำให้ผู้พัฒนาบทบาทสามารถพัฒนาคุณลักษณะต่างๆ แทนที่จะปรับแต่งบทบาทให้เหมาะกับระบบ ปัญหานี้เป็นจริงโดยเฉพาะอย่างยิ่งสำหรับบทบาททั่วไปสำหรับทุกระบบในแคมเปญ
ผู้ดูแลระบบไม่จำเป็นต้องเข้าใจรหัสการปรับใช้อีกต่อไป สิ่งที่จำเป็นสำหรับการปรับใช้ที่ประสบความสำเร็จคือการกรอกไฟล์ของตัวแปรสภาพแวดล้อม
วรรณกรรม
ผู้เขียน
Kalyuzhny เดนิส อเล็กซานโดรวิช
ที่มา: will.com