วิธีการของระบบกับตัวแปรใน Ansible

ยกเลิกรหัสสไตล์

เฮ้! ชื่อของฉันคือ เดนิส คาลยูซนี่ ฉันทำงานเป็นวิศวกรในแผนกพัฒนากระบวนการอัตโนมัติ ทุกๆ วัน แอปพลิเคชั่นใหม่ๆ จะถูกเผยแพร่ไปยังเซิร์ฟเวอร์แคมเปญนับร้อย และในบทความนี้ ฉันจะแชร์ประสบการณ์การใช้ Ansible เพื่อวัตถุประสงค์เหล่านี้

คู่มือนี้นำเสนอวิธีการจัดระเบียบตัวแปรในการปรับใช้ คู่มือนี้ออกแบบมาสำหรับผู้ที่ใช้บทบาทใน playbooks และอ่านอยู่แล้ว ปฏิบัติที่ดีที่สุดแต่พบปัญหาที่คล้ายกัน:

  • เมื่อพบตัวแปรในรหัสแล้วจะไม่สามารถเข้าใจได้ทันทีว่ามีหน้าที่รับผิดชอบอะไร
  • มีหลายบทบาทและตัวแปรจำเป็นต้องเชื่อมโยงกับค่าเดียว แต่ไม่ได้ผล
  • มีปัญหาในการอธิบายให้ผู้อื่นทราบว่าตรรกะของตัวแปรใน playbooks ทำงานอย่างไร

เราพบปัญหาเหล่านี้ในโครงการในบริษัทของเรา ซึ่งเป็นผลมาจากกฎสำหรับการจัดรูปแบบตัวแปรใน playbooks ของเรา ซึ่งแก้ปัญหาเหล่านี้ได้ในระดับหนึ่ง

วิธีการของระบบกับตัวแปรใน Ansible

ตัวแปรในบทบาท

บทบาทเป็นวัตถุระบบการปรับใช้ที่แยกต่างหาก เช่นเดียวกับอ็อบเจกต์อื่นๆ ของระบบ มันต้องมีอินเตอร์เฟสสำหรับการโต้ตอบกับส่วนที่เหลือของระบบ ตัวแปรบทบาทเป็นอินเทอร์เฟซดังกล่าว

ยกตัวอย่างเช่นบทบาท apiซึ่งติดตั้งแอปพลิเคชัน Java บนเซิร์ฟเวอร์ มันมีตัวแปรอะไรบ้าง?

วิธีการของระบบกับตัวแปรใน Ansible

ตัวแปรบทบาทแบ่งตามประเภทได้ 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 ต่างกัน แต่มีการตั้งค่าต่างกัน

วิธีการของระบบกับตัวแปรใน Ansible

ลองจินตนาการว่า 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 ออกไปที่จุดเริ่มต้นของตัวแปร

ดังนั้นจึงมั่นใจได้ถึงความสม่ำเสมอและไม่ตัดกันของชื่อ

มาลองผูกตัวแปรจากตัวอย่างด้านบน:

วิธีการของระบบกับตัวแปรใน Ansible

ลองนึกภาพว่าเรามีตัวแปรที่พึ่งพาซึ่งกันและกัน:

# 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 ที่ถูกต้อง ในขณะที่ผู้ดูแลระบบซึ่งมีจุดยืนอธิบายไว้ในคลัง มีหน้าที่รับผิดชอบโดยตรงในการกรอกตัวแปรในคลัง

บทบาทกลายเป็นหน่วยการพัฒนาในตัวเองที่มีอินเทอร์เฟซของตนเอง ทำให้ผู้พัฒนาบทบาทสามารถพัฒนาคุณลักษณะต่างๆ แทนที่จะปรับแต่งบทบาทให้เหมาะกับระบบ ปัญหานี้เป็นจริงโดยเฉพาะอย่างยิ่งสำหรับบทบาททั่วไปสำหรับทุกระบบในแคมเปญ

ผู้ดูแลระบบไม่จำเป็นต้องเข้าใจรหัสการปรับใช้อีกต่อไป สิ่งที่จำเป็นสำหรับการปรับใช้ที่ประสบความสำเร็จคือการกรอกไฟล์ของตัวแปรสภาพแวดล้อม

วรรณกรรม

  1. เอกสาร

ผู้เขียน

Kalyuzhny เดนิส อเล็กซานโดรวิช

ที่มา: will.com

เพิ่มความคิดเห็น