محیط تست مدرن الزاماً Cloud، Kubernetes یا «یک محیط برای هر Pull Request» نیست. محیط مدرن، بستری متناسب با تصمیم است که Artifact، پیکربندی، داده، Dependency، هویت و محدودیتهایش نسخهپذیرند؛ Readiness آن با Evidence ثابت میشود؛ انزوا و Fidelity آن برای Failure mechanism کافی است؛ هزینه و عمرش دیده میشود؛ و تیم میتواند آن را بازسازی، پاکسازی و در صورت لزوم از Provider خارج کند. گاهی پاسخ درست Docker Compose محلی است، گاهی VM، گاهی Cluster، گاهی سرویس Managed و گاهی Device یا Sandbox واقعی.
این راهنما مالک تصمیم معماری و مهاجرت زیرساخت محیط تست است: Outcome/Risk → Failure mechanism → Fidelity/Isolation → Substrate/Topology → Lifecycle/Evidence → TCO/Exit. برای مدل عملیاتی کل سبد محیطها به مدیریت محیط تست، برای چرخه اختصاصی Review App به Preview Environment برای هر PR، و برای پیادهسازی Docker Compose به آموزش Docker در محیط تست بروید. این تفکیک جلوی سه مقاله رقیب با توصیههای یکسان را میگیرد.
پاسخ کوتاه: معماری محیط تست مدرن چیست؟
معماری محیط تست مدرن، انتخاب آگاهانه یک Portfolio از بسترهاست؛ نه استانداردکردن همه تستها روی گرانترین فناوری. برای هر Evidence question، کمهزینهترین محیطی انتخاب میشود که سازوکار شکست را حفظ کند. Unit و Contract test شاید Process-local باشند؛ Integration به Container نیاز داشته باشد؛ رفتار Scheduler یا NetworkPolicy فقط روی Kubernetes معتبر باشد؛ و دوربین، GPU، Secure Element یا Firmware به سختافزار واقعی نیاز داشته باشد.
اصل تصمیم: نام فناوری Requirement نیست. «Kubernetes میخواهیم» را به «باید رفتار Probe، Service discovery، Network policy، Scheduler یا Upgrade مربوط به Kubernetes را با این Fidelity مشاهده کنیم» تبدیل کنید. اگر Failure mechanism در Compose حفظ میشود، Cluster شاید فقط زمان و هزینه اضافه کند.
سه صفحه نزدیک، سه مالکیت متفاوت
| پرسش | صفحه مالک | خروجی |
|---|---|---|
| کل سبد Shared/Ephemeral/Staging را چگونه اداره کنیم؟ | مدیریت محیط تست ۸۹۲ | Operating model، manifest، booking، drift و incident |
| برای هر PR چگونه Review App امن بسازیم و پاک کنیم؟ | Preview Environment 1557 | PR/SHA lifecycle، reconcile، TTL، cleanup و Fork security |
| بین Local/VM/Container/Kubernetes/Cloud/Real انتخاب و مهاجرت کنیم؟ | همین صفحه ۱۷۶۱ | Architecture decision، Fidelity، hard gates، TCO، PoC و Exit |
| Compose را چطور عملاً بسازیم و Debug کنیم؟ | Docker ۹۷۲ و Lab ۱۱۰۸ | فایل اجرایی، healthcheck، runner، logs و reset |
Cloud، Container، Kubernetes و IaC مترادف نیستند
| مفهوم | چه مسئلهای را حل میکند؟ | چه چیزی را تضمین نمیکند؟ |
|---|---|---|
| Cloud | دسترسی On-demand به Pool منابع و سرویسها | ارزانبودن، دسترسی از ایران، Portability یا Production parity |
| VM | مجازیسازی ماشین/سیستمعامل و boundary قویتر از Process | Provision سریع یا Image تازه |
| Container | بستهبندی و اجرای Process با محیط کاربری نسخهپذیر | Kernel parity، انزوای کامل، داده پاک یا رفتار Orchestrator |
| Kubernetes | API و کنترلگرهای orchestration برای workload کانتینری | نیاز واقعی تیم، امنیت پیشفرض یا عملیات کمهزینه |
| IaC | تعریف و تغییر منابع با Configuration و Workflow قابلمرور | عدم Drift، عدم Destruction، صحت Provider یا Secret safety |
| Environment as Code | ترکیب IaC، app config، data/dependency contract و health evidence | همسانی مطلق با Production |
| TEaaS | Self-service interface برای درخواست/تحویل/انقضای محیط | یک استاندارد واحد یا کیفیت خودکار محیط |
Cloud را با ویژگیهایش بسنجید، نه با لوگوی Provider
NIST SP 800-145 Cloud را با پنج ویژگی On-demand self-service، Broad network access، Resource pooling، Rapid elasticity و Measured service و نیز مدلهای خدمت/استقرار تعریف میکند. این سند تعریف است، نه دستور خرید یا تضمین کیفیت. برای Test Architecture بپرسید: Self-service واقعاً بدون Ticket است؟ مصرف به Environment/Run قابلانتساب است؟ Quota و ظرفیت هنگام Peak موجود است؟ Export و حذف کامل ممکن است؟ Region، هویت، Billing و API از شبکه تیم در ایران قابلاتکا هستند؟
از Outcome شروع کنید، نه از Migration پروژه محبوب
Environment Architecture Brief decision horizon: محصول/Release/تیم و بازه زمانی outcomes: چه تصمیمهایی باید سریعتر یا معتبرتر شوند؟ baseline: زمان انتظار، setup، invalid-run، contention، cost، incidents evidence questions: چه Claimهایی باید آزموده شوند؟ failure mechanisms: کدام OS/Network/Orchestrator/Device رفتار مهم است؟ hard gates: Security, Fidelity, Iran access, export, cleanup, budget candidate portfolio: Local | Container | VM | K8s | Managed | Real change boundary: چه چیز فعلاً مهاجرت نمیکند؟ success/countermetrics: بهبود همراه با عوارض جانبی owners: Product, QA, Platform, Data, Security, Finance exit/rollback: چه زمانی Stop یا بازگشت انجام میشود؟
چه زمانی اصلاً مهاجرت نکنیم؟
- Baseline ندارید و مسئله فقط با واژههایی مثل «کند» یا «قدیمی» توصیف شده است.
- بیشتر Failureها از Test data، Oracle یا Testability میآیند و Substrate آنها را حل نمیکند.
- تعداد Run و Change آنقدر کم است که Platform overhead از زمان ذخیرهشده بیشتر میشود.
- تیم مالک Operations، Security patch، Backup، Cost و Incident برای Stack جدید ندارد.
- Application هنوز Stateful/License-bound/Hardware-coupled است و فرض Containerization اثبات نشده.
- Provider/Registry/Package/Payment از ایران Continuity قابلآزمون ندارد و Offline plan موجود نیست.
- Exit/Export ممکن نیست یا Contract اجازه بازگردانی Artifact، Data و Evidence را نمیدهد.
- میتوان با حذف Queue دستی، ساخت Golden VM یا اصلاح Seed/Reset به Outcome رسید.
ماتریس انتخاب بستر محیط تست
| بستر | مناسب برای | Fidelity مهم | ریسک/هزینه پنهان |
|---|---|---|---|
| Process/Library محلی | Unit، property، component سریع | منطق و API داخل Process | از دستدادن runtime/network behavior |
| Container/Compose محلی | Integration چندسرویس و بازتولید Failure | Image، config، network، dependency نسخهشده | Kernel/architecture/host و shared daemon |
| VM | OS/Kernel/agent/legacy و boundary ماشین | OS image، driver، service manager | boot/image drift/patch/storage |
| Kubernetes محلی/آزمایشگاهی | K8s API، probe، policy، rollout و operator | نسخه API، CNI/CSI، admission و topology | Cluster operations و false parity |
| Managed Cloud service | Behavior اختصاصی service/region/IAM/scale | همان Offering/Edition/Region/API | Lock-in، quota، egress، access و billing |
| Shared Integration | Contract بین چند تیم و dependency واقعیتر | نسخه و availability مشترک | contention، data collision و blame ambiguity |
| Staging محدود | Release rehearsal و چند Claim high-risk | release topology/config/identity | صف، گرانی و توهم «کپی Production» |
| Real device/hardware | sensor، battery، GPU، driver، secure element | مدل/firmware/network/physical state | ظرفیت، reset، wear و evidence capture |
Fidelity را چندبعدی و Claimمحور تعریف کنید
«Production-like» سنجه نیست. برای هر Evidence question مشخص کنید کدام ابعاد باید مشابه، نماینده، شبیهسازی یا عمداً متفاوت باشند. هیچ محیط غیرProduction در همه ابعاد برابر نیست و حتی Production با زمان تغییر میکند.
| بعد Fidelity | Identity/Evidence | نمونه Failure در شکاف |
|---|---|---|
| Artifact/runtime | digest، architecture، runtime/OS | dependency یا CPU instruction متفاوت |
| Config/feature/policy | config hash، flag snapshot، rule version | مسیر غیرفعال یا threshold متفاوت |
| Topology/scale | replica، zone، LB، queue partition | race/failover/hot partition پنهان |
| Network | DNS، TLS، proxy، latency/loss policy | timeout/certificate/retry behavior متفاوت |
| Data | schema، distribution، volume، lineage | edge/collision/cardinality حذف میشود |
| Dependency | real/sandbox/virtual contract و version | callback/order/rate-limit اشتباه |
| Identity/permission | role، scope، token lifetime | تست با admin، Production با least privilege |
| Time/locale | clock، timezone، calendar، locale | DST/Tehran/Jalali/Unicode failure |
| Observability | schema، sampling، correlation، retention | Failure رخ میدهد ولی قابلتشخیص نیست |
| Failure controls | fault type، injection point، recovery | فقط happy path معتبر است |
Fidelity Ladder برای Dependencyها
Stub سریع برای Contract اولیه مناسب است، اما Failure semantics سرویس واقعی را نگه نمیدارد. سطح را با ریسک بالا ببرید: in-process fake → protocol stub → stateful simulator → provider sandbox → shared non-production instance → محدود و کنترلشده Production observation. Virtualization را با Contract، state، latency، rate limit، duplicate/late/out-of-order events و error families Qualification کنید؛ صرف پاسخ HTTP ۲۰۰ کافی نیست.
کانتینر چه چیزی را ثابت میکند و چه چیزی را نه؟
Container، Application و بخشی از User space را بستهبندی میکند؛ Kernel میزبان، سختافزار، CNI، storage driver، secret source و External service را داخل Image نمیگذارد. NIST SP 800-190 نیز در کنار قابلیت حمل و اتوماسیون، ریسکهای Image، Registry، Orchestrator، Container و Host OS را تشریح میکند. پس عبارت «هرجا دقیقاً یکسان اجرا میشود» را به Claimهای قابلآزمون بشکنید.
- Image را با digest immutable مصرف کنید؛ Tag قابلاستفاده مجدد است. مستند Docker همین تفاوت Tag و Digest را روشن میکند.
- Base image، package lock، build args، CPU architecture و provenance را ثبت کنید.
- Rootless/user، capability، mount، socket، network و secret boundary را منفی تست کنید.
- Writable state را از Image جدا و Reset/Delete آن را مستقل اثبات کنید.
- Host kernel و architecture matrix را در Environment identity بیاورید.
- Image یکسان با Config یا Dependency متفاوت، Environment یکسان نیست.
Build once، Deploy many؛ اما با Identity کامل
برای کاهش Build drift، Artifact را یک بار بسازید و همان digest را میان Laneها Promote کنید؛ ولی Config، Secret reference، migration، data contract و deployment policy همچنان محیطویژهاند. Attestation میتواند Provenance Build را تقویت کند؛ برای نمونه GitHub Artifact Attestations ادعای امضاشده درباره منشأ Build میسازد، اما Vulnerability-free بودن یا Suitability محیط را ثابت نمیکند.
Environment identity tuple source_commit + build_run + artifact_digest + provenance_status + deploy_manifest_digest + infra_module/provider/lock versions + runtime/OS/architecture + config/feature/policy hashes + schema/migration + dataset + dependency/sandbox versions + identity/secret refs (never secret values) + environment/run/tenant IDs + created/expires timestamps
Kubernetes فقط وقتی انتخاب است که رفتار آن در سؤال باشد
اگر Claim درباره readiness/liveness/startup probe، rollout، scheduler، service discovery، admission، NetworkPolicy، operator، autoscaling یا CNI/CSI است، Kubernetes fidelity لازم میشود. اگر هدف صرفاً تست API دو سرویس و DB است، Compose ممکن است Feedback سریعتر و Debug سادهتری بدهد. Cluster محلی نیز با Managed Offering در CNI، storage، IAM، LB، version skew و topology برابر نیست؛ تفاوتها را Manifest کنید.
Namespace مرز امنیت کامل نیست
راهنمای رسمی Multi-tenancy کوبرنتیز Namespace یا control plane مجازی را دو الگوی اشتراک معرفی میکند. Namespace بسیاری از Objectها را Scope میکند، اما Node، StorageClass، PersistentVolume و برخی منابع Cluster-wide بیرون آناند؛ Network isolation نیز به Policy و CNI وابسته است. برای کد غیرقابلاعتماد یا Tenant پرریسک، Cluster/Node/VM boundary جدا ممکن است لازم باشد.
| لایه انزوا | کنترل | آزمون منفی |
|---|---|---|
| Identity/RBAC | service account کوتاهعمر و least privilege | خواندن Secret/Namespace دیگر رد شود |
| Network | default deny + allowlist + egress control | metadata/internal/tenant cross-call رد شود |
| Compute | request/limit/quota/node policy | resource exhaustion و noisy neighbor |
| Pod/Process | non-root، capabilities، seccomp، readonly | privilege/socket/host mount رد شود |
| Data/Storage | DB/schema/tenant/volume/key isolation | cross-run read و residual data صفر |
| Messaging/Cache | topic/consumer/cache prefix و ACL | event مصرف یا key collision محیط دیگر |
| External effect | sink/fake domain/rate/allowlist | SMS، ایمیل، PSP یا webhook واقعی ارسال نشود |
IaC تکرارپذیری مطلق و خطای انسانی صفر نمیدهد
IaC یک Workflow کنترل تغییر میسازد، نه جادو. گردشکار رسمی Terraform پیکربندی Desired را با State و Objectهای واقعی مقایسه میکند، Plan میسازد و Apply تغییر میدهد. Provider/API، داده بیرونی، Version، nondeterminism و تغییر دستی میتوانند نتیجه را عوض کنند. Plan نیز تنها Preview ابزار است؛ درستبودن intent، امنیت و اثر حذف را تیم باید بررسی کند.
IaC evidence chain declared configuration @ commit → locked module/provider versions → validated/linted/scanned code → refreshed actual + prior state → reviewed saved plan + policy decision → authorized apply + output → health/smoke/fidelity verification → observed actual inventory + drift scan → destroy plan + cleanup + verify absent
State، Drift و خطر بازآفرینی ناخواسته
State میتواند شناسه و داده حساس داشته باشد؛ دسترسی، encryption، locking، backup و audit میخواهد. تغییر Out-of-band موجب Drift میشود و Reconcile کور ممکن است Resource را حذف یا بازسازد. در راهنمای رسمی مدیریت Resource drift نیز بر دیدن تفاوت State/Actual و بررسی مسیر اصلاح تأکید شده است. Import، ignore یا پذیرش Drift باید Decision ثبتشده باشد، نه راهی برای سبزکردن Plan.
Environment Contract قابلکپی
Test Environment Contract purpose / evidence questions / prohibited claims owner / users / trust level / concurrency model substrate & topology / offering-edition-region-version identity tuple / artifact digest / provenance fidelity dimensions / declared gaps / escalation environment isolation: identity, network, compute, data, queue, storage, effects data: classification, source, seed, lease, reset, retention, delete dependencies: real/sandbox/virtual, version, limits, failure semantics readiness: provision, runtime, migration, dependency, app, telemetry capacity/quota / performance validity / contention policy secrets/keys/certificates / access / audit / emergency path lifecycle: create, update, rollback, TTL, destroy, verify absent observability/evidence / correlation / redaction / retention cost allocation / budget / alert / idle policy Iran continuity / mirror / offline operation / currency / support exit/export/restore rehearsal / owners / approval / expiry
Provisioned با Ready و Valid فرق دارد
| Gate | Evidence | Failure نمونه |
|---|---|---|
| Provision | منابع Desired ایجاد و identity ثبت شد | partial apply یا wrong region |
| Runtime | Process/Pod پایدار، نه صرف Running | crash loop پس از health اولیه |
| Migration | schema/version/rollback compatibility | app آماده، DB کهنه |
| Data | dataset/seed/lease/reset identity | باقیمانده Run قبلی |
| Dependency | contract/version/auth/failure probe | sandbox بدون callback موردنیاز |
| Application smoke | Journey کمینه + side-effect Oracle | HTTP ۲۰۰ با queue/ledger خراب |
| Telemetry | logs/metrics/traces با correlation | Run بدون شواهد Debug |
| Fidelity | ابعاد لازم پاس، Gapها آشکار | تست Scheduler روی Compose |
| Completeness | تمام Evidenceها حاضر و تازه | missing signal بهاشتباه Pass |
Result semantics برای محیط
READY یعنی Contract لازم برای آن Test run پاس شده؛ نه اینکه محیط برای همه تستها سالم است. DEGRADED فقط با Gap و تستهای مجاز مشخص قابلاستفاده است. INCONCLUSIVE یعنی Evidence کافی نیست؛ INVALID یعنی Identity/Fidelity/Isolation نقض شده و نتایج Test نباید به Product نسبت داده شوند. BLOCKED نیز مانع بیرونی شناختهشده دارد. این معناها را Machine-readable کنید.
داده تست: Snapshot گرفتن، TDM نیست
محیط سریع با داده حساس، کهنه یا غیرقابلReset معتبر نیست. Classification، Minimization، Masking، synthetic generation، Referential integrity، multi-store consistency، lease، reset، retention و deletion Evidence لازماند. مالک چرخه کامل در راهنمای مدیریت داده تست است؛ معماری محیط باید فقط Interface و Hard gate آن را مصرف کند.
| الگو | مزیت | ریسک | پذیرش |
|---|---|---|---|
| DB/Store اختصاصی هر Run | Isolation و cleanup روشن | زمان/هزینه و quota | unique identity + verify absent |
| Schema اختصاصی | سبکتر | extension/global object/cross-schema leak | negative access + migration qualification |
| Tenant منطقی | مقیاس بالا | bug در tenant filter و collision | cross-tenant probes + reset proof |
| Shared mutable dataset | راهاندازی ساده | race، flaky و ownership مبهم | lease/partition/serialization؛ آخرین گزینه |
| Production-derived | distribution نزدیکتر بالقوه | privacy، staleness، re-identification | approved pipeline + leakage/utility evidence |
| Synthetic/versioned | کنترل و بازتولید | فقدان realism و edge | claim-specific coverage + invariants |
Secret و Identity چرخه محیط را دنبال کنند
- Secret واقعی Production را در Test کپی نکنید؛ Credential جدا، کوتاهعمر و Scopeشده بسازید.
- Secret value نباید در IaC state، Plan، log، screenshot یا Artifact ذخیره شود.
- Environment create باید Identity بسازد یا Bind کند؛ destroy باید revoke را اثبات کند.
- Certificate، callback URL، allowlist و DNS باید expiry/cleanup مشترک داشته باشند.
- Break-glass دسترسی زماندار، ثبتشده و بازبینیشونده باشد.
- تست منفی بخواند/بنویسد/Impersonate کند و Deny را با audit تأیید کند.
Observability بخشی از Environment identity است
Run بدون Correlation، شواهد قابلانتساب ندارد. Environment ID، Test run، Commit، Artifact digest، service name/version و dataset را به Log/Metric/Trace اضافه کنید. Semantic Conventions سرویس OpenTelemetry برای service.name/namespace/instance/version واژگان مشترک میدهد؛ این Attributeها را با Cardinality و PII controls Tailor کنید، نه اینکه PR ID نامحدود را به هر Metric label اضافه کنید.
محیط Performance باید Contention و Capacity را آشکار کند
نتیجه Performance روی Node اشتراکی، burstable CPU، autoscaling نامعلوم یا noisy neighbor ممکن است برای سؤال Release نامعتبر باشد. Hardware/instance، topology، quota/limit، autoscaler، background load، network path، data volume، cache state، warmup، clock و observability را ثبت کنید. Container بهتنهایی Performance parity نمیدهد و Cloud elasticity نیز پاسخگویی را تضمین نمیکند.
Environment Ephemeral را با Preview Environment اشتباه نگیرید
Ephemeral فقط Lifetime کوتاه را توصیف میکند؛ Preview هدف بازبینی Change/PR دارد. یک Load environment دوساعته Ephemeral است ولی Review App نیست؛ یک Preview ممکن است چند روز Lease داشته باشد. طراحی دقیق desired SHA، Fork trust، URL، TTL، orphan detection و verify-absent در صفحه Preview Environment آمده و اینجا تکرار نمیشود.
Lifecycle استاندارد معماری محیط
Request/Authorize → Resolve immutable identities → Plan/Policy/Cost preview → Provision/Bind identity → Migrate/Seed/Connect dependencies → Health/Smoke/Fidelity gate → Test/Observe/Evidence → Update/Reconcile or Freeze → Expire/Destroy/Revoke → Verify absent/Close cost/Retain redacted evidence
Cleanup موفق یعنی Verify absent
خروجی موفق Pipeline حذف کافی نیست. Inventory واقعی را برای Compute، Route/DNS/LB، volume/snapshot، DB/schema، queue/topic، cache، object storage، secret/key/cert، identity/token، sandbox subscription، log sink و cost tag Query کنید. Outcome باید DESTROYED، PARTIAL، BLOCKED یا UNKNOWN باشد. Orphan detector مستقل، ابتدا Dry-run/Quarantine و سپس حذف با Guardrail انجام دهد.
TCO: قیمت هر ساعت VM فقط یکی از جملههاست
TCO horizon = compute + storage/snapshot/backup + network/egress/LB/DNS + managed-service/request/license/support + build/registry/scanner/observability retention + platform engineering + security + operations + incident/on-call + migration/training/dual-run + compliance/privacy controls + idle/orphan/failed-run/rework + currency/payment/access risk + exit/export/rebuild/restore rehearsal − only measured avoided cost (never assumed savings)
Cost per created environment بهراحتی Game میشود. Cost per valid consumed test-hour، wait-to-ready، first-attempt readiness، invalid-run rate، cost-after-expiry، orphan age، evidence completeness و defect escape مرتبط با Fidelity را کنار هم ببینید. کاهش هزینه با افزایش انتظار یا کاهش Fidelity موفقیت نیست.
Hard Gate پیش از Scorecard
امتیاز Feature، تجربه توسعهدهنده یا حتی میانگین وزنی نباید فقدان نیاز غیرقابلمذاکره را بپوشاند. ابتدا Hard gateها را Pass/Fail/Unknown کنید؛ فقط گزینههای واجد شرایط را با Score مقایسه کنید.
| Hard Gate | Evidence پذیرش |
|---|---|
| Failure-mechanism fidelity | PoC همان رفتار OS/Network/K8s/Device لازم |
| Isolation/security | negative cross-tenant/network/secret/effect tests |
| Data/privacy | approved dataset + reset/delete/leakage evidence |
| Artifact/provenance | digest + source/build/deploy trace |
| Iran continuity | actual access/payment/quota/mirror/offline drill |
| Lifecycle/cleanup | fault-injected destroy + verify absent |
| Export/exit | complete export + restore on alternate substrate |
| Operations | named owner + incident/upgrade/backup/rollback drill |
| Budget | three-year TCO + currency/egress/idle bounds |
آزمایش بازتولیدپذیر: Feature بیشتر، انتخاب معتبرتر نیست
یک Fixture تصمیم کاملاً خیالی و بدون Dependency با Node.js ۲۴.۱۸.۰ اجرا کردیم. Workload ساختگی، تست Reconciliation پرداختی بود که رفتار اختصاصی Kubernetes، Isolation هر Run، Mirror آفلاین Artifact، Export کامل، Continuity دسترسی ایران و Cleanup تأییدشده را Hard gate داشت. سه گزینه نویسندهساختهاند و هیچ Vendor یا محصول واقعی را نمایندگی نمیکنند.
LOCAL_COMPOSE features=18 | weighted=4.4 | fictional cost/hour=0.18 failed: kubernetesApiFidelity → INELIGIBLE FUTURE_MANAGED_CLOUD features=37 | weighted=4.7 | fictional cost/hour=1.35 failed: offlineArtifactMirror, completeExport, iranAccessContinuity → INELIGIBLE PORTABLE_K8S_LAB features=24 | weighted=4.2 | fictional cost/hour=0.72 failed: none → ELIGIBLE naive feature winner = FUTURE_MANAGED_CLOUD (ineligible) naive weighted winner = FUTURE_MANAGED_CLOUD (ineligible) conditional selection = PORTABLE_K8S_LAB
گزینه Managed هم Feature بیشتر و هم Score بالاتر داشت، اما سه Gate حیاتی را رد کرد؛ Compose نیز برای این Claim مشخص، Kubernetes API fidelity نداشت. فقط Lab قابلحمل واجد شرایط شد و انتخابش همچنان به PoC واقعی، Threat model، عملیات و Exit rehearsal مشروط است. نامها، Score، Gate و هزینه ساختگیاند؛ هیچ Workload، Provider، اندازهگیری، قیمت بازار، نتیجه تحریم، Performance/Security یا Production evidence ندارند و برای رتبهبندی Cloud/Kubernetes/Docker، Forecast صرفهجویی یا تصمیم خرید مناسب نیستند.
PoC برابر و تصمیمآماده طراحی کنید
هر گزینه همان Journey، حجم، Failure injection، Artifact و Evidence question را اجرا کند. Demo فروشنده، Trial با Scope متفاوت یا Environment ازپیشگرمشده مقایسه نیست. Raw logs، timestamps، cost، manual steps و failureها را نگه دارید.
| تمرین PoC | Evidence | Failure موردنظر |
|---|---|---|
| Create از صفر | elapsed، manual touch، identity، plan/apply | hidden prerequisite و flaky provision |
| Same artifact deploy | digest/provenance/config trace | rebuild یا tag drift |
| Seed/Reset | dataset identity و state probes | residual/collision |
| Dependency failures | timeout/duplicate/late/rate-limit | fake غیرواقعی |
| Isolation attack | negative RBAC/network/data/effect | cross-environment leak |
| Node/provider outage | recovery evidence و RTO/RPO مشاهدهشده | hidden single point |
| Version change | upgrade/rollback و compatibility | lock-in یا migration break |
| Destroy failure | retry + inventory verify absent | orphan/credential leak |
| Iran unavailable drill | mirror/offline/alternate path | ۴۰۳، quota، registry یا support loss |
| Exit/restore | export کامل و rebuild جایگزین | missing state/data/evidence |
مهاجرت مرحلهای، نه Big Bang زیرساخت
- Baseline و Failure taxonomy را ۲ تا ۴ هفته ثبت کنید.
- یک Journey پرارزش و کموابستگی انتخاب کنید.
- Environment Contract و identity tuple را پیش از Tool بنویسید.
- Candidateهای کمینه را با Hard gate غربال کنید.
- PoC برابر را در کنار محیط فعلی اجرا کنید؛ Dual run را زماندار نگه دارید.
- Invalid-runها را Product defect حساب نکنید و منبع شکست را طبقهبندی کنید.
- Security، Data، Cost، Failure و Exit drill را پیش از Adoption انجام دهید.
- فقط اگر Outcome و Countermetric هر دو بهتر شدند Scope را گسترش دهید.
- Shared componentها را با Compatibility/rollback مهاجرت دهید.
- محیط قبلی را پس از Restore evidence و خروج امن Retire کنید.
طبقهبندی Failure از Blame جلوگیری میکند
| کلاس | نشانه | مالک اولیه |
|---|---|---|
| Product | محیط Valid و Oracle محصول Fail | Product/Engineering |
| Test | script/oracle/fixture defect | Test owner |
| Data | seed/schema/lease/reset invalid | Data owner |
| Environment | identity/readiness/capacity/drift/cleanup | Platform/Environment |
| Dependency | sandbox/provider/contract/version | Dependency owner |
| Security/Policy | auth/admission/network/secret denial | Security/Platform |
| Unknown | Evidence ناکافی یا چند علت | Triage مشترک؛ نه Quarantine دائمی |
سناریوی ایرانی: محیط تست Reconciliation پرداخت خیالی
یک بازارگاه خیالی ایرانی باید Journey سفارش→PaymentAttempt→PSP→Ledger→Outbox→Reconciliation را روی چند بستر بررسی کند. پول Canonical ریال است و UI مبلغ تومان را با واحد صریح نشان میدهد؛ ارقام فارسی/عربی/لاتین، Unicode/RTL، UTC و Asia/Tehran و نمایش جلالی پوشش دارند. دادهها مصنوعیاند و PAN، CVV2، OTP یا Token واقعی ندارند. سناریو توصیه بانکی/حقوقی یا ادعای سازگاری با PSP خاص نیست.
Iranian fictional environment contract claim: duplicate/late/out-of-order callback and timeout-after-commit artifact: one immutable digest across candidates dependencies: stateful PSP simulator; no real charge/SMS/email/webhook data: synthetic order/payment/ledger/outbox/reconciliation dataset identity: tenant/order/payment-attempt/idempotency/run/environment oracle: one financial effect + reconciled final state + evidence correlation K8s-specific claim: rollout/probe/network-policy behavior only in K8s lane locale: IRR + explicitly labelled toman; digits/RTL; UTC/Tehran/Jalali continuity: approved mirrors, package/image cache, offline runbook exit: source/IaC/images/data-schema/evidence export + alternate restore prohibitions: production secrets/data/effects and unsupported legal claims
محدودیتهای ایران را Gate واقعی کنید
- Login/API/Registry/Package/Plugin/Telemetry و Support را از شبکهها و Identityهای مجاز واقعی آزمایش کنید.
- تحریم، Geo-block، VPN dependency، تغییر IP و قطع DNS/CDN را فقط Risk ننویسید؛ unavailable drill اجرا کنید.
- Billing، پرداخت، ارز، افزایش نرخ، refund و توقف Account را در TCO/Continuity لحاظ کنید.
- Artifact/package/module/provider mirror تأییدشده و فرایند update/signature/vulnerability داشته باشد.
- Region/data residency/subprocessor/backup/export را بر اساس Contract واقعی ثبت کنید؛ «Cloud» محل داده را پاسخ نمیدهد.
- نسخه، License، quota، EOL و feature availability را برای Offering دقیق ثبت کنید.
- مسیر جایگزین نباید به Production Secret یا دانلود ناامن و بدون Provenance متکی باشد.
- راهنمای اختصاصی گزینههای جایگزین در شرایط ۴۰۳ در ابزارهای تست برای محدودیت دسترسی ایران تکمیلکننده این Gate است.
Exit Plan بخشی از معماری روز اول است
Portability ادعا نیست؛ Restore موفق روی مقصد جایگزین Evidence است. Source، IaC، module/provider locks، imageها و SBOM/provenance، schema/migration، dataset generator، secrets mapping بدون Value، policy، dashboard/alert، logs/evidence schema و Runbook را Export کنید. Feature اختصاصی Managed service را به Replace/Retain/Emulate/Retire نگاشت و هزینه/ریسک هرکدام را ثبت کنید. Trade-off License و Vendor در راهنمای متنباز یا تجاری تفصیل دارد.
Metrics و Countermetrics غیرقابلبازی
| Metric | Denominator/Clock | Countermetric |
|---|---|---|
| Request-to-ready | همه درخواستها، P50/P95، first attempt | Invalid-run و Fidelity gap |
| First-attempt readiness | بدون Retry/Manual repair | Provision time |
| Valid consumed hours | ساعت واقعاً استفادهشده و Contract-valid | idle/orphan hours |
| Cost per valid run | کل هزینه تخصیصپذیر / Run معتبر | wait، coverage و escape |
| Environment-caused failure | همه first attempts با taxonomy | Unknown و misclassification |
| Cleanup completeness | همه expiry/close/destroy requests | cost-after-close و orphan age |
| Evidence completeness | Runهای مصرفشده در تصمیم | storage/privacy/retention cost |
| Change failure rate | تغییرات Platform/Environment | change frequency و recovery time |
| Iran continuity | drillها و رخدادهای access | freshness و mirror security |
Evidence Pack تصمیم معماری
Architecture Evidence Pack brief/baseline/decision horizon risk→failure mechanism→fidelity mapping candidate offering/version/region/topology inventory contracts, hard gates and raw PoC results artifact/provenance/infra/data/dependency identities security/privacy/threat-model and negative tests readiness/failure/cleanup/verify-absent evidence TCO assumptions, invoices/measurements and uncertainty Iran unavailable drill and offline/mirror evidence exit/export/alternate-restore rehearsal exceptions with owner/expiry; decision and dissent monitor triggers, rollback conditions and review date
Release Evidence و Promotion
محیط Test «Release نمیشود»؛ Evidence آن برای تصمیم محصول مصرف میشود. هر Report باید Environment identity، Validity، Fidelity gaps، Test result، first attempt، Retry و exceptions را حمل کند. نتیجه محیط Invalid یا Inconclusive را Pass محصول نکنید. Continuous Testing laneها و بودجه بازخورد در راهنمای تست مداوم مالکیت جدا دارند.
مالکیت و Decision Rights
| نقش | مسئولیت | حق تصمیم |
|---|---|---|
| Product/Test strategy | Evidence question و Fidelity need | رد محیط نامعتبر برای Claim |
| Platform/Environment | Provision، lifecycle، SLO، incident، upgrade | Stop/rollback Platform change |
| Service team | Artifact/config/testability/runbook | پذیرش Compatibility change |
| Data owner | dataset، privacy، reset/delete | رد داده غیرمجاز/نامعتبر |
| Security | threat model، identity، network، secrets | Hard stop در leakage/critical risk |
| Finance/Procurement | TCO، contract، currency، invoice | budget/contract boundary |
| QA | independent PoC، Oracle، validity و evidence | Hold برای Hard-gate failure |
| Incident commander | containment، recovery، communication | quarantine/disable shared substrate |
Runbook رخداد محیط تست
- مصرف نتایج جدید را متوقف و Scope محیط/Runهای مشکوک را علامتگذاری کنید.
- Environment identity، Plan/Apply، events و telemetry را Freeze/Preserve کنید.
- در خطر Data/Secret/Cross-tenant فوراً Contain و Credential را Revoke کنید.
- Product/Test/Data/Environment/Dependency/Unknown را بدون Blame اولیه طبقهبندی کنید.
- آخرین Environment سالم و تغییرهای Artifact/Config/Infra/Data/Dependency را Diff کنید.
- Rollback یا Rebuild از Artifact/Configuration شناختهشده را اجرا کنید.
- Health/Fidelity/Isolation/cleanup را دوباره اثبات کنید؛ Pod سبز کافی نیست.
- Runهای متاثر را Invalid کنید و Decision consumerها را خبر دهید.
- Root/contributing causes و gap شواهد را ثبت و Control را اصلاح کنید.
- پس از Retest مستقل، محیط را باز و SLO/error budget را بهروز کنید.
برنامه ۳۰روزه تصمیم و PoC محیط تست مدرن
| بازه | کار | خروجی |
|---|---|---|
| روز ۱–۵ | Baseline، decision horizon، Journey و failure mechanisms | Architecture Brief و taxonomy |
| روز ۶–۱۰ | Fidelity/Isolation/Data/Iran/Exit hard gates و Contract | Candidate shortlist و rejection reasons |
| روز ۱۱–۱۵ | PoC create→ready→test با Artifact/Dataset یکسان | Raw timing، validity و evidence |
| روز ۱۶–۲۰ | Fault، security، drift، upgrade و cleanup failure | Failure packets و recovery evidence |
| روز ۲۱–۲۵ | TCO، unavailable ایران، offline mirror و Exit/restore | Cost model و continuity/exit verdict |
| روز ۲۶–۳۰ | Score فقط Eligibleها، decision review و rollback | Adopt/Adapt/Stop + phased migration plan |
۲۰ ضدالگو در معماری محیط تست
- شروع از «باید Cloud/Kubernetes داشته باشیم» بدون Evidence question.
- مهاجرت برای مدرنبودن بدون Baseline.
- برابرگرفتن Container با VM یا امنیت کامل.
- ادعای اجرای دقیقاً یکسان صرفاً با Image.
- استفاده از Tag متغیر بهعنوان Artifact identity.
- فرض Namespace بهعنوان مرز کامل امنیت.
- یکیگرفتن Ephemeral و Preview.
- استفاده از «Production-like» بدون ابعاد Fidelity.
- تست behavior کوبرنتیز روی Compose و تعمیم نتیجه.
- فرض IaC بهعنوان تکرارپذیری ۱۰۰٪ و خطای انسانی صفر.
- Apply خودکار بدون Plan/Policy/Destruction review.
- پذیرش Running/HTTP ۲۰۰ بهعنوان Ready.
- کپی Production data/secrets برای Realism.
- استفاده از Admin identity در Test و least privilege در Production.
- نادیدهگرفتن noisy neighbor در Performance.
- محاسبه فقط VM-hour و حذف نیروی عملیات/egress/idle/exit.
- انتخاب Feature/Score بر خلاف Hard gate.
- اتکا به Vendor demo با Scope متفاوت.
- موفقدانستن Destroy job بدون Verify absent.
- نداشتن Iran continuity، owner، rollback و restore-tested Exit.
چکلیست ۲۰نقطهای انتخاب محیط تست
- Outcome، baseline و decision horizon روشن است.
- Evidence question و failure mechanism نوشته شدهاند.
- کوچکترین Substrate کافی بررسی شده است.
- ابعاد Fidelity و Gapهای مجاز ثبت شدهاند.
- Offering/edition/region/version دقیق است.
- Artifact با digest و provenance قابلردیابی است.
- Config/Infra/Data/Dependency identity کامل است.
- Identity/Network/Compute/Data/Effect isolation منفی تست شده است.
- State و Drift workflow امن دارید.
- Provision/Runtime/Migration/Data/Dependency/App/Telemetry gate جداست.
- Invalid/Inconclusive با Product fail/pass قاطی نمیشود.
- Data lease/reset/delete و Secret revoke اثبات شدهاند.
- Performance capacity/contention قابلتوضیح است.
- Observability به Run/Environment/Version پیوند دارد.
- Cleanup Fault-injected و Verify absent شده است.
- سهساله TCO و Countermetric دارید.
- Iran access/payment/mirror/offline drill پاس شده است.
- Export و Alternate restore واقعاً اجرا شدهاند.
- PoC برابر و Hard gate پیش از Score انجام شده است.
- Owner، decision rights، rollout و rollback ثبت شدهاند.
جمعبندی: محیط متناسب با Evidence، نه مد روز
محیط تست مدرن یک مقصد تکفناوری نیست. ابتدا تصمیم و سازوکار شکست را روشن کنید، سپس Fidelity و Isolation لازم را بنویسید و کمینه بستر کافی را انتخاب کنید. Artifact، Infra، Config، Data، Dependency و Identity را نسخه دهید؛ Ready/Valid را با شواهد چندلایه ثابت کنید؛ Hard gateهای امنیت، ایران، Cleanup و Exit را بیرون Score نگه دارید؛ و فقط پس از PoC برابر مهاجرت مرحلهای انجام دهید. Cloud میتواند Self-service و Elasticity بدهد، Container بستهبندی میدهد، Kubernetes رفتار Orchestration و IaC تغییر کنترلشده؛ هیچکدام بهتنهایی کیفیت، برابری Production یا صرفهجویی را تضمین نمیکنند.
پرسشهای متداول محیط تست مدرن
آیا هر تیم برای محیط تست مدرن به Kubernetes نیاز دارد؟
خیر. اگر Evidence question به API، Scheduler، NetworkPolicy، probe، rollout یا operator کوبرنتیز وابسته نیست، Container/Compose یا VM ممکن است ارزانتر و قابلعیبیابیتر باشد. Kubernetes زمانی موجه است که Failure mechanism یا Offering هدف به آن وابسته باشد و هزینه عملیاتش پذیرفته شود.
آیا Container مشکل «روی سیستم من کار میکند» را کاملاً حل میکند؟
خیر. Container بخش مهمی از User space و dependencyها را نسخهپذیر میکند، اما Kernel/architecture، Config، data، secret، network، storage و external service هنوز میتوانند متفاوت باشند. Digest و Environment identity کامل، ادعا را محدود و آزمونپذیر میکنند.
تفاوت محیط Ephemeral و Preview Environment چیست؟
Ephemeral درباره عمر کوتاه/حذفپذیری است؛ Preview درباره هدف بازبینی Change یا PR. یک Performance lab موقت Ephemeral است اما Preview نیست. Preview ممکن است تا پایان Lease چند روز بماند و چرخه PR/SHA، URL، Fork security، reconcile و cleanup اختصاصی دارد.
آیا IaC محیط کاملاً یکسان و بدون خطا میسازد؟
نه بهصورت مطلق. IaC پیکربندی و تغییر را قابلمرور و بازاجرا میکند، اما State، Provider/API، version، داده بیرونی، Drift، nondeterminism و Intent غلط باقیاند. Plan، Apply، health/fidelity verification، actual inventory و drift/cleanup evidence با هم لازماند.
Cloud همیشه هزینه محیط تست را کم میکند؟
خیر. Elasticity و اندازهگیری مصرف میتوانند کمک کنند، اما idle/orphan، storage، egress، managed requests، observability، نیروی Platform/On-call، migration، ارز، دسترسی ایران و Exit ممکن است TCO را بالا ببرند. هزینه را به valid consumed run/hour و Outcome پیوند دهید، نه فقط قیمت VM-hour.

