WisarWisar
Dasturlash kitobi/10-QISM — DevOps41 daqiqa

10.10-bob: Infrastructure as Code — Terraform asoslari

10-QISM — DevOps va Deploy · 10-mavzu


1. Kirish va motivatsiya

10-QISM'da biz infratuzilmani bosqichma-bosqich qurdik: Linux server va SSH 10.1-bob, Nginx 10.2-bob, Docker (10.3-10.4), CI/CD 10.5-bob, AWS cloud xizmatlari 10.6-bob, deploy strategiyalari 10.7-bob, Kubernetes 10.8-bob va monitoring 10.9-bob. Lekin 10.6 da AWS resurslarini (EC2, S3, RDS, Security Group) qanday yaratdik? Qo'lda — AWS Console'da sichqoncha bilan tugmalarni bosib, maydonlarni to'ldirib. Bu — ClickOps (klik bilan operatsiya) deb ataladi va u jiddiy muammolarga olib keladi: bir oydan keyin "men buni qanday sozlagandim?" deb eslay olmaysiz; ikkinchi serverni xuddi shunday qilib yaratish — yana 30 daqiqa qo'l mehnati va albatta biror joyda xato; "production va staging bir xilmi?" degan savolga ishonch bilan javob bera olmaysiz; xodim ketsa — bilim ham u bilan ketadi.

Yechim — Infrastructure as Code (IaC — infratuzilma kod sifatida): serverni, tarmoqni, ma'lumotlar bazasini qo'lda emas, matnli kod fayllar orqali ta'riflash. Bu kod Git'da versiyalanadi (4-QISM), code review'dan o'tadi 15.2-bob, bir buyruq bilan takrorlanadi va istalgan paytda aynan o'sha holatga qaytariladi. Va IaC'ning de-fakto standarti — Terraform (HashiCorp). Siz HCL tilida "menga t3.micro EC2 + S3 bucket + Security Group kerak" deb yozasiz, terraform apply deb bosasiz — Terraform AWS API orqali hammasini yaratib beradi. O'chirmoqchi bo'lsangiz terraform destroy — hammasi izsiz yo'qoladi. Bu — "men serverni qo'lda sozlayman" deydigan junior bilan, "butun infratuzilmani kodda ta'riflab, bir buyruq bilan ko'tarib-tushiraman" deydigan senior o'rtasidagi farq.

Bu bob: IaC nima (imperative vs declarative, ClickOps muammosi), Terraform nima (multi-cloud, declarative engine), HCL til (block, resource, argument), provider (aws/gcp/azure), resource (yaratiladigan obyekt), declarative model (kerakli holat — Terraform farqni hisoblaydi), state (terraform.tfstate — real holat xaritasi, drift), workflow (init/plan/apply/destroy), variable va output (parametrlash), data source (mavjud resursni o'qish), module (qayta ishlatish), remote state/backend (S3 lock — jamoa), workspace (dev/prod), Terraform'ni boshqa vositalar bilan taqqoslash, hamda ko'p resurs (count/for_each, dynamic, lifecycle), local/depends_on/provisioner/provider alias/import va CI/CD bilan integratsiya. Bu bob 10.6 (AWS) ni avtomatlashtiradi, 10.5 (CI/CD) bilan birlashadi va 10.11 (secrets) ga ko'prik bo'ladi.

O'xshatish: IaC — retsept kitobi va IKEA yig'ish chizmasi. Qo'lda server yaratish — oshpaz oshxonada o'z xotirasidan, "ko'z bilan" osh damlashi: bir marta zo'r chiqadi, lekin ikkinchisi boshqacha, va boshqa odam takrorlay olmaydi (hujjatsiz). IaC esa — aniq yozilgan retsept: har bir masalliq (resource), miqdori (argument), tartibi (dependency) qog'ozda. Istalgan oshpaz (jamoadagi har kim) bir xil natijani qaytaradi. Terraform — IKEA yig'ish ustasi: siz unga chizmani (HCL kod) berasiz, u qutidagi qismlarni (AWS resurslar) to'g'ri tartibda yig'ib beradi. Eng muhimi — chizmada "menga 3 ta javon kerak" deb yozasiz (declarative — kerakli holat), "avval bu vintni bur, keyin u taxtani qo'y" deb emas (imperative — qadamlar). Hozir 2 ta javon bo'lsa — Terraform o'zi farqni ko'rib, faqat 1 tasini qo'shadi. State fayli — yig'ilgan mebel ro'yxati: nima yig'ilgani, qayerda turgani yozilgan daftar (Terraform shu daftarga qarab keyingi safar nima qilishni biladi).

Nega muhim?

  • Takrorlanuvchanlik — bitta buyruq bilan dev/staging/prod'ni bir xil yaratasiz (qo'l xatosi yo'q).
  • Versiyalash — infratuzilma Git'da, har o'zgarish review/rollback qilinadi (10.6'dagi ClickOps'da bu yo'q).
  • Hujjat — kod o'zi hujjat: "nima bor?" degan savolga .tf fayllar javob beradi.
  • Intervyu/ish — "Terraform bilan ishlaganmisan? state nima?" — DevOps/SRE intervyularining markaziy savoli.

2. Nazariya — chuqur tushuntirish

2.1. IaC nima: imperative vs declarative, ClickOps muammosi

text
  INFRASTRUCTURE AS CODE (IaC) — infratuzilmani QO'LDA emas, KOD bilan boshqarish:
   server, tarmoq, DB, IP — hammasi matnli faylda ta'riflanadi (versiyalanadi)

  3 XIL YONDASHUV (infratuzilma qanday yaratiladi):

  1. ClickOps (QO'LDA) — AWS Console'da sichqoncha bilan 10.6-bob:
      takrorlab bo'lmaydi (har safar boshqacha)
      hujjatsiz ("qanday sozlagandim?" — eslab bo'lmaydi)
      xato ko'p (inson qo'li), audit yo'q

  2. IMPERATIVE (qadamlar bilan) — skript yoziladi (bash, AWS CLI — 10.6):
     "avval EC2 yarat, keyin SG yarat, keyin biriktir..." (HOW — qanday)
      holat o'zgarsa — skript buziladi (allaqachon bor bo'lsa xato beradi)

  3. DECLARATIVE (kerakli holat) — Terraform:
     "menga 1 EC2 + 1 S3 + 1 SG KERAK" (WHAT — nima, tartibni o'zi hal qiladi)
      Terraform real holatni tekshirib, FARQNI hisoblaydi (yo'qni yaratadi)
      ikki marta ishlatsang ham — natija bir xil (idempotent)

Infrastructure as Code (IaC) — infratuzilmani qo'lda (sichqoncha bilan) emas, matnli kod fayllar orqali ta'riflash va boshqarish. Uch xil yondashuv bor. ClickOps — AWS Console'da qo'lda bosish (10.6'da shunday qildik): takrorlab bo'lmaydi, hujjatsiz, xato ko'p. Imperative (buyruqli) — qadamlarni skript bilan yozasiz (bash + AWS CLI): "avval bu, keyin u" — ya'ni qanday (HOW) qilishni aytasiz; muammosi — resurs allaqachon mavjud bo'lsa, skript buziladi. Declarative (e'lon qiluvchi) — Terraform yondashuvi: nima (WHAT) kerakligini ta'riflaysiz ("1 ta EC2 kerak"), tartibni va qadamlarni Terraform o'zi hal qiladi. Eng muhim afzallik — idempotentlik: bir xil kodni ikki, o'n marta ishlatsangiz ham natija bir xil bo'ladi (Terraform real holatni tekshirib, faqat yetishmagan qismni yaratadi). Bu ClickOps'da mutlaqo yo'q.

2.2. Terraform nima va nega (multi-cloud, declarative engine)

text
  TERRAFORM — IaC vositasi (HashiCorp), infratuzilmani kod bilan quradi:
  "Terraform lets you build, change, and version cloud and on-prem resources
   safely and efficiently" (rasmiy ta'rif)

  ASOSIY XUSUSIYATLAR:
   DECLARATIVE — kerakli holatni ta'riflaysan 2.1-bob, Terraform amalga oshiradi
   MULTI-CLOUD — bitta til (HCL) bilan AWS, GCP, Azure, K8s, GitHub... 2.3-bob
   STATE-BASED — real holatni state faylda kuzatadi 2.7-bob
   PLAN — o'zgarishni OLDINDAN ko'rsatadi (xavfsizlik — 2.6, 2.8)

  TERRAFORM QANDAY ISHLAYDI (yuqori daraja):
  ┌──────────────┐   o'qiydi   ┌─────────────┐   API    ┌──────────────┐
  │  .tf fayllar │ ────────── │  TERRAFORM  │ ─────── │  AWS / GCP   │
  │  (HCL kod)   │             │  (engine +  │          │  (haqiqiy    │
  │  kerakli     │             │  provider)  │ ─────── │   resurslar) │
  │  holat       │             └──────┬──────┘  holat   └──────────────┘
  └──────────────┘                    │
                              ┌────────▼────────┐
                              │ terraform.tfstate│   real holat xaritasi
                              └─────────────────┘

Terraform — HashiCorp'ning IaC vositasi: cloud va on-prem (o'z data-markazingdagi) resurslarni kod bilan quradi, o'zgartiradi va versiyalaydi. Asosiy xususiyatlari: declarative (kerakli holatni ta'riflaysiz — 2.1); multi-cloud — bitta til (HCL) bilan AWS, GCP, Azure, Kubernetes, GitHub va minglab boshqa platformalarni boshqarasiz (har biri uchun alohida CLI o'rganmaysiz — 2.3); state-based — real holatni terraform.tfstate faylda kuzatadi 2.7-bob; plan — har o'zgarishni amalga oshirishdan oldin ko'rsatadi 2.6-bob. Ishlash mexanizmi: siz .tf fayllarda kerakli holatni yozasiz Terraform engine ularni o'qiydi, provider orqali 2.4-bob cloud API'siga murojaat qiladi resurslarni yaratadi/o'zgartiradi natijani state faylga yozadi. Keyingi safar Terraform avval state'ni o'qiydi, real holat bilan kerakli holatni solishtiradi va faqat farqni qo'llaydi. Terraform — IaC bozorining eng keng tarqalgan vositasi (Pulumi, OpenTofu — muqobillar, 2.13).

2.3. HCL til: block, argument, expression

text
  HCL (HashiCorp Configuration Language) — Terraform'ning tili:
   matnli, o'qilishi oson, ikki asosiy qurilma: ARGUMENT va BLOCK

  ARGUMENT — nomga qiymat beradi (ism = qiymat):
  ┌─────────────────────────────────┐
  │  instance_type = "t3.micro"     │
  │  └────┬─────┘  │  └────┬─────┘   │
  │     IDENTIFIER =     QIYMAT       │
  │     (nom)        (expression)     │
  └─────────────────────────────────┘

  BLOCK — boshqa mazmun saqlovchi konteyner (TUR + LABEL'lar + tana {}):
  ┌──────────────────────────────────────────────┐
  │  resource  "aws_instance"  "web"  {           │
  │  └───┬───┘ └──────┬──────┘ └─┬─┘  │           │
  │    TUR        1-LABEL     2-LABEL  tana        │
  │  (block type) (resurs turi)(nom)               │
  │                                                │
  │    ami           = "ami-0abc123"   argument   │
  │    instance_type = "t3.micro"      argument   │
  │  }                                             │
  └──────────────────────────────────────────────┘

  IZOH:   # bir qatorli (asosiy)   // ham mumkin   /* ko'p qatorli */
   Fayl UTF-8, kengaytma .tf ; identifier harf/_ bilan boshlanadi

HCL (HashiCorp Configuration Language) — Terraform yoziladigan til (matnli, inson o'qishi uchun qulay). Ikki asosiy qurilma bor (rasmiy hujjat). Argument — nomga qiymat beradi: instance_type = "t3.micro" (chap tomonda identifier — nom, teng belgidan keyin expression — qiymat/ifoda). Block — boshqa mazmunni saqlovchi konteyner: tur (block type — resource, variable, provider...), keyin label'lar (0 yoki undan ko'p — resource ikki label oladi: resurs turi "aws_instance" va nom "web"), va { } ichidagi tana (body — argumentlar va ichki bloklar). Sintaksis qoidalari (rasmiy): fayl UTF-8 kodlangan, kengaytmasi .tf; izohlar — # (asosiy, idiomatik), // yoki /* */; identifier harf yoki _ bilan boshlanadi (raqam bilan emas), faqat harf/raqam/_/- bo'ladi. HCL JSON emas — ancha o'qilishi oson, lekin Terraform JSON formatini ham qabul qiladi (mashina generatsiyasi uchun).

2.4. Provider — cloud bilan ko'prik (aws/gcp/azure)

text
  PROVIDER — Terraform'ni biror platformaga ulaydigan PLAGIN:
   har resurs turi bitta provider tomonidan amalga oshiriladi
   providersiz Terraform HECH NARSA boshqara olmaydi (rasmiy)

  MASHHUR PROVIDER'LAR (Terraform Registry'da minglab bor):
  - hashicorp/aws     AWS (EC2, S3, RDS — 10.6)
  - hashicorp/google  Google Cloud (GCP)
  - hashicorp/azurerm Microsoft Azure
  - hashicorp/kubernetes  K8s 10.8-bob ;  cloudflare, github, docker...

  E'LON QILISH (har modul qaysi provider kerakligini AYTADI):
  terraform {
    required_providers {
      aws = {
        source  = "hashicorp/aws"   # Registry'dagi manba
        version = "~> 5.0"          # versiya cheklovi (2.12 — muhim!)
      }
    }
  }

  provider "aws" {                  # provider'ni sozlash
    region = "eu-central-1"         # qaysi region (10.6: 2.2)
  }

Provider — Terraform'ni biror platforma (AWS, GCP, Azure...) bilan bog'laydigan plagin. Har bir resurs turi (aws_instance, aws_s3_bucket) aniq bir provider tomonidan amalga oshiriladi — provider o'sha platformaning API'sini biladi. Rasmiy: providersiz Terraform hech qanday infratuzilmani boshqara olmaydi — u Terraform'ning "qo'llari". Mashhur provider'lar Terraform Registry'da: hashicorp/aws (AWS — 10.6), hashicorp/google (GCP), hashicorp/azurerm (Azure), hashicorp/kubernetes (K8s — 10.8), shuningdek cloudflare, github, docker va minglab boshqalar. Har modul qaysi provider kerakligini required_providers blokida e'lon qiladi (source — Registry manbasi, version — versiya cheklovi). Keyin provider "aws" { region = ... } bilan sozlanadi (qaysi region, ixtiyoriy autentifikatsiya). terraform init 2.6-bob shu e'londan kelib chiqib provider'larni avtomatik yuklab oladi.

2.5. Resource va data source

text
  RESOURCE — Terraform YARATADIGAN/boshqaradigan obyekt (eng muhim element):
   "Resources are the most important element in the Terraform language" (rasmiy)
   bitta resource bloki = bitta (yoki ko'p) infratuzilma obyekti

  resource "aws_instance" "web" {     # YARATILADI (Terraform boshqaradi)
    ami           = "ami-0abc123"
    instance_type = "t3.micro"
  }
   ichki murojaat: aws_instance.web.id  (boshqa joyda shu resursga havola)

  DATA SOURCE — MAVJUD resursni faqat O'QIYDI (yaratmaydi):
   Terraform tashqarida yaratilgan narsani "ko'radi" (faqat o'qish)

  data "aws_ami" "ubuntu" {           # MAVJUD AMI'ni IZLAYDI (yaratmaydi)
    most_recent = true
    owners      = ["099720109477"]    # Canonical (Ubuntu)
    filter { name = "name"  values = ["ubuntu/images/*-24.04-*"] }
  }
   ishlatish: ami = data.aws_ami.ubuntu.id  (topilgan AMI'ni resource'ga ber)

   resource = MEN yarataman/boshqaraman ; data = MAVJUD narsani o'qiyman

Resource — Terraform yaratadigan va boshqaradigan infratuzilma obyekti, eng muhim element (rasmiy: "Resources are the most important element in the Terraform language"). Bitta resource bloki bitta (yoki bir nechta) obyektni ta'riflaydi: resource "aws_instance" "web" { ... } — Terraform shu EC2 instance'ni yaratadi, o'zgartiradi va destroy'da o'chiradi. Resursga boshqa joyda havola qilish — aws_instance.web.id (Terraform o'zi to'g'ri tartibni — dependency graph'ni — quradi, 2.8). Data source esa — mavjud (Terraform tashqarisida yaratilgan) resursni faqat o'qiydi (yaratmaydi): data "aws_ami" "ubuntu" { ... } AWS'dagi eng so'nggi Ubuntu AMI'sini topadi, siz uni data.aws_ami.ubuntu.id orqali ishlatasiz. Asosiy farq: resource — men yarataman/boshqaraman; data — mavjud narsani o'qiyman (masalan, default VPC ID'sini olish, eng yangi AMI'ni topish). Bu — kodni qattiq qiymatlardan (hardcode) xalos qiladi.

2.6. Terraform workflow: init / plan / apply / destroy

text
  TERRAFORM ASOSIY ISH JARAYONI (4 buyruq — eng muhim):

  1. terraform init     TAYYORLASH (har loyihada birinchi marta):
      provider'larni yuklab oladi 2.4-bob, backend'ni sozlaydi 2.10-bob
      .terraform/ papka + .terraform.lock.hcl yaratiladi

  2. terraform plan     OLDINDAN KO'RISH (nima o'zgaradi — XAVFSIZLIK):
      real holat (state) bilan kerakli holatni solishtiradi
      + create (yashil)   ~ update   - destroy (qizil)  ko'rsatadi
      HECH NARSA o'zgartirmaydi (faqat reja — quruq yugurish)

  3. terraform apply    QO'LLASH (haqiqatan yaratadi/o'zgartiradi):
      plan'ni ko'rsatadi  "yes" deb tasdiqlaysan  bajaradi
      state faylni yangilaydi (real holat yoziladi)

  4. terraform destroy  O'CHIRISH (boshqarilgan hamma resursni o'chiradi):
      faqat Terraform yaratganini o'chiradi (ehtiyot — qaytmaydi!)

  YORDAMCHI: terraform fmt (formatla) | validate (tekshir) | show (holatni ko'r)

Terraform workflow — to'rt asosiy buyruq (rasmiy: write plan apply). terraform init — loyihani tayyorlaydi (har yangi loyihada birinchi marta): required_providers'dan provider'larni yuklab oladi, backend'ni 2.10-bob sozlaydi, .terraform/ papka va .terraform.lock.hcl (versiya qulflari) yaratadi. terraform plan — o'zgarishni oldindan ko'rsatadi: real holatni (state) kerakli holat bilan solishtirib, nima yaratilishi (+), o'zgarishi (~) yoki o'chishi (-) ni chiqaradi — lekin hech narsa qilmaydi (xavfsiz "quruq yugurish"). terraform apply — rejani qo'llaydi: avval plan'ni ko'rsatib, yes so'rab, keyin haqiqatan resurslarni yaratadi/o'zgartiradi va state'ni yangilaydi. terraform destroy — Terraform boshqargan hamma resursni o'chiradi (faqat o'zi yaratganini — qaytmaydi, ehtiyot bo'l). Yordamchi buyruqlar: terraform fmt (kodni standart formatlaydi), validate (sintaksisni tekshiradi), show (joriy state'ni ko'rsatadi). Doimo plan'ni ko'rib, keyin apply qil 2.8-bob.

2.7. State nima va nega muhim (tfstate, drift)

text
  STATE — Terraform boshqargan REAL holatning XARITASI:
   default: terraform.tfstate (JSON fayl, lokal)
   "source of truth" — qaysi kod qaysi haqiqiy resursga mos kelishi

  NEGA KERAK (Terraform'siz bilolmaydi):
  - kod: aws_instance.web      haqiqat: i-0abc123 (qaysi EC2 — state'da yozilgan)
  - state bo'lmasa — Terraform "men nimani yaratganman?" deb bilolmaydi
  - plan tezligi: state'dagi holatni asos qilib farqni hisoblaydi

  DRIFT — kod bilan haqiqat ORASIDAGI farq (kimdir QO'LDA o'zgartirsa):
  ┌──────────────┐         ┌──────────────┐         ┌──────────────┐
  │  KOD (.tf)   │  =?=    │  STATE       │  =?=    │  HAQIQAT(AWS)│
  │ t3.micro     │         │ t3.micro     │        │ t3.LARGE     │  kimdir
  └──────────────┘         └──────────────┘         └──────────────┘   qo'lda
   terraform plan drift'ni ko'rsatadi (qaytib kodga moslashtiradi — refresh)  o'zgartirgan

   STATE FAYLI — JIDDIY: secret'larni OCHIQ saqlashi mumkin (parol, kalit — 2.11)
   tfstate'ni Git'ga commit QILMA (xavf!) — remote backend ishlat (2.10)

State — Terraform boshqargan real infratuzilmaning xaritasi (rasmiy: "source of truth for your environment"). Default holatda lokal terraform.tfstate fayl (JSON). Nega kerak: Terraform kodingizdagi aws_instance.web qaysi haqiqiy EC2 instance'ga (i-0abc123) mos kelishini state'dan biladi — state bo'lmasa, Terraform "men nimani yaratganman?" deb bilolmaydi (resurslarni qayta yaratib yuboradi yoki o'chira olmaydi). Drift (siljish) — kod/state bilan haqiqat orasidagi farq: kimdir AWS Console'da qo'lda instance turini t3.micro'dan t3.large'ga o'zgartirsa, kod bilan haqiqat mos kelmay qoladi. terraform plan bu drift'ni aniqlaydi va kodga qaytib moslashtirishni taklif qiladi (refresh). Eng muhim xavfsizlik ogohlantirishi: state fayli secret'larni ochiq matnda saqlashi mumkin (DB paroli, kalitlar — 2.11). Shuning uchun terraform.tfstate'ni hech qachon Git'ga commit qilma va lokal saqlama — remote backend 2.10-bob ishlat. Bu IaC'dagi eng keng tarqalgan jiddiy xato.

2.8. Plan: oldindan ko'rish va dependency graph

text
  PLAN — apply'dan OLDIN nima bo'lishini ko'rsatadi (review qilinadi — xavfsizlik):

  $ terraform plan
  Terraform will perform the following actions:

    # aws_instance.web will be created
    + resource "aws_instance" "web" {
        + ami           = "ami-0abc123"           + yangi qiymat
        + instance_type = "t3.micro"
        + id            = (known after apply)     yaratilgach ma'lum bo'ladi
      }
  Plan: 1 to add, 0 to change, 0 to destroy.     XULOSA (eng muhim qator!)

  BELGILAR:  + create   ~ update (joyida)   -/+ replace (o'chir+yarat)   - destroy

  DEPENDENCY GRAPH — Terraform tartibni O'ZI hisoblaydi:
   aws_instance ami = data.aws_ami.ubuntu.id    AVVAL data, KEYIN instance
   bog'liq bo'lmaganlarni PARALLEL yaratadi (tez)

   plan'ni DOIM o'qi: "X to destroy" ko'rsatsa — nima o'chayotganini tekshir!

Plan — Terraform'ning eng muhim xavfsizlik xususiyati: apply'dan oldin aynan nima o'zgarishini ko'rsatadi, siz review qilasiz. Chiqishda har resurs uchun belgi: + (create — yaratiladi), ~ (update — joyida o'zgartiriladi), -/+ (replace — o'chirib qaytadan yaratiladi, masalan o'zgartirib bo'lmaydigan maydon o'zgarsa), - (destroy — o'chiriladi). Eng muhim qator — oxirgi xulosa: Plan: 1 to add, 0 to change, 0 to destroy. Dependency graph (bog'liqlik grafi): Terraform resurslar orasidagi havolalardan (data.aws_ami.ubuntu.id'ni ishlatgan instance — avval AMI o'qiladi, keyin instance) to'g'ri tartibni o'zi hisoblaydi — siz tartibni yozmaysiz (declarative — 2.1). Bog'liq bo'lmagan resurslarni parallel yaratadi (tez). Oltin qoida: plan chiqishini doimo o'qib chiq — agar "X to destroy" ko'rsatsa, nima o'chayotganini tekshir (production DB tasodifan o'chmasin). CI/CD'da plan'ni PR'ga qo'shish — eng yaxshi amaliyot (2.13, 10.5).

2.9. Variable va output: parametrlash

text
  VARIABLE — kodga TASHQARIDAN kiritiladigan qiymat (parametrlash):
  variable "instance_type" {
    type        = string
    default     = "t3.micro"        # berilmasa — shu (ixtiyoriy)
    description = "EC2 instance o'lchami"
  }
   ishlatish: instance_type = var.instance_type

  QIYMAT BERISH (bir necha usul, prioritet ortib boradi):
  - default (kodda)  <  terraform.tfvars fayl  <  -var CLI  <  TF_VAR_ env

  OUTPUT — apply'dan KEYIN chiqariladigan qiymat (natija):
  output "public_ip" {
    value = aws_instance.web.public_ip   # yaratilgan IP'ni ko'rsat
  }
   terraform apply oxirida: public_ip = "203.0.113.5"

  SENSITIVE — maxfiy qiymatni yashirish (parol, IP — 2.11):
  output "db_password" {
    value     = aws_db_instance.main.password
    sensitive = true                # plan/output'da "(sensitive)" deb yashiradi
  }

Variable — kodga tashqaridan kiritiladigan qiymat (kodni parametrlaydi — bir kodni dev/prod uchun turli qiymat bilan ishlatasiz). variable "instance_type" { type = string; default = "t3.micro" }type (turi), default (berilmasa ishlatiladigan qiymat — ixtiyoriy), description (izoh). Ishlatish — var.instance_type. Qiymat berish usullari (prioritet pastdan yuqoriga): kodadagi default < terraform.tfvars fayl < -var CLI bayrog'i < TF_VAR_ muhit o'zgaruvchisi. Outputapply'dan keyin chiqariladigan qiymat (natija — masalan yaratilgan EC2'ning public IP'si): output "public_ip" { value = aws_instance.web.public_ip }. Bu — boshqa modulga qiymat uzatish yoki sodda ravishda foydalanuvchiga ko'rsatish uchun. sensitive = true — maxfiy qiymatni (DB paroli) plan va output chiqishida (sensitive value) deb yashiradi (terminalga yoki log'ga oshkor bo'lmaydi). Lekin diqqat: u state faylda baribir ochiq saqlanadi (2.7, 2.11) — shuning uchun secret'larni alohida boshqarish kerak 10.11-bob.

2.10. Remote state va backend (S3 lock — jamoa)

text
  BACKEND — state QAYERDA saqlanishini belgilaydi:
  - LOCAL (default) — terraform.tfstate lokal faylda (faqat o'zing — yomon jamoa uchun)
  - REMOTE — markaziy joyda (S3, HCP Terraform, GCS, Azure Blob...) — JAMOA uchun

  NEGA REMOTE (jamoada lokal state YOMON):
   lokal: har kimda o'z nusxasi (bir-biriga zid — konflikt)
   lokal: kompyuter buzilsa — state yo'qoladi (resurslar "yetim" qoladi)
   remote: bitta markaziy state (hamma bir manbadan o'qiydi)
   remote: shifrlash + versiyalash + LOCK

  STATE LOCKING — ikki kishi BIR VAQTDA apply qilmasligi uchun qulf:
   A apply qilayotganda — B kutadi (state buzilmaydi — race condition yo'q)

  S3 BACKEND (AWS — eng keng tarqalgan):
  terraform {
    backend "s3" {
      bucket       = "mening-tfstate-2026"    # state saqlanadigan S3 (10.6: 2.6)
      key          = "prod/terraform.tfstate" # bucket ichidagi yo'l
      region       = "eu-central-1"
      encrypt      = true                      # state shifrlanadi (2.7 — secret!)
      use_lockfile = true                      # NATIVE S3 lock (2026 — yangi usul)
    }
  }
   ESKI: DynamoDB jadval bilan lock (endi deprecated — use_lockfile afzal — rasmiy)

Backend — state qayerda saqlanishini belgilaydi. Local (default) — terraform.tfstate lokal faylda (faqat o'zingiz ishlasangiz yetadi, lekin jamoa uchun yomon). Remote — markaziy joyda (AWS S3, HCP Terraform, GCS, Azure Blob). Nega remote: lokal state'da har kishida o'z nusxasi bo'lib, bir-biriga zid bo'ladi (konflikt); kompyuter buzilsa state yo'qoladi va resurslar "yetim" qoladi (Terraform ularni boshqara olmaydi). Remote — bitta markaziy manba, shifrlangan, versiyalangan. State locking (qulflash) — ikki kishi bir vaqtda apply qilib state'ni buzmasligi uchun: A apply qilayotganda B kutadi (race condition yo'q — 10.1 jamoa muammosiga o'xshash). S3 backend (eng keng tarqalgan): bucket, key (yo'l), region, encrypt = true (state shifrlanadi — 2.7 secret xavfi), va use_lockfile = true — S3'ning native lock mexanizmi. 2026 muhim yangilik (rasmiy): ilgari lock uchun alohida DynamoDB jadval kerak edi, endi u deprecated (eskirgan) — use_lockfile bilan S3'ning o'zi qulflaydi (DynamoDB shart emas). Eski loyihalar migratsiya uchun ikkalasini birga ishlatishi mumkin.

2.11. Module: qayta ishlatish

text
  MODULE — birga boshqariladigan resurslar TO'PLAMI (qayta ishlatiladigan paket):
   "A module is a collection of resources that Terraform manages together" (rasmiy)

  ROOT MODULE — sen turgan asosiy papka (terraform shu yerda ishga tushadi)
  CHILD MODULE — root chaqiradigan boshqa modul (module bloki orqali)

  CHAQIRISH (module bloki):
  module "vpc" {
    source  = "terraform-aws-modules/vpc/aws"  # Registry'dan (yoki ./local-yo'l)
    version = "5.0.0"                            # versiya (qulflash — 2.12)
    name    = "mening-vpc"                       # modulga kirish (variable)
    cidr    = "10.0.0.0/16"
  }
   natija: module.vpc.vpc_id  (modul output'iga murojaat)

  MANBA (source) TURLARI:
  - ./modules/network   lokal papka (o'z modullaring)
  - terraform-aws-modules/vpc/aws  Terraform Registry (ommaviy, tayyor)
  - github.com/org/repo  Git repozitoriy

   MODULE = funksiya (5.6'dagi funksiyaga o'xshash): input (var)  resurslar  output

Module — birga boshqariladigan resurslar to'plami (rasmiy ta'rif), qayta ishlatiladigan paket. Har Terraform loyihasida root module bor — siz turgan asosiy papka (Terraform shu yerda ishlaydi). Child module — root chaqiradigan boshqa modul (module bloki orqali). Chaqirish: module "vpc" { source = "..."; version = "..."; name = "..." }source modulni qayerdan olishni, qolgan argumentlar modulga kirish (input — variable) qiymatlarini beradi. Modul natijasiga murojaat — module.vpc.vpc_id. Source turlari: lokal papka (./modules/network — o'z modullaring), Terraform Registry (terraform-aws-modules/vpc/aws — tayyor, ommaviy modullar), yoki Git repozitoriy (github.com/...). Modulni funksiya deb tasavvur qil (5.6'dagi funksiyaga o'xshash): kirish (variable) qabul qiladi ichida resurslar yaratadi chiqish (output) qaytaradi. Bir marta yozasiz — dev/staging/prod'da, hatto turli loyihalarda qayta ishlatasiz (DRY — takrorlanishni kamaytirish). Bu — IaC'ning eng kuchli tomoni.

2.12. Workspace, versiya cheklovi va sensitive

text
  WORKSPACE — bir kod, ko'p ALOHIDA state (dev/staging/prod):
  terraform workspace new dev      # yangi workspace
  terraform workspace new prod
  terraform workspace select prod  # prod'ga o'tish
   har workspace'da AYRIM state (dev resurslari prod'dan ajralgan)
   ko'pincha katta loyihalarda alohida PAPKA/backend afzal (workspace o'rniga)

  VERSIYA CHEKLOVI (juda muhim — kutilmagan buzilishdan himoya):
  required_version = ">= 1.5"        # Terraform o'zining versiyasi
  version = "~> 5.0"    5.x ruxsat, 6.0 EMAS (pessimistik operator)
  version = ">= 5.0, < 6.0"          # aniq diapazon
   .terraform.lock.hcl provider'ni AYNAN qulflaydi (jamoa bir versiya)

  SENSITIVE / SECRET (10.11 bilan bog'liq):
  - sensitive = true  terminal/log'da yashiradi 2.9-bob
  - LEKIN state'da OCHIQ 2.7-bob  remote+encrypt MAJBURIY 2.10-bob
  - secret'larni kodga YOZMA  tfvars (gitignore) yoki Vault/SSM (10.11)

Workspace — bitta kod bilan bir nechta alohida state boshqarish (dev/staging/prod): terraform workspace new dev, select prod. Har workspace'ning ayrim state'i bor (dev resurslari prod'dan ajralgan, lekin kod bir xil). Amalda katta loyihalarda ko'pincha alohida papka/backend afzal ko'riladi (workspace o'rniga) — chunki workspace'lar bir backend'da turib chalkashtirishi mumkin. Versiya cheklovi (juda muhim — kutilmagan buzilishdan himoya): required_version = ">= 1.5" (Terraform CLI versiyasi), provider uchun version = "~> 5.0" — pessimistik operator (5.x ruxsat, lekin 6.0 emas — katta versiya buzuvchi o'zgarish keltirishi mumkin). .terraform.lock.hcl fayli provider versiyasini aynan qulflaydi (Git'ga commit qilinadi — jamoaning hammasi bir xil versiya ishlatadi, 4-QISM). Sensitive/secret 10.11-bob: sensitive = true terminal/log'da yashiradi 2.9-bob, lekin state'da ochiq qoladi 2.7-bob — shuning uchun remote backend + encrypt majburiy 2.10-bob, va secret'larni kodga yozma — .tfvars (gitignore) yoki Vault/AWS SSM Parameter Store ishlat 10.11-bob.

2.13. Terraform vs Ansible/CloudFormation/Pulumi/OpenTofu

text
  IaC VOSITALARI — qachon qaysi biri:

  ┌──────────────┬─────────────┬──────────────────────────────────────┐
  │ Vosita       │ Tur         │ Farqi                                │
  ├──────────────┼─────────────┼──────────────────────────────────────┤
  │ Terraform    │ provisioning│ declarative, multi-cloud, state, HCL │
  │ Ansible      │ config mgmt │ server ICHINI sozlash (paket, fayl)  │
  │              │             │  ko'pincha Terraform BILAN birga    │
  │ CloudFormation│ provisioning│ faqat AWS (HCL emas, YAML/JSON)      │
  │ Pulumi       │ provisioning│ Terraform'ga o'xshash, lekin TS/Py/Go│
  │ OpenTofu     │ provisioning│ Terraform'ning ochiq forki (2023+)   │
  └──────────────┴─────────────┴──────────────────────────────────────┘

  XULOSA:
  - infratuzilma YARATISH (server, tarmoq, DB)  Terraform (provisioning)
  - server ICHINI sozlash (Node o'rnatish, config)  Ansible yoki Docker 10.3-bob
   ko'p loyiha: Terraform (resurs) + Ansible/Docker (sozlash) — birga

IaC vositalari va ularning farqi. Terraformprovisioning (resurs yaratish): declarative, multi-cloud, state-li, HCL. Ansibleconfiguration management (server ichini sozlash — paket o'rnatish, config fayl yozish — 10.1'dagi qo'l ishini avtomatlashtiradi); ko'pincha Terraform bilan birga ishlatiladi (Terraform serverni yaratadi Ansible uni sozlaydi). CloudFormation — AWS'ning o'z IaC vositasi (faqat AWS, HCL emas — YAML/JSON; Terraform ko'p platformali). Pulumi — Terraform'ga o'xshash, lekin HCL o'rniga haqiqiy dasturlash tili (TypeScript/Python/Go — 7-QISM). OpenTofu — Terraform'ning litsenziya o'zgarishidan keyin paydo bo'lgan ochiq forki (2023+, deyarli mos). Qaror: infratuzilma yaratish (server, tarmoq, DB) Terraform; server ichini sozlash (Node o'rnatish, deploy) Ansible yoki Docker (10.3-10.4). Ko'p production loyihada ikkalasi birga ishlatiladi. Terraform — provisioning sohasida de-fakto standart, shuning uchun avval shuni o'rgan.

2.14. Ko'p resurs: count va for_each, dynamic block, lifecycle

text
  KO'P RESURS YARATISH — bir blok, ko'p nusxa (qo'lda takrorlamaslik — DRY):

  count — SON bo'yicha (0, 1, 2... nusxa):
  resource "aws_instance" "web" {
    count         = 3                      # 3 ta bir xil EC2
    instance_type = "t3.micro"
    tags = { Name = "web-${count.index}" } # count.index: 0,1,2
  }
   murojaat: aws_instance.web[0].id  (indeks bilan — ro'yxat)
   MUAMMO: o'rtadan bittasi o'chsa — indekslar SILJIYDI (keyingilar qayta yaratiladi)

  for_each — TO'PLAM (map/set) bo'yicha — TURG'UN kalit (afzalroq):
  resource "aws_instance" "web" {
    for_each      = toset(["web", "api", "worker"])   # 3 ta NOMLI
    instance_type = "t3.micro"
    tags = { Name = each.key }             # each.key / each.value
  }
   murojaat: aws_instance.web["api"].id  (kalit bilan — o'chsa boshqasi tegmaydi)
   QOIDA: bir xil nusxa + tartib muhim  count ;  nomli/turg'un  for_each (afzal)

  dynamic — takrorlanuvchi ICHKI BLOK generatsiyasi (SG qoidalari kabi):
  dynamic "ingress" {
    for_each = var.ports                   # [80, 443, 8080] uchun
    content {                              # har biriga bitta ingress bloki
      from_port = ingress.value  to_port = ingress.value  protocol = "tcp"
    }
  }

  lifecycle — resurs HAYOT SIKLINI boshqarish (meta-argument):
  lifecycle {
    create_before_destroy = true    # AVVAL yangi yarat, KEYIN eskini o'chir (uzilishsiz)
    prevent_destroy       = true    # bu resursni O'CHIRISHNI bloklaydi (prod DB himoyasi)
    ignore_changes        = [tags]  # bu maydon drift'ini E'TIBORSIZ qoldir (tashqi o'zgarish)
  }

count va for_each — bitta resurs blokidan ko'p nusxa yaratish (kodni takrorlamaslik). count = 3 — son bo'yicha 3 ta bir xil nusxa; count.index (0, 1, 2) bilan farqlash, murojaat aws_instance.web[0]. Muammosi: o'rtadagi nusxa o'chsa, indekslar siljiydi va keyingilar keraksiz qayta yaratiladi. for_each — map yoki set bo'yicha nusxalash, har biriga turg'un kalit beradi (each.key, each.value), murojaat aws_instance.web["api"]. Amaliy qoida: nusxalar bir xil va tartib muhim bo'lsa — count; nomli/turg'un identifikatsiya kerak bo'lsa — for_each afzal (bitta element o'chsa, qolganlariga tegmaydi). dynamic block — takrorlanuvchi ichki bloklarni (masalan Security Group'ning ko'p ingress qoidasi) ro'yxatdan avtomatik generatsiya qiladi (for_each + content bilan) — qo'lda o'nlab bir xil blok yozmaysiz. lifecycle — resurs hayot siklini boshqaradigan meta-argument: create_before_destroy = true (avval yangisini yaratib, keyin eskisini o'chiradi — almashtirishda uzilish bo'lmaydi); prevent_destroy = true (resursni o'chirishni butunlay bloklaydi — production ma'lumotlar bazasi uchun himoya); ignore_changes = [tags] (ko'rsatilgan maydondagi drift'ni e'tiborsiz qoldiradi — masalan tashqi tizim o'zgartiradigan teg).

2.15. Local values, depends_on, provisioner, provider alias, import

text
  LOCAL VALUES — kod ichidagi TAKRORLANUVCHI ifodaga nom (var emas — ichki):
  locals {
    project = "mening-loyiham"
    common_tags = { Project = local.project, ManagedBy = "Terraform" }
  }
   ishlatish: tags = local.common_tags   (bir marta yoz, hamma joyda ishlat — DRY)
   variable = TASHQARIDAN kiritiladi ;  local = ICHKARIDA hisoblanadi

  BOG'LIQLIK (dependency) — Terraform tartibni O'ZI biladi:
  - IMPLICIT (yashirin) — havola orqali AVTOMATIK (afzal):
    vpc_security_group_ids = [aws_security_group.web.id]   avval SG, keyin EC2
  - EXPLICIT — depends_on (havola YO'Q, lekin tartib kerak — kamdan-kam):
    resource "aws_instance" "web" {
      depends_on = [aws_s3_bucket.data]   # IAM/yon-effekt bog'liqligi
    }

  PROVISIONER — OXIRGI CHORA (resurs yaratilgach buyruq bajarish):
  provisioner "remote-exec" { inline = ["sudo apt install -y nginx"] }
   RASMIY: provisioner — SO'NGGI chora. Afzal: user_data / Ansible / Docker 2.13-bob

  PROVIDER ALIAS — bir provider'ning bir NECHTA sozlamasi (ko'p region):
  provider "aws" { region = "eu-central-1" }              # asosiy (default)
  provider "aws" { alias = "us"  region = "us-east-1" }   # ikkinchi region
   ishlatish: resource "aws_instance" "x" { provider = aws.us  ... }

  IMPORT — MAVJUD (qo'lda yaratilgan) resursni Terraform boshqaruviga olish:
  terraform import aws_instance.web i-0abc123   # eski usul (CLI)
  import { to = aws_instance.web  id = "i-0abc123" }  # yangi: import bloki (kodda)
   import faqat STATE'ga qo'shadi — resource blokini QO'LDA yozish kerak (plan tekshiradi)

Local values (locals) — kod ichida takrorlanuvchi ifodaga nom berish (local.common_tags). Farqi: variable tashqaridan kiritiladi (parametr), local ichkarida hisoblanadi (yordamchi ifoda — bir marta yoziladi, hamma joyda ishlatiladi, DRY). Bog'liqlik (dependency): Terraform resurslar tartibini o'zi aniqlaydi 2.8-bob. Implicit (yashirin) — bir resurs boshqasining atributiga havola qilsa (aws_security_group.web.id), Terraform avtomatik "avval SG, keyin EC2" tartibini quradi (bu — afzal usul). Explicitdepends_on = [...] bilan qo'lda ko'rsatiladi: havola yo'q, lekin yashirin bog'liqlik bor bo'lganda (masalan IAM ruxsati resurs yaratilishidan oldin tayyor bo'lishi kerak) — kamdan-kam ishlatiladi. Provisioner — resurs yaratilgach unda buyruq bajarish (remote-exec — SSH orqali skript). Rasmiy hujjat buni so'nggi chora (last resort) deb ataydi: undan oldin user_data, Ansible yoki Docker'ni ko'rib chiqing 2.13-bob — provisioner Terraform state'iga to'liq kirmaydi va mo'rt bo'ladi. Provider alias — bitta provider'ning bir nechta sozlamasi (masalan ikki AWS region): default provider'dan tashqari alias = "us" bilan ikkinchisi e'lon qilinadi, resursda provider = aws.us bilan tanlanadi (ko'p regionli deploy). Import — Terraform tashqarisida (qo'lda) yaratilgan mavjud resursni Terraform boshqaruviga olib kirish: eski usul terraform import CLI buyrug'i, yangi usul — koddagi import { to = ... id = ... } bloki. Import faqat resursni state'ga qo'shadi — mos resource blokini qo'lda yozish kerak (keyin plan kod bilan haqiqat mos kelishini tekshiradi). Bu — ClickOps bilan yaratilgan eski infratuzilmani IaC'ga ko'chirishning asosiy yo'li.


3. Sintaksis — tez ma'lumotnoma

text
WORKFLOW 2.6-bob: terraform init | plan | apply | destroy | fmt | validate | show
                terraform apply -auto-approve  (tasdiqsiz — CI/CD'da ehtiyot)
BLOCK 2.3-bob:    resource "<TUR>" "<NOM>" { argument = qiymat }
PROVIDER 2.4-bob: terraform { required_providers { aws = { source="hashicorp/aws" } } }
                provider "aws" { region = "eu-central-1" }
RESOURCE 2.5-bob: resource "aws_instance" "web" { ami = "..." instance_type = "..." }
DATA 2.5-bob:     data "aws_ami" "x" {...}    data.aws_ami.x.id
VARIABLE 2.9-bob: variable "name" { type=string default="..." }    var.name
OUTPUT 2.9-bob:   output "ip" { value = aws_instance.web.public_ip }
HAVOLA:         aws_instance.web.id  |  module.vpc.vpc_id  |  data.x.y.z
BACKEND 2.10-bob: terraform { backend "s3" { bucket=".." key=".." use_lockfile=true } }
MODULE 2.11-bob:  module "vpc" { source="./modules/vpc"  cidr="10.0.0.0/16" }
WORKSPACE2.12-bob:terraform workspace new|select|list  dev|prod
STATE 2.7-bob:    terraform state list | show <addr> | rm <addr>  (ehtiyotkorona!)
COUNT 2.14-bob:   resource "..." "x" { count = 3 ... }     ...x[0].id  (count.index)
FOR_EACH2.14-bob: resource "..." "x" { for_each = toset([...]) }    ...x["k"]  (each.key)
DYNAMIC 2.14-bob: dynamic "ingress" { for_each = ... content { ... } }
LIFECYCLE2.14-bob:lifecycle { create_before_destroy | prevent_destroy | ignore_changes }
LOCAL 2.15-bob:   locals { common_tags = {...} }    local.common_tags
DEPENDS 2.15-bob: depends_on = [aws_s3_bucket.data]   (yashirin bog'liqlik)
ALIAS 2.15-bob:   provider "aws" { alias = "us" ... }    provider = aws.us
IMPORT 2.15-bob:  import { to = aws_instance.web  id = "i-0abc123" }

4. Batafsil kod namunalari

Misol 1 — Terraform o'rnatish va birinchi loyiha (init)

bash
# Terraform o'rnatish (rasmiy — HashiCorp repozitoriysidan, Ubuntu — 10.1)
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor \
  -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
  https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform     # o'rnatish (10.1: 2.5)
terraform version                                 # tekshirish: Terraform v1.x.x

# Yangi loyiha papkasi
mkdir mening-infra && cd mening-infra              # bo'sh papka (root module — 2.11)
# main.tf faylini yozamiz (Misol 2), keyin:
terraform init                                     # provider yuklab oladi (2.6)
#  "Terraform has been successfully initialized!" (.terraform/ paydo bo'ladi)

Misol 2 — Provider va birinchi resurs (EC2 — 2.4, 2.5)

hcl
# main.tf — eng oddiy to'liq misol (AWS EC2 yaratish)

terraform {
  required_version = ">= 1.5"            # Terraform CLI versiyasi (2.12)
  required_providers {
    aws = {
      source  = "hashicorp/aws"          # Registry'dagi provider (2.4)
      version = "~> 5.0"                  # 5.x ruxsat, 6.0 emas (2.12)
    }
  }
}

provider "aws" {                         # provider sozlash
  region = "eu-central-1"                # Frankfurt (10.6: 2.2)
}                                        #  kalitlar bu yerda EMAS — env/IAM role (10.6: 2.9)

resource "aws_instance" "web" {          # YARATILADIGAN EC2 (2.5)
  ami           = "ami-0abc1234567890"   # Ubuntu AMI (region'ga xos — Misol 5'da data bilan)
  instance_type = "t3.micro"             # arzon, free tier (10.6: 2.11)

  tags = {
    Name = "web-server"                  # AWS Console'da ko'rinadigan nom
  }
}
bash
terraform plan      # nima yaratilishini ko'rsatadi 2.8-bob — "1 to add"
terraform apply     # "yes" so'raydi  haqiqatan EC2 yaratiladi (2.6)

Misol 3 — Variable bilan parametrlash (2.9)

hcl
# variables.tf — kiritiladigan qiymatlar (kodni dev/prod uchun moslaydi)

variable "instance_type" {
  type        = string
  default     = "t3.micro"               # berilmasa shu (2.9)
  description = "EC2 instance o'lchami"
}

variable "environment" {
  type        = string
  description = "Muhit nomi (dev/staging/prod)"
  # default yo'q  MAJBURIY (apply paytida so'raydi yoki tfvars'dan oladi)

  validation {                            # qiymatni tekshirish (faqat ruxsat etilgan)
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "environment faqat dev/staging/prod bo'lishi mumkin."
  }
}
hcl
# main.tf — variable'larni ishlatish
resource "aws_instance" "web" {
  ami           = "ami-0abc1234567890"
  instance_type = var.instance_type      # var.<nom> orqali (2.9)
  tags = {
    Name        = "web-${var.environment}"   # interpolatsiya: web-prod
    Environment = var.environment
  }
}

Misol 4 — terraform.tfvars bilan qiymat berish (2.9)

hcl
# prod.tfvars — production qiymatlari (alohida fayl)
environment   = "prod"
instance_type = "t3.large"               # prod kuchliroq

# dev.tfvars — development qiymatlari
# environment   = "dev"
# instance_type = "t3.micro"
bash
# Qaysi muhit uchun apply qilayotganimizni TANLAYMIZ (bir kod, har xil qiymat)
terraform plan  -var-file="prod.tfvars"        # prod rejasini ko'r
terraform apply -var-file="prod.tfvars"        # prod'ni qo'lla
#  *.tfvars'da secret bo'lsa — .gitignore'ga qo'sh (10.11, 2.11)

Misol 5 — Data source (mavjud AMI'ni topish — 2.5)

hcl
# AMI ID'sini QO'LDA yozmaslik — eng yangi Ubuntu'ni AVTOMATIK topamiz (2.5)
data "aws_ami" "ubuntu" {
  most_recent = true                       # eng so'nggisi
  owners      = ["099720109477"]           # Canonical (Ubuntu rasmiy egasi)

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-noble-24.04-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id   # topilgan AMI'ni ishlatamiz (2.5)
  instance_type = var.instance_type
  #  endi AMI ID'sini har region uchun qo'lda izlamaymiz — Terraform topadi
}

Misol 6 — Security Group resursi (10.6: 2.5 ni kodda)

hcl
# Security Group — virtual firewall (10.6: 2.5 — qo'lda emas, kodda)
resource "aws_security_group" "web_sg" {
  name        = "web-sg"
  description = "Web server firewall (Terraform boshqaradi)"

  ingress {                                # KIRUVCHI: SSH — faqat o'z IP'ngga
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["203.0.113.10/32"]      #  0.0.0.0/0 EMAS (10.6: 2.5 xavfsizlik)
    description = "SSH faqat ofis IP"
  }

  ingress {                                # KIRUVCHI: HTTP/HTTPS — hammaga
    from_port   = 80
    to_port     = 443                      # 80-443 oralig'i
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]            # web ochiq
  }

  egress {                                 # CHIQUVCHI: hammasi ochiq (default)
    from_port   = 0
    to_port     = 0
    protocol    = "-1"                     # barcha protokol
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web" {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.web_sg.id]  # SG'ni biriktiramiz (2.8 havola)
}

Misol 7 — S3 bucket resursi (10.6: 2.6 ni kodda)

hcl
# S3 bucket — kodda (10.6: 2.6 — qo'lda Console'da emas)
resource "aws_s3_bucket" "uploads" {
  bucket = "mening-loyiham-uploads-2026"   # GLOBAL noyob (10.6: 2.6)
  tags   = { Name = "Foydalanuvchi rasmlari" }
}

# Public kirishni BLOKLASH (default xavfsiz — 10.6: 2.6)
resource "aws_s3_bucket_public_access_block" "uploads" {
  bucket                  = aws_s3_bucket.uploads.id   # yuqoridagi bucket'ga havola
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true                       #  to'liq private (sizmasin)
}

# Versiyalash (tasodifan o'chgan faylni qaytarish — backup)
resource "aws_s3_bucket_versioning" "uploads" {
  bucket = aws_s3_bucket.uploads.id
  versioning_configuration { status = "Enabled" }
}

Misol 8 — Output bilan natija chiqarish (2.9)

hcl
# outputs.tf — apply'dan keyin ko'rsatiladigan qiymatlar (2.9)
output "instance_public_ip" {
  value       = aws_instance.web.public_ip     # yaratilgan EC2 IP'si
  description = "Web server public IP (SSH/brauzer uchun)"
}

output "bucket_name" {
  value = aws_s3_bucket.uploads.bucket
}

output "ssh_command" {                          # tayyor SSH buyrug'i (qulay)
  value = "ssh ubuntu@${aws_instance.web.public_ip}"   # 10.1: 2.8
}
bash
terraform apply
# Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
# Outputs:
#   instance_public_ip = "203.0.113.5"
#   ssh_command        = "ssh ubuntu@203.0.113.5"
terraform output instance_public_ip            # bitta output'ni alohida olish

Misol 9 — Remote backend (S3 + native lock — 2.10)

hcl
# backend.tf — state'ni S3'da saqlash (jamoa uchun — 2.10)
terraform {
  backend "s3" {
    bucket       = "mening-tfstate-2026"        # state saqlanadigan S3 (avval yaratilgan)
    key          = "prod/terraform.tfstate"     # bucket ichidagi yo'l
    region       = "eu-central-1"
    encrypt      = true                          # state SHIFRLANADI (2.7 — secret xavfi!)
    use_lockfile = true                          # NATIVE S3 lock (2026 — DynamoDB shart emas)
  }
}
bash
# Lokal state'dan remote'ga ko'chirish (init backend'ni o'rnatadi)
terraform init -migrate-state                    # "yes"  state S3'ga ko'chadi
#  Endi jamoa bir state'dan ishlaydi, ikki kishi bir vaqtda apply qilolmaydi (lock — 2.10)
#  tfstate'ni Git'ga commit QILMA — .gitignore: *.tfstate, *.tfstate.*, .terraform/

Misol 10 — Module ishlatish (qayta foydalanish — 2.11)

hcl
# main.tf — tayyor VPC modulini Registry'dan chaqiramiz (2.11)
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"      # Terraform Registry (ommaviy)
  version = "5.0.0"                              # versiya qulflanadi (2.12)

  name = "mening-vpc"
  cidr = "10.0.0.0/16"                           # tarmoq diapazoni (10.6: 2.10)

  azs             = ["eu-central-1a", "eu-central-1b"]   # 2 AZ (10.6: 2.2)
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]       # public (EC2)
  private_subnets = ["10.0.11.0/24", "10.0.12.0/24"]     # private (RDS — 10.6: 2.10)
}

# Modul OUTPUT'iga murojaat (2.11)
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type
  subnet_id     = module.vpc.public_subnets[0]   # modul yaratgan public subnet'ga qo'y
}

output "vpc_id" {
  value = module.vpc.vpc_id                       # modul qaytargan VPC ID (2.11)
}

Misol 11 — count va for_each: ko'p resurs (2.14)

hcl
# count — bir xil 3 ta EC2 (indeks bilan farqlanadi)
resource "aws_instance" "worker" {
  count         = 3                                # 3 nusxa (2.14)
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  tags = { Name = "worker-${count.index}" }        # worker-0, worker-1, worker-2
}
# murojaat: aws_instance.worker[0].id  (ro'yxat — indeks bilan)

# for_each — NOMLI resurslar (turg'un kalit — o'chsa boshqasi tegmaydi — afzal)
resource "aws_instance" "service" {
  for_each      = toset(["web", "api", "worker"])  # 3 ta nomli (2.14)
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type
  tags = { Name = each.key }                       # each.key: "web"/"api"/"worker"
}
# murojaat: aws_instance.service["api"].public_ip  (kalit bilan)

Misol 12 — dynamic block + local values (2.14, 2.15)

hcl
# local — takrorlanuvchi qiymatlarga nom (bir marta yoz, hamma joyda ishlat — 2.15)
locals {
  project     = "mening-loyiham"
  common_tags = { Project = local.project, ManagedBy = "Terraform" }
  web_ports   = [80, 443, 8080]                    # ochiladigan portlar ro'yxati
}

# dynamic — takrorlanuvchi ingress bloklarini ro'yxatdan generatsiya (2.14)
resource "aws_security_group" "web_sg" {
  name = "web-sg"
  tags = local.common_tags                         # local'ni ishlatamiz (DRY)

  dynamic "ingress" {                              # local.web_ports uchun har biriga blok
    for_each = local.web_ports
    content {
      from_port   = ingress.value                  # ingress.value: 80, 443, 8080
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

Misol 13 — lifecycle va explicit depends_on (2.14, 2.15)

hcl
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  depends_on = [aws_s3_bucket.uploads]             # yashirin bog'liqlik (2.15)

  lifecycle {
    create_before_destroy = true                   # avval yangi, keyin eski (uzilishsiz — 2.14)
    ignore_changes        = [tags["LastScanned"]]  # tashqi tizim tegini e'tiborsiz qoldir
  }
}

# Production ma'lumotlar bazasi — tasodifan o'chmasin (2.14)
resource "aws_db_instance" "main" {
  identifier = "prod-db"
  # ...
  lifecycle {
    prevent_destroy = true                         # destroy'ni bloklaydi (himoya)
  }
}

Misol 14 — Provider alias va import (2.15)

hcl
# Bir provider — ikki region (alias bilan — 2.15)
provider "aws" {
  region = "eu-central-1"                          # asosiy (default) — Frankfurt
}
provider "aws" {
  alias  = "us"                                    # ikkinchi sozlama
  region = "us-east-1"                             # Virginia (masalan CloudFront/ACM uchun)
}

resource "aws_instance" "us_web" {
  provider      = aws.us                           # AYNAN us region provider'i (2.15)
  ami           = "ami-0abc1234567890"
  instance_type = "t3.micro"
}

# Mavjud (qo'lda yaratilgan) resursni Terraform boshqaruviga olish (2.15)
import {
  to = aws_instance.legacy                         # koddagi manzil
  id = "i-0abc123def456"                           # AWS'dagi haqiqiy ID
}
#  Mos "resource aws_instance legacy {...}" blokini QO'LDA yozib, keyin:
#    terraform plan   kod bilan haqiqat mos kelishini tekshiradi (farq bo'lsa ko'rsatadi)

Misol 15 — CI/CD: GitHub Actions'da plan (PR) va apply (merge) — 10.5

yaml
# .github/workflows/terraform.yml — infratuzilmani avtomatik qo'llash (10.5)
name: Terraform
on:
  pull_request:            # PR'da faqat PLAN (o'zgarish ko'rinadi, review qilinadi — 2.8)
  push:
    branches: [main]       # main'ga merge bo'lganda APPLY (2.6)

jobs:
  terraform:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write # plan natijasini PR izohiga yozish uchun
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform fmt -check           # format buzilgan bo'lsa — fail (2.6, 8-bo'lim)
      - run: terraform validate             # sintaksis tekshiruvi (2.6)
      - run: terraform plan -no-color       # PR'da: nima o'zgarishini ko'rsatadi (2.8)
      - name: Apply (faqat main)
        if: github.ref == 'refs/heads/main' # PR'da EMAS — faqat merge'dan keyin
        run: terraform apply -auto-approve  # tasdiqlangan o'zgarishni qo'llaydi (2.6)
    env:                                    # AWS kalitlari — GitHub Secrets (kodda EMAS — 10.11)
      AWS_ACCESS_KEY_ID:     ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

5. To'g'ri va noto'g'ri holatlar

1) Infratuzilma yaratish usuli

text
 AWS Console'da qo'lda (ClickOps — takrorlab/hujjatlab bo'lmaydi — 2.1)
 Terraform kod — versiyalanadi, takrorlanadi, review qilinadi

2) State saqlash

text
 terraform.tfstate'ni Git'ga commit qilish (secret sizadi, konflikt — 2.7)
 Remote backend (S3 + encrypt + lock); tfstate'ni .gitignore'ga (2.10)

3) Apply qilish tartibi

text
 Ko'rmasdan to'g'ridan apply (yoki -auto-approve hamma yerda)
 Avval terraform plan'ni o'qi, KEYIN apply (nima o'chayotganini tekshir — 2.8)

4) AMI / qiymatlar

text
 ami = "ami-0abc..." qo'lda (har region boshqacha, eskiradi — 2.5)
 data "aws_ami" bilan avtomatik topish (har region'da ishlaydi — 2.5)

5) Secret boshqaruvi

text
 DB parolini main.tf'ga yozish (kodda ochiq, git'ga ketadi — 2.12)
 tfvars (gitignore) yoki Vault/SSM; sensitive=true; encrypt (10.11, 2.11)

6) Provider versiyasi

text
 version berilmagan (har init turli versiya — kutilmagan buzilish)
 version = "~> 5.0" + .terraform.lock.hcl commit (jamoa bir xil — 2.12)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — State qo'lda o'zgartirilgan (drift)

Sababi: kimdir AWS Console'da resursni qo'lda o'zgartirgan (instance turi, SG qoidasi) — kod/state bilan haqiqat mos kelmaydi 2.7-bob. Yechimi: terraform plan drift'ni ko'rsatadi terraform apply kodga qaytib moslashtiradi (yoki kodni haqiqatga moslab yozasiz). Oldini olish: resurslarni faqat Terraform orqali o'zgartir (qo'lda tegma — 2.1).

Xato 2 — Error acquiring the state lock

Sababi: boshqa apply hali tugamagan (lock ushlab turibdi), yoki avvalgi apply yarim qolib lock "osilib" qolgan 2.10-bob. Yechimi: boshqa apply tugashini kut; haqiqatan osilib qolgan bo'lsa terraform force-unlock <LOCK_ID> (ehtiyotkorona — faqat ishonch bo'lsa).

Xato 3 — tfstate'da secret ochiq qolgan

Sababi: DB paroli/kalit state faylda ochiq matnda saqlanadi 2.7-bob, tfstate Git'ga ketgan. Yechimi: tfstate'ni Git tarixidan o'chir (sizib ketgan parolni almashtir — kech), remote backend + encrypt=true o'rnat 2.10-bob, tfstate'ni .gitignore'ga qo'sh 14.5-bob.

Xato 4 — Plan'siz apply, resurs kutilmaganda o'chgan

Sababi: o'zgartirib bo'lmaydigan maydon (masalan ami) o'zgargan Terraform resursni replace qiladi (o'chir+yarat — 2.8), plan'ni o'qimasdan apply qilingan. Yechimi: doim plan'ni o'qi (-/+ replace belgisiga e'tibor); production'da prevent_destroy lifecycle qo'y. Oldini olish: CI/CD'da plan'ni PR'ga chiqar (2.13, 10.5).

Xato 5 — No valid credential sources found (autentifikatsiya)

Sababi: AWS kalitlari topilmadi (provider sozlanmagan). Yechimi: aws configure (10.6: Misol 1) yoki AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY env, yoki EC2'da IAM role (10.6: 2.9 — eng xavfsiz). Kalitni provider blokiga yozma (git'ga ketadi).

Xato 6 — Provider versiyasi mos kelmadi / kutilmagan buzilish

Sababi: version berilmagan, yangi major versiya 6.0-bob buzuvchi o'zgarish keltirgan 2.12-bob. Yechimi: version = "~> 5.0" qo'y, .terraform.lock.hcl'ni commit qil (jamoa bir versiya); terraform init -upgrade bilan ataylab yangila.

Xato 7 — terraform destroy kerakli resursni o'chirdi

Sababi: destroy Terraform boshqargan hammasini o'chiradi (production DB ham — 2.6). Yechimi: muhim resursga lifecycle { prevent_destroy = true } qo'y; destroy oldidan terraform plan -destroy bilan ro'yxatni ko'r. Eslatma: o'chgan ma'lumot qaytmaydi — backup shart (10.6: 2.7 RDS backup).


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • AWS cloud 10.6-bob: Terraform aynan shu EC2/S3/RDS/SG resurslarini qo'lda emas, kodda yaratadi (bu bobning markaziy bog'lanishi).
  • CI/CD 10.5-bob: GitHub Actions'da terraform plan (PR'da) + apply (merge'da) — infratuzilma avtomatik qo'llanadi.
  • Linux/SSH 10.1-bob: Terraform serverni yaratadi, keyin user_data yoki Ansible uni sozlaydi (paket, deploy).
  • Docker/K8s (10.3, 10.8): kubernetes/helm provider bilan klaster va deploy'larni ham Terraform boshqaradi.
  • Secrets 10.11-bob: state'dagi secret xavfi sensitive, encrypt, Vault/SSM — keyingi bob.
  • Git (4-QISM): .tf fayllar versiyalanadi, .terraform.lock.hcl commit, tfstate .gitignore.
  • Xavfsizlik 14.5-bob: kalit/parol kodga yozilmaydi, state shifrlangan remote'da.

8. Eng yaxshi amaliyotlar (best practices)

  • Hammasi kodda — ClickOps o'rniga Terraform; har o'zgarish Git'da (2.1, review — 15.2).
  • Remote backend + lock — S3 + encrypt + use_lockfile (jamoa, xavfsiz — 2.10).
  • State'ni hech qachon Git'ga qo'yma.gitignore: *.tfstate, .terraform/ 2.7-bob.
  • Doim plan'ni o'qi — apply'dan oldin, ayniqsa destroy/replace'ga e'tibor 2.8-bob.
  • Versiyani qulflarequired_version + provider version + lock fayl commit 2.12-bob.
  • Parametrlashvariable/tfvars bilan (kodni hardcode qilma — dev/prod — 2.9).
  • fmt va validate — har commit oldidan (toza kod, CI'da tekshir — 15.3).
  • Modul bilan DRY — takrorlanuvchi qismni modulga (qayta ishlat — 2.11).
  • Least privilege — Terraform IAM huquqi minimal; secret kodda emas (10.6: 2.9, 10.11).
  • Kichik, fokuslangan state — butun infrani bitta state'ga tiqma (xavf/sekinlik kamayadi).

9. Amaliy loyiha: "Infratuzilmani noldan kodda ko'tarish"

10.6 da qo'lda yaratgan AWS infratuzilmani butunlay Terraform kodiga ko'chir — bir buyruq bilan ko'tarib-tushiriladigan, versiyalangan infratuzilma.

Maqsad

Bo'sh papkadan boshlab, HCL kod bilan to'liq web infratuzilma yarat: VPC (yoki default), Security Group, EC2 instance (eng yangi Ubuntu AMI), S3 bucket — hammasi terraform apply bilan ko'tarilsin, terraform destroy bilan izsiz o'chsin. State remote (S3) backend'da, parametrlangan (dev/prod), modul bilan tartibli.

Talablar (requirements)

  1. Provider: aws provider, required_version va version qulflangan (Misol 2, 2.12).
  2. Variable: environment (dev/prod, validation bilan) va instance_type (Misol 3, 2.9).
  3. Data source: eng yangi Ubuntu 24.04 AMI'ni avtomatik top (Misol 5, 2.5).
  4. Security Group: SSH faqat o'z IP'ngga, HTTP/HTTPS hammaga (Misol 6, 10.6: 2.5).
  5. EC2: data AMI + variable type + SG biriktirilgan (Misol 2, 6).
  6. S3: bucket + public access block + versioning (Misol 7, 10.6: 2.6).
  7. Output: EC2 public IP va tayyor ssh buyrug'i (Misol 8, 2.9).
  8. Remote backend: state S3'da, encrypt + use_lockfile (Misol 9, 2.10).
  9. Parametrlash: dev.tfvars va prod.tfvars — bir kod, ikki muhit (Misol 4, 2.9).
  10. Hujjat: .gitignore (tfstate, .terraform), kichik README — qanday ishga tushirish.

Maslahatlar (hint)

  • Avval lokal state bilan ishla, ishlagach backend qo'shib init -migrate-state qil (Misol 9).
  • Har apply'dan oldin albatta plan'ni o'qi — nima yaratilayotganini ko'r 2.8-bob.
  • AMI'ni qo'lda yozma — data "aws_ami" ishlat (har region'da ishlaydi — 2.5).
  • Kalitni kodga yozma — aws configure yoki env (10.6: Misol 1, Xato 5).
  • Tugatgach terraform destroy qil — keraksiz AWS hisobi kelmasin (10.6: 2.11 billing).
  • Kodni fmt bilan formatla, validate bilan tekshir (8-bo'lim).

"Tayyor" mezonlari (acceptance criteria)

  • terraform init provider'larni muvaffaqiyatli yuklab oladi.
  • terraform plan aniq nima yaratilishini ko'rsatadi (xulosa qatori bilan).
  • terraform apply EC2 + SG + S3'ni haqiqatan yaratadi, output'da IP chiqadi.
  • Brauzer/SSH orqali EC2'ga ulanish ishlaydi (output'dagi buyruq bilan).
  • State S3 backend'da (lokal terraform.tfstate yo'q), encrypt yoqilgan.
  • dev.tfvars/prod.tfvars bilan har xil instance turi qo'llanadi.
  • .gitignore'da tfstate va .terraform/ bor (Git'ga ketmaydi).
  • terraform destroy hamma resursni izsiz o'chiradi.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda Infrastructure as Code va Terraform'ni chuqur o'rgandik:

  • IaC (qo'lda ClickOps muammosi, imperative vs declarative — 2.1); Terraform (multi-cloud, declarative engine — 2.2); HCL (block, argument, expression — 2.3).
  • Provider (cloud ko'prigi — 2.4); resource va data source (yaratish vs o'qish — 2.5); workflow (init/plan/apply/destroy — 2.6).
  • State (tfstate, drift, secret xavfi — 2.7); plan (oldindan ko'rish, dependency graph — 2.8); variable/output (parametrlash — 2.9).
  • Remote backend (S3 + native lock — 2.10); module (qayta ishlatish — 2.11); workspace/versiya/sensitive 2.12-bob; vositalar taqqosi 2.13-bob.
  • Ko'p resurs (count/for_each, dynamic block, lifecycle — 2.14); local values, depends_on, provisioner, provider alias, import 2.15-bob; CI/CD integratsiyasi (plan PR'da, apply merge'da — Misol 15, 10.5).

Endi siz infratuzilmani qo'lda emas, kodda quray olasiz — versiyalangan, takrorlanadigan, jamoada ishonchli. Bu — 10.6'dagi ClickOps'ni professional, qaytariladigan jarayonga aylantiradi. "Serverni qo'lda sozlayman" chegarasidan o'tildi — endi infratuzilma ham dastur kabi boshqariladi.

Keyingi bob — 10.11-bob: Environment va secrets boshqaruvi. Terraform state'da secret'lar ochiq saqlanishini ko'rdik (2.7, 2.11) — bu jiddiy muammoning bir qismi. Endi to'liq savol: ilova va infratuzilma uchun maxfiy ma'lumotlarni (DB parol, API kalit, JWT secret) qayerda va qanday saqlash kerak? .env fayllar, environment o'zgaruvchilari, va professional yechimlar — HashiCorp Vault, AWS Secrets Manager/SSM Parameter Store. Bu — 10-QISM'ning so'nggi va xavfsizlik uchun eng muhim mavzularidan biri.


Foydalanilgan rasmiy/ishonchli manbalar

  • HashiCorp Developer — "What is Terraform?" va IaC tushunchasi (declarative vs imperative), 2026
  • Terraform Language — Configuration Syntax (HCL): block, argument, expression; izohlar, 2026
  • Terraform Language — Providers (required_providers, provider konfiguratsiyasi, alias), 2026
  • Terraform Language — Resources va meta-argumentlar: count, for_each, depends_on, lifecycle (create_before_destroy, prevent_destroy, ignore_changes), provider, 2026
  • Terraform Language — Data Sources; Variables (type, default, validation, sensitive), Outputs, Local Values, 2026
  • Terraform Language — Modules (root/child, source, input/output); Dynamic Blocks; Provisioners (last resort), 2026
  • Terraform Language — Import (import bloki va terraform import CLI), 2026
  • Terraform State — Purpose, Remote State, State Locking; Backend Type: s3 (use_lockfile, DynamoDB locking deprecated), 2026
  • Terraform CLI — init, plan, apply, destroy, fmt, validate, workspace, state, force-unlock buyruqlari, 2026
  • Terraform Registry — provider va modullar (hashicorp/aws, terraform-aws-modules/vpc), 2026
  • HashiCorp/GitHub — setup-terraform action (CI/CD integratsiyasi), 2026

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
10.10-bob: Infrastructure as Code — Terraform asoslari — Wisar