27 β Infrastructure as Code: Ansible va Terraform¶
β¬ οΈ Oldingi: 26 β Logging, alerting, backup va ishonchlilik Β· π README Β· Keyingi: 28 β Yakuniy kapston: to'liq DevOps platforma β‘οΈ
Bu bobda: 04-bobda serverni QO'LDA β
apt install,ufw, foydalanuvchi yaratish, Docker o'rnatish β sozlagandik. Bu yondashuvning eng katta og'rig'ini hal qilamiz: qo'lda sozlangan server takrorlanmaydi, hujjatlanmaydi va xatoga moyil ("snowflake server" β qaytarib bo'lmaydigan, noyob server). Yechim β Infrastructure as Code (IaC): infratuzilmani kod sifatida yozish (versiyalanadi, ko'rib chiqiladi, takrorlanadi). IaC tamoyillarini ko'ramiz: deklarativ vs imperativ, idempotentlik (bir necha marta ishlatsa ham bir xil natija) va immutable infrastructure. Ikki asosiy vositani o'rganamiz: Ansible β mavjud serverni sozlash uchun (configuration management, agentsiz, SSH orqali,inventory+playbook+ansible.builtin.*modullar, idempotent), va Terraform β cloud resurslarini yaratish uchun (provisioning, HCL til,provider/resource/variable/output,init/plan/apply, state fayl). Misol sifatida 04/06-boblarning qo'lda ishini Ansible playbook'ga, cloud VPS yaratishni Terraform'ga ko'chiramiz, va nihoyat Ansible vs Terraform farqini (sozlash vs yaratish β ko'pincha birga ishlatiladi) aniqlaymiz.
Muammo: "snowflake server" β qaytarib bo'lmaydigan server¶
04-bobda VPS serverni qo'lda sozlagandik. Esda tutsangiz, qadamlar shunaqa edi:
sudo apt update && sudo apt upgrade -y
sudo adduser deploy
sudo ufw allow OpenSSH && sudo ufw allow 80 && sudo ufw allow 443 && sudo ufw enable
sudo apt install -y fail2ban
# ... Docker o'rnatish, SSH kalit, va hokazo
Ishladi. Lekin oradan olti oy o'tdi va endi sizga ikkinchi server kerak bo'ldi (trafik o'sdi, yoki staging muhit qurmoqchisiz). Savol: o'sha birinchi serverni aniq qanday sozlagan edingiz?
ufwda qaysi portlarni ochdingiz?fail2banning qaysi sozlamasini o'zgartirdingiz?deployfoydalanuvchiga qaysi guruhlarni qo'shdingiz? Docker'ning aynan qaysi versiyasini o'rnatdingiz?- Kechasi soat ikkida bir komandani "tezda" terib qo'ygandingiz β u qayerda hujjatlangan? Hech qayerda.
Bu β snowflake server muammosi: har bir qor parchasi noyob bo'lgani kabi, qo'lda sozlangan server ham noyob β uni aynan takrorlab bo'lmaydi. Uchta jiddiy oqibati bor:
- Takrorlanmaydi. Ikkinchi bir xil serverni yaratish β yana bir necha soatlik qo'l mehnati, va natija hech qachon aynan bir xil chiqmaydi.
- Hujjatlanmaydi. "Bu serverda nima sozlangan?" degan savolga javob β faqat sizning xotirangizda (yoki uni boshqargan odam ishdan ketgan).
- Xatoga moyil. Qo'lda terilgan har bir buyruq β xato qilish imkoni. Bir serverda
--no-install-recommendsqo'ydingiz, ikkinchisida unutdingiz β endi ular bir-biridan farq qiladi ("configuration drift", sozlama siljishi).
β οΈ Snowflake serverning eng yomon ko'rinishi: server qulab tushdi (disk yondi, provayder o'chirdi) va sizda uni aynan qayta tiklash uchun hech narsa yo'q. Bu β 05-bobda sanagan oltinchi og'riq: "qayta tiklash butunlay qo'lda".
Yechim β infratuzilmani xotirangizda yoki qo'lingizda emas, kodda saqlash.
Infrastructure as Code nima¶
Infrastructure as Code (IaC) β infratuzilmani (serverlar, tarmoq, sozlamalar) deklarativ matn fayllar orqali, xuddi dastur kodi kabi tasvirlash va boshqarish amaliyoti. Bu fayllar oddiy ilova kodi bilan bir qatorda Git'da yashaydi.
Oddiy o'xshatish: qo'lda sozlash β bu oshpaz taom pishirib, retseptni hech qayerga yozmasligi (faqat boshida bor). IaC esa β yozma retsept: kim bo'lsa ham, qaytadan o'sha taomni aynan pishira oladi.
IaC quyidagilarni beradi:
- Versiyalanadi. Sozlama Git'da β kim, qachon, nimani o'zgartirgani
git logda ko'rinadi. Xato bo'lsa βgit revert. - Ko'rib chiqiladi. Infratuzilma o'zgarishi ham Pull Request orqali ko'rib chiqiladi (12-bobdagi CI/CD jarayoni kabi).
- Takrorlanadi. Bitta kod fayli bir, o'n yoki yuz serverni bir xil holatga keltiradi.
- Hujjat o'zining o'zi. Kod β eng aniq hujjat: "bu serverda nima bor?" degan savolga javob faylning o'zida.
Uchta asosiy tamoyil¶
1. Deklarativ vs imperativ. Bu β IaC ni tushunishning kaliti.
- Imperativ ("buyruqli") β qanday qilishni qadam-baqadam aytasiz: "apt update qil, keyin nginx o'rnat, keyin uni yoq". Bash skript β imperativ. Muammo: skriptni ikkinchi marta ishlatsangiz nima bo'ladi? Nginx allaqachon o'rnatilgan bo'lsa-chi?
- Deklarativ ("e'lon qiluvchi") β qanday natija kerakligini aytasiz: "bu serverda nginx o'rnatilgan va ishlab turgan bo'lsin". Vositaning o'zi joriy holatni tekshiradi: agar nginx allaqachon bor bo'lsa β hech narsa qilmaydi; yo'q bo'lsa β o'rnatadi. Ansible va Terraform asosan deklarativ.
2. Idempotentlik. Bu β IaC ning eng muhim xossasi. Idempotent amal β uni bir marta ham, o'n marta ham ishlatsangiz, natija bir xil bo'ladi.
Imperativ (idempotent EMAS): Deklarativ (idempotent):
"foydalanuvchi qo'sh" "bu foydalanuvchi MAVJUD bo'lsin"
1-marta: qo'shildi β
1-marta: yo'q edi -> yaratildi β
2-marta: "allaqachon bor" XATO β 2-marta: bor edi -> o'zgarish yo'q β
Idempotentlik sababli IaC kodini xotirjam qayta-qayta ishlatasiz: faqat kerakli o'zgarishlar qo'llaniladi, qolgani teginilmaydi.
3. Immutable infrastructure (o'zgarmas infratuzilma). An'anaviy yondashuvda serverni joyida o'zgartirasiz (mutable): yangilash kerak bo'lsa, eski serverga kirib yangilaysiz β vaqt o'tib u "snowflake" ga aylanadi. Immutable yondashuvda esa serverni hech qachon o'zgartirmaysiz: yangi versiya kerak bo'lsa, butunlay yangi server yaratasiz va eskisini o'chirasiz. Docker image aynan shu g'oya (06-bob): konteynerni "tahrir qilmaysiz" β yangi image qurib, qaytadan ishga tushirasiz.
π IaC ikki vazifani bajaradi va shunga ko'ra ikki sinf vosita bor. Provisioning β resurslarni yaratish (server, tarmoq, disk cloud'da). Buni Terraform qiladi. Configuration management β mavjud serverni sozlash (paket o'rnatish, foydalanuvchi, fayl). Buni Ansible qiladi. Ko'pincha ular birga ishlatiladi: Terraform serverni yaratadi, Ansible uni sozlaydi.
Ansible: mavjud serverni sozlash¶
Ansible β configuration management vositasi: mavjud serverlarga SSH orqali ulanib, ularni kerakli holatga keltiradi (paket o'rnatadi, fayl ko'chiradi, xizmat yoqadi). 04 va 06-bobdagi qo'l ishini aynan shu avtomatlashtiradi.
Ansible ning ikki katta afzalligi:
- Agentsiz (agentless). Boshqariladigan serverga hech narsa o'rnatmaysiz β Ansible oddiy SSH va Python orqali ishlaydi (server'da Python bo'lsa kifoya, u esa Linux'da deyarli har doim bor). Bu β uni o'rnatish va boshlashni juda osonlashtiradi.
- Deklarativ va idempotent. Siz "qanday natija kerak"ni yozasiz; Ansible joriy holatni tekshirib, faqat kerakli o'zgarishni qo'llaydi.
Ansible uch tushunchadan iborat: siz turgan control node (boshqaruvchi mashina β sizning noutbukingiz yoki CI runner), boshqariladigan inventory (hostlar ro'yxati) va bajariladigan playbook (YAML'da yozilgan ish rejasi).
Inventory: qaysi serverlar¶
Inventory β Ansible boshqaradigan hostlar ro'yxati. Eng sodda ko'rinishi β INI yoki YAML fayl. Hostlarni mantiqiy guruhlarga bo'lasiz:
# inventory.ini
[web]
web1 ansible_host=203.0.113.10
web2 ansible_host=203.0.113.11
[db]
db1 ansible_host=203.0.113.20
[all:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/id_ed25519
Bu yerda web guruhida ikki server, db da bitta. [all:vars] β barcha hostlarga umumiy o'zgaruvchilar: qaysi foydalanuvchi bilan SSH qilish (deploy β 04-bobda yaratganimiz) va qaysi kalit bilan (04-bobdagi SSH kalit). IP'lar bu yerda hujjat uchun ajratilgan namuna diapazondan (203.0.113.x) β siz o'z server IP'laringizni yozasiz.
Ulanishni tekshirish uchun Ansible'ning ping moduli bor (bu ICMP ping emas β SSH + Python ishlashini tekshiradi):
web1 | SUCCESS => {"changed": false, "ping": "pong"}
web2 | SUCCESS => {"changed": false, "ping": "pong"}
db1 | SUCCESS => {"changed": false, "ping": "pong"}
βΉοΈ Bu buyruq haqiqiy serverlarga SSH qiladi, shuning uchun chiqishi illustrativ β o'z serveringizda ishga tushirsangiz shunday natija kutiladi.
changed: falseβ idempotentlikning belgisi: ping hech narsani o'zgartirmaydi.
Playbook: nima qilinadi¶
Playbook β YAML fayl bo'lib, qaysi hostlarda qaysi tasklarni (vazifalarni) bajarishni e'lon qiladi. Har bir task bitta modulni chaqiradi. Modullar ansible.builtin.* nom maydonida (namespace) keladi β masalan ansible.builtin.apt (paket), ansible.builtin.copy (fayl), ansible.builtin.service (xizmat), ansible.builtin.user (foydalanuvchi).
04-bobning server hardening + Docker o'rnatish ishini playbook'ga ko'chiramiz:
# site.yml
- name: Serverni sozlash (hardening + Docker)
hosts: web
become: true
tasks:
- name: Paket ro'yxatini yangilash va tizimni yangilash
ansible.builtin.apt:
update_cache: true
upgrade: dist
- name: Kerakli paketlarni o'rnatish
ansible.builtin.apt:
name:
- ufw
- fail2ban
- ca-certificates
- curl
state: present
- name: deploy foydalanuvchisini yaratish
ansible.builtin.user:
name: deploy
groups: sudo
shell: /bin/bash
state: present
- name: SSH (OpenSSH) portiga ruxsat
community.general.ufw:
rule: allow
name: OpenSSH
- name: HTTP va HTTPS portlariga ruxsat
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
- name: ufw ni yoqish, kiruvchini standart rad etish
community.general.ufw:
state: enabled
policy: deny
- name: Docker GPG kalitini qo'shish uchun katalog
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
- name: Docker apt repozitoriyasidan o'rnatish
ansible.builtin.apt:
name: docker.io
state: present
update_cache: true
- name: Docker xizmatini yoqish va ishga tushirish
ansible.builtin.service:
name: docker
state: started
enabled: true
Diqqat qilinadigan asosiy elementlar:
hosts: webβ bu play qaysi inventory guruhiga tegishli (yuqoridagi[web]).become: trueβ buyruqlarnisudo(root huquqi) bilan bajaradi. 04-bobda har buyruqdasudoyozgandik; bu yerda bir marta e'lon qilamiz.name:β har task'ning inson o'qiy oladigan tavsifi (chiqishda ko'rinadi).state: presentβ deklarativ: "bu paket/foydalanuvchi mavjud bo'lsin".state: startedβ "xizmat ishlab tursin",enabled: trueβ "boot'da yoqilsin" (19-bobdagisystemctl enableekvivalenti).loop:+{{ item }}β bitta task'ni ro'yxat bo'yicha takrorlash (bu yerda 80 va 443 portlari uchun).
π
ansible.builtin.*β Ansible bilan birga keladigan asosiy modullar (apt,copy,template,service,user,file,ping).ufwesacommunity.generalkollektsiyasida β uniansible-galaxy collection install community.generalbilan o'rnatasiz. Modul nomini ixtiro qilmang: shubha bo'lsaansible-doc ansible.builtin.aptyoki rasmiy docs (docs.ansible.com) ni tekshiring.
Playbook'ni ishga tushirish:
PLAY [Serverni sozlash (hardening + Docker)] ***********************
TASK [Kerakli paketlarni o'rnatish] *******************************
changed: [web1]
ok: [web2]
TASK [deploy foydalanuvchisini yaratish] **************************
ok: [web1]
ok: [web2]
PLAY RECAP ********************************************************
web1 : ok=10 changed=3 unreachable=0 failed=0
web2 : ok=10 changed=0 unreachable=0 failed=0
PLAY RECAP β idempotentlikning eng yorqin ko'rinishi. web1 da 3 ta o'zgarish bo'ldi (changed=3); web2 allaqachon to'g'ri sozlangan edi, shuning uchun changed=0 β hech narsa o'zgartirilmadi. Playbook'ni qancha marta ishlatsangiz ham, faqat haqiqatan kerak bo'lgan o'zgarishlar qo'llaniladi.
π‘
ansible-playbook --check site.ymlβ "quruq ishga tushirish" (dry run): hech narsani o'zgartirmasdan, nima o'zgarishini ko'rsatadi. Terraform'ningplaniga o'xshash. Production'ga qo'llashdan oldin doim--checkbilan ko'rib oling.
Template, handler va role (qisqacha)¶
Real playbook'larda yana uch tushuncha tez-tez uchraydi:
ansible.builtin.templateβ Jinja2 shablon faylini o'zgaruvchilar bilan to'ldirib serverga ko'chiradi. Masalan Nginx config (16-bob) yoki systemd unit (19-bob) faylida domen nomini o'zgaruvchidan olib qo'yish. (copyβ faylni o'zgartirmasdan ko'chiradi;templateβ o'zgaruvchilarni qo'yib ko'chiradi.)handlersβ faqat o'zgarish bo'lganda bir marta ishga tushadigan task. Klassik misol: config fayl o'zgardi -> Nginx'ni qayta yukla. Agar config o'zgarmasa, handler ishlamaydi (idempotent).
- name: Nginx config'ini joylash
ansible.builtin.template:
src: app.conf.j2
dest: /etc/nginx/conf.d/app.conf
notify: Restart nginx
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
rolesβ playbook'ni qayta ishlatiladigan bo'laklarga ajratish. Masalanwebserver,database,commonrollari β har biri o'z task, template va o'zgaruvchilariga ega standart papka tuzilishi (roles/webserver/tasks/main.yml). Katta loyihadasite.ymlfaqat rollarni chaqiradi:
π‘ Tayyor rollarni Ansible Galaxy (galaxy.ansible.com) dan olishingiz mumkin β masalan Docker yoki Nginx o'rnatishning sinovdan o'tgan rollari. Lekin o'rganish bosqichida o'z playbook'ingizni yozish β nima bo'layotganini tushunish uchun foydaliroq.
Terraform: cloud resurslarini yaratish¶
Ansible mavjud serverni sozlaydi. Lekin serverning o'zini (cloud'dagi VPS, tarmoq, disk) kim yaratadi? Buni qo'lda β provayder veb-panelidan tugma bosib β qilish ham yana o'sha "snowflake" muammosiga olib keladi. Bu yerda Terraform keladi.
Terraform β provisioning vositasi: cloud resurslarini (server, tarmoq, IP, disk, DNS yozuvi) HCL (HashiCorp Configuration Language) tilida deklarativ yozasiz, va Terraform ularni provayder API'si orqali yaratadi. AWS, Google Cloud, Azure, DigitalOcean, Hetzner β yuzlab provider qo'llab-quvvatlanadi.
Terraform ishlash oqimi to'rt buyruqdan iborat: init (provider'ni yuklash), plan (nima o'zgarishini ko'rsatish), apply (o'zgarishni qo'llash), destroy (hammasini o'chirish).
HCL: resurslarni e'lon qilish¶
HCL β blok asosidagi deklarativ til. Asosiy bloklar: provider (qaysi cloud), resource (yaratilgan narsa), variable (kirish parametrlari), output (chiqish qiymatlari).
Quyida DigitalOcean'da bitta VPS ("droplet") va tarmoq (VPC) yaratish misoli. (Sintaksis va resurs nomlari provayderga bog'liq; bu β illustratsiya uchun tipik tuzilish.)
# providers.tf β qaysi provider va versiyasi
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
provider "digitalocean" {
token = var.do_token
}
# variables.tf β kirish parametrlari
variable "do_token" {
description = "DigitalOcean API tokeni"
type = string
sensitive = true
}
variable "region" {
description = "Resurslar joylashadigan region"
type = string
default = "fra1"
}
# main.tf β yaratiladigan resurslar
resource "digitalocean_vpc" "app_network" {
name = "vazifalar-network"
region = var.region
ip_range = "10.10.10.0/24"
}
resource "digitalocean_droplet" "web" {
name = "vazifalar-web"
image = "ubuntu-24-04-x64"
size = "s-1vcpu-1gb"
region = var.region
vpc_uuid = digitalocean_vpc.app_network.id
ssh_keys = [var.ssh_fingerprint]
}
# outputs.tf β apply tugagach ko'rsatiladigan qiymatlar
output "web_ip" {
description = "Yaratilgan serverning ommaviy IP manzili"
value = digitalocean_droplet.web.ipv4_address
}
Asosiy elementlar:
resource "tur" "nom"β birinchi qator: resurs turi (digitalocean_dropletβ providerga xos), ikkinchisi: sizning ichki nomingiz (webβ kodda murojaat uchun).var.regionβ o'zgaruvchiga murojaat.sensitive = trueβ maxfiy qiymat (token)plan/outputchiqishida yashiriladi.digitalocean_vpc.app_network.idβ bir resursdan boshqasiga murojaat: droplet shu VPC ichida yaratiladi. Terraform bu bog'liqliklarni o'zi aniqlaydi va resurslarni to'g'ri tartibda yaratadi (avval tarmoq, keyin server).outputβapplytugagach kerakli qiymatni ko'rsatadi (masalan, yangi server IP'sini β keyin uni Ansible inventory'ga berasiz).
plan, apply va state fayl¶
Terraform ishlatish ketma-ketligi:
terraform init # provider'larni yuklaydi (.terraform/ papkasi)
terraform plan # nima yaratilishi/o'zgarishini ko'rsatadi (hech narsa qilmaydi)
terraform apply # tasdiqlashdan keyin resurslarni yaratadi
terraform plan chiqishi (illustrativ):
Terraform will perform the following actions:
# digitalocean_droplet.web will be created
+ resource "digitalocean_droplet" "web" {
+ name = "vazifalar-web"
+ image = "ubuntu-24-04-x64"
+ size = "s-1vcpu-1gb"
+ ipv4_address = (known after apply)
}
# digitalocean_vpc.app_network will be created
+ resource "digitalocean_vpc" "app_network" {
+ name = "vazifalar-network"
+ ip_range = "10.10.10.0/24"
}
Plan: 2 to add, 0 to change, 0 to destroy.
+ belgisi β yaratiladigan resurs. Agar mavjud kodni o'zgartirsangiz, plan ~ (o'zgartiriladi) yoki - (o'chiriladi) ko'rsatadi. plan β Terraform'ning eng muhim xavfsizlik mexanizmi: apply dan oldin aniq nima bo'lishini ko'rasiz.
Terraform "joriy holat bilan kerakli holat o'rtasidagi farqni" qanday biladi? State fayl orqali:
terraform.tfstateβ Terraform yaratgan barcha resurslarning joriy holatini saqlaydigan JSON fayl.planpaytida Terraform shu faylni o'qib, real cloud bilan solishtiradi va farqni hisoblaydi.
β οΈ State fayl β Terraform'ning eng nozik joyi. Uni qo'lda tahrir qilmang, va Git'ga qo'shmang β unda maxfiy ma'lumotlar (token, parol) ochiq bo'lishi mumkin. Jamoada ishlasangiz, state'ni remote backend da saqlang (masalan S3, yoki Terraform Cloud) β shunda hamma bir xil state'ni ko'radi va bir vaqtda o'zgartirishdan locking himoya qiladi.
# backend.tf β state'ni remote saqlash (jamoa uchun)
terraform {
backend "s3" {
bucket = "mening-terraform-state"
key = "vazifalar/terraform.tfstate"
region = "eu-central-1"
}
}
Resurslarni o'chirish:
π
terraform plan/apply/destroyhaqiqiy cloud akkauntga (va pulga) ta'sir qiladi β bu buyruqlar va ularning chiqishi shu bobda illustrativ. O'z cloud akkauntingizda (DigitalOcean, AWS bepul daraja, yoki Hetzner) sinab ko'rishingiz mumkin;applyreal server yaratadi va hisobingizdan pul yechiladi. Sinovdan keyinterraform destroybilan o'chirib, behuda to'lovning oldini oling.
Ansible vs Terraform: sozlash vs yaratish¶
Ikkala vosita ham IaC, lekin har xil vazifa uchun. Eng keng tarqalgan chalkashlik β "qaysi birini ishlataman?". Javob: ko'pincha ikkalasini ham, ketma-ket.
| Terraform | Ansible | |
|---|---|---|
| Asosiy vazifa | Provisioning β resurs yaratish | Configuration management β server sozlash |
| Nimani boshqaradi | Cloud resurslari (VPS, tarmoq, disk, DNS) | Mavjud serverning ichki holati (paket, fayl, xizmat) |
| Til | HCL (deklarativ) | YAML playbook (deklarativ) |
| Holatni kuzatish | State fayl (terraform.tfstate) |
Statesiz β har safar serverni tekshiradi |
| Qanday ulanadi | Cloud provider API | SSH (agentsiz) |
| Tipik savol | "Menga 3 ta server va tarmoq kerak" | "Bu serverlarga Docker va Nginx o'rnat" |
Amaldagi tipik oqim:
- Terraform cloud'da serverlar va tarmoqni yaratadi;
outputorqali yangi server IP'larini beradi. - Bu IP'lar Ansible inventory'ga uzatiladi.
- Ansible o'sha serverlarga SSH qilib, ularni sozlaydi (Docker, Nginx, ilova β 04/06/16-boblardagidek).
Terraform apply --> yangi server IP'lari --> Ansible inventory --> ansible-playbook
(YARATADI) (output) (SOZLAYDI)
π‘ Oddiy o'xshatish: Terraform β uy quruvchi (poydevor, devor, tom β bo'sh bino). Ansible β mebelchi va elektrik (jihoz qo'yadi, sim tortadi β yashashga tayyor qiladi). Birinchi bino bo'lishi kerak, keyin uni jihozlash mumkin.
Boshqa IaC vositalari (qisqa)¶
Ansible va Terraform β eng keng tarqalganlari, lekin yagona emas:
- Pulumi β Terraform kabi provisioning, lekin HCL o'rniga oddiy dasturlash tillari (TypeScript, Python, Go) da yoziladi. Agar jamoangiz allaqachon shu tilni bilsa va sikl/funksiya kabi to'liq til imkoniyatlari kerak bo'lsa qulay.
- cloud-init β cloud serverlar birinchi yuklanganda avtomatik bajariladigan boshlang'ich sozlash (foydalanuvchi yaratish, paket o'rnatish, SSH kalit qo'yish). Ko'pincha Terraform bilan birga: Terraform server yaratadi, cloud-init uni darhol minimal sozlaydi, keyin Ansible to'liq sozlaydi. Misol
user_data(YAML):
#cloud-config
users:
- name: deploy
groups: sudo
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... siz@mashina
package_update: true
packages:
- ufw
- fail2ban
- OpenTofu β Terraform'ning ochiq-kodli forki (litsenziya o'zgarishidan keyin chiqdi); HCL va buyruqlari deyarli aynan bir xil.
βΉοΈ Bu vositalarni hozir chuqur o'rganish shart emas. Asosiysi β IaC tamoyilini (deklarativ, idempotent, versiyalangan) tushunish. Tamoyilni bilsangiz, istalgan vositaga o'tish oson.
Yakun¶
05-bobdagi oltinchi va oxirgi og'riqni β "qayta tiklash butunlay qo'lda" β yopdik. Snowflake server muammosini (takrorlanmaydi, hujjatlanmaydi, xatoga moyil) Infrastructure as Code bilan hal qildik: infratuzilmani kod sifatida yozdik β versiyalanadi, ko'rib chiqiladi, takrorlanadi. IaC ning uch tamoyilini ko'rdik: deklarativ vs imperativ, idempotentlik va immutable infrastructure.
Ikki vositani o'rgandik. Ansible β agentsiz, SSH orqali mavjud serverni sozlaydi: inventory (hostlar), playbook (YAML task'lar), ansible.builtin.* modullar (apt, copy, service, user, template), handlers va roles, hammasi idempotent. 04/06-bobning qo'l ishini playbook'ga ko'chirdik. Terraform β HCL'da cloud resurslarini yaratadi: provider/resource/variable/output, init/plan/apply/destroy oqimi, va eng nozigi β state fayl. Nihoyat ikkalasini taqqosladik: Terraform yaratadi, Ansible sozlaydi β odatda birga ishlatiladi.
Endi 01-bobdan boshlangan butun yo'lni bosib o'tdik: Linux, Bash, xavfsizlik, Docker, CI/CD, Nginx, HTTPS, systemd, Kubernetes, monitoring, IaC. Keyingi 28-bobda β yakuniy kapston: o'rgangan hamma narsani bitta to'liq DevOps platformaga birlashtiramiz.
27-bob mashqlari¶
Oson¶
- "Snowflake server" nima va qo'lda sozlangan serverning uchta og'rig'ini sanang.
- Infrastructure as Code (IaC) bergan kamida uchta foydani ayting (versiyalanish, ko'rib chiqilish, ...).
- Deklarativ va imperativ yondashuv farqini bir-ikki jumlada tushuntiring. Bash skript qaysi turga kiradi?
- Idempotentlik nima? Nega u IaC uchun muhim?
- Ansible va Terraform har biri qaysi asosiy vazifani bajaradi (sozlash yoki yaratish)? Bittadan jumla bilan ayting.
- Ansible nima uchun "agentsiz" deyiladi? Boshqariladigan serverga qanday ulanadi?
O'rta¶
- Ansible inventory faylida
[web]guruhiga ikkita server va[all:vars]daansible_user=deployqo'shilgan misol yozing.[all:vars]nima vazifani bajaradi? - Quyidagi Ansible task'da xato bor β toping va to'g'rilang:
name: nginx; apt: nginx(modul to'liq nomi vastateyetishmaydi). To'g'ri task'ni yozing. ansible-playbook --checkvaterraform planqanday umumiy maqsadga xizmat qiladi? Nega ikkalasi ham "qo'llashdan oldin" bosqichi muhim?- Terraform
statefayli nima uchun kerak va nega uni Git'ga qo'shmaslik kerak? "Remote backend" nima muammoni hal qiladi? - Terraform va Ansible'ni birga ishlatish oqimini uch qadamda tasvirlang (qaysi vosita nima qiladi va ular orasida nima uzatiladi).
Qiyin¶
- 04-bobdagi qo'lda hardening ishini Ansible playbook (
hardening.yml) ga ko'chiring:webguruhida,become: truebilan β (a)ufw,fail2banpaketlarini o'rnatish; (b)deployfoydalanuvchisinisudoguruhi bilan yaratish; (c) OpenSSH, 80 va 443 portlariga ruxsat beribufwni yoqish. Idempotentlikni qandaystate:qiymatlari ta'minlaydi β ayting. - DigitalOcean (yoki istalgan provider) uchun Terraform konfiguratsiyasi yozing: bitta
variable "region"(default qiymat bilan), bittadigitalocean_dropletresursi (Ubuntu 24.04, region o'zgaruvchidan), va serverning IP'sini ko'rsatadiganoutput. So'ng to'g'ri buyruqlar ketma-ketligini (init->plan->apply) yozing va negaplanni o'tkazib yubormaslik kerakligini ayting. - Ansible'da config fayl o'zgarganda Nginx'ni qayta yuklaydigan handler yozing (
templatetask +notify+handlers). Nega handler oddiy task'dan ko'ra idempotent β tushuntiring (config o'zgarmasa nima bo'ladi?).
Yechim β 8
To'g'ri task β modulning to'liq nomi (ansible.builtin.apt), name: (task tavsifi) va modul ichida name: (paket) hamda state: kerak:
state: present β "nginx mavjud bo'lsin" (deklarativ, idempotent). Agar uni har doim yangilamoqchi bo'lsangiz state: latest; lekin latest idempotent emas (har ishlatganda yangi versiyani tortishi mumkin), shuning uchun odatda present afzal.
Yechim β 12
hardening.yml:
- name: Server hardening
hosts: web
become: true
tasks:
- name: Xavfsizlik paketlarini o'rnatish
ansible.builtin.apt:
name:
- ufw
- fail2ban
state: present
update_cache: true
- name: deploy foydalanuvchisini yaratish
ansible.builtin.user:
name: deploy
groups: sudo
shell: /bin/bash
state: present
- name: OpenSSH portiga ruxsat
community.general.ufw:
rule: allow
name: OpenSSH
- name: HTTP va HTTPS portlariga ruxsat
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
- name: ufw ni yoqish (kiruvchini standart rad et)
community.general.ufw:
state: enabled
policy: deny
Ishga tushirish: ansible-playbook -i inventory.ini hardening.yml.
Idempotentlikni state: present (paket/foydalanuvchi β "mavjud bo'lsin, bor bo'lsa tegma") va state: enabled (ufw β "yoqilgan bo'lsin") ta'minlaydi. Playbook'ni qayta ishlatsangiz, allaqachon bajarilgan task'lar ok (changed emas) bo'lib o'tadi.
Yechim β 13
# variables.tf
variable "region" {
description = "Resurs joylashadigan region"
type = string
default = "fra1"
}
# main.tf
resource "digitalocean_droplet" "web" {
name = "vazifalar-web"
image = "ubuntu-24-04-x64"
size = "s-1vcpu-1gb"
region = var.region
}
# outputs.tf
output "web_ip" {
description = "Server IP manzili"
value = digitalocean_droplet.web.ipv4_address
}
Buyruqlar:
terraform init # provider'ni yuklaydi
terraform plan # nima yaratilishini ko'rsatadi (hech narsa qilmaydi)
terraform apply # tasdiqdan keyin serverni yaratadi
plan ni o'tkazib yubormaslik kerak, chunki u β apply dan oldin aniq nima o'zgarishini (yaratiladi +, o'zgaradi ~, o'chiriladi -) ko'rsatadigan xavfsizlik bosqichi. Uni ko'rmasdan apply qilsangiz, kutilmagan resursni o'chirib yuborishingiz yoki ortiqcha resurs yaratib pul sarflashingiz mumkin. (provider blokini ham qo'shish kerak β qisqalik uchun bu yerda tushirib qoldirildi.)
Yechim β 14
- name: Nginx config va handler
hosts: web
become: true
tasks:
- name: Nginx config'ini joylash
ansible.builtin.template:
src: app.conf.j2
dest: /etc/nginx/conf.d/app.conf
notify: Restart nginx
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
notify: Restart nginx β template task o'zgarish keltirsa (config fayl haqiqatan o'zgardi, changed), handler chaqiriladi. Handler oddiy task'dan idempotentroq, chunki u faqat o'zgarish bo'lganda ishlaydi: agar config fayl avvalgisi bilan bir xil bo'lsa, template changed=false qaytaradi, handler umuman ishga tushmaydi β Nginx behuda qayta yuklanmaydi. Bir play ichida bir nechta task bir handler'ni notify qilsa ham, handler play oxirida bir marta ishlaydi.
β¬ οΈ Oldingi: 26 β Logging, alerting, backup va ishonchlilik Β· π README Β· Keyingi: 28 β Yakuniy kapston: to'liq DevOps platforma β‘οΈ