পাঠ ২১ · ৫৭-এর মধ্যে · মডিউল ৫
Home / Courses / Cloud Computing & DevOps / IaC বেস্ট প্র্যাকটিস ও টেস্টিং

IaC বেস্ট প্র্যাকটিস ও টেস্টিং

IaC best practices & testing
৭ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • IaC-এর জন্য মূল বেস্ট প্র্যাকটিস — কেন প্রতিটি গুরুত্বপূর্ণ
  • IaC টেস্টিং-এর তিনটি স্তর এবং প্রতিটি কী ধরনের সমস্যা ধরতে পারে
  • পলিসি-অ্যাজ-কোড ধারণা — automated গেট যা apply-এর আগে কনফিগারেশন যাচাই করে
  • Python দিয়ে L16-এর সিকিউরিটি-গ্রুপ চেকার পুনর্ব্যবহার করে একটি IaC পলিসি ভ্যালিডেটর তৈরি করা

১ · IaC বেস্ট প্র্যাকটিস — মডিউল ৫-এর সবকিছু একত্র করা

এই মডিউলের প্রতিটি পাঠ একটি নির্দিষ্ট নীতি শিখিয়েছে — এখন সেগুলোকে একটি সম্পূর্ণ বেস্ট-প্র্যাকটিস চেকলিস্টে একত্র করা যাক।

ভার্সন কন্ট্রোলে কনফিগ
IaC কনফিগ ফাইল ঠিক অ্যাপ্লিকেশন কোডের মতোই Git-এ রাখা উচিত (L17)।
ম্যানুয়াল এডিট নিষিদ্ধ
IaC-ম্যানেজড ইনফ্রাস্ট্রাকচার কখনো কনসোলে সরাসরি এডিট করা উচিত নয় — ড্রিফট তৈরি হয় (L20)।
মডিউল ব্যবহার
পুনরাবৃত্ত প্যাটার্নের জন্য মডিউল ব্যবহার করা, কপি-পেস্ট নয় (L19)।
এনভায়রনমেন্ট-প্রতি আলাদা state
dev/staging/prod-এর জন্য আলাদা state file — একটিতে ভুল হলে অন্যগুলো নিরাপদ থাকে।
PR-এর মাধ্যমে রিভিউ
IaC পরিবর্তনও পুল রিকোয়েস্টের মাধ্যমে রিভিউ করা উচিত, ঠিক অ্যাপ কোডের মতো (M8-এর সাথে সংযুক্ত)।

২ · IaC টেস্টিং — তিনটি স্তর

IaC কনফিগারেশন "টেস্ট" করার অর্থ ঐতিহ্যবাহী ইউনিট টেস্টের মতো নয় — বরং তিনটি ভিন্ন স্তরে যাচাই করা —

  • স্ট্যাটিক ভ্যালিডেশন — real ইনফ্রাস্ট্রাকচার স্পর্শ করার আগেই সিনট্যাক্স/স্কিমা যাচাই করা (যেমন একটি প্রয়োজনীয় ফিল্ড অনুপস্থিত কিনা, একটি টাইপ ভুল কিনা) — সবচেয়ে দ্রুত ও সস্তা চেক।
  • Plan রিভিউ — L18-এ শেখা plan আউটপুট সবসময় apply-এর আগে রিভিউ করা — মানুষ বা স্বয়ংক্রিয় সিস্টেম দিয়ে।
  • স্বয়ংক্রিয় পলিসি-চেক — একটি পাইপলাইনে স্বয়ংক্রিয়ভাবে চলা নিয়ম যাচাই (যেমন "কোনো সিকিউরিটি গ্রুপ যেন 0.0.0.0/0-কে ডেটাবেস পোর্টে অ্যাক্সেস না দেয়") — এই প্র্যাকটিসকে প্রায়ই policy as code বলা হয়।
Policy as code — L16-এর ধারণার সরাসরি পুনর্ব্যবহার

L16-এ আমরা একটি সিকিউরিটি-গ্রুপ রুল ইভালুয়েটর তৈরি করেছিলাম যা 0.0.0.0/0-কে ডেটাবেস পোর্টে অ্যাক্সেস দেওয়া একটি misconfiguration হিসেবে চিহ্নিত করেছিল। IaC পাইপলাইনে এই একই ধরনের চেক apply-এর আগে স্বয়ংক্রিয়ভাবে চালানো যায় — যাতে একটি বিপজ্জনক কনফিগারেশন কখনোই real ইনফ্রাস্ট্রাকচার পর্যন্ত পৌঁছাতে না পারে, একজন মানুষ ম্যানুয়ালি প্রতিটি plan না পড়েও।

৩ · Python-এ একটি পলিসি ভ্যালিডেটর তৈরি করা

নিচে validate_config(config, policies) ফাংশন একটি প্রস্তাবিত কনফিগারেশনের বিরুদ্ধে একটি তালিকার policy-check ফাংশন চালায় — প্রতিটি policy ফাংশন True (পাস) বা একটি সমস্যা-বার্তা (ফেইল) ফেরত দেয়। এখানে L16-এর দর্শন পুনর্ব্যবহার করে একটি "no open db port" পলিসি লেখা হয়েছে।

Python
# toy সিমুলেশন — কোনো real Terraform CLI বা cloud API কল হচ্ছে না
DB_PORT = 5432

def policy_no_open_db_port(config):
    """L16-এর দর্শন পুনর্ব্যবহার — কোনো সিকিউরিটি-গ্রুপ রুল যেন 0.0.0.0/0-কে DB পোর্টে অ্যাক্সেস না দেয়।"""
    for rule in config.get("security_group_rules", []):
        allow, port, source_cidr = rule["allow"], rule["port"], rule["source_cidr"]
        if allow and port == DB_PORT and source_cidr == "0.0.0.0/0":
            return f"লঙ্ঘন: পোর্ট {DB_PORT} (DB) সম্পূর্ণ ইন্টারনেটের (0.0.0.0/0) জন্য উন্মুক্ত"
    return True

def policy_requires_region(config):
    """স্ট্যাটিক ভ্যালিডেশন উদাহরণ — প্রতিটি resource-এ region ফিল্ড থাকা আবশ্যক।"""
    for name, spec in config.get("resources", {}).items():
        if "region" not in spec:
            return f"লঙ্ঘন: resource '{name}'-এ 'region' ফিল্ড অনুপস্থিত"
    return True

def validate_config(config, policies):
    """সব পলিসি চালিয়ে pass/fail রিপোর্ট তৈরি করে — apply চালানোর আগে।"""
    results = []
    for policy in policies:
        outcome = policy(config)
        results.append((policy.__name__, outcome))
    return results

def print_validation(label, results):
    print(f"--- {label} ---")
    all_passed = True
    for name, outcome in results:
        if outcome is True:
            print(f"  [PASS] {name}")
        else:
            print(f"  [FAIL] {name} -> {outcome}")
            all_passed = False
    print(f"  => apply করার জন্য {'অনুমোদিত' if all_passed else 'ব্লকড'}")

policies = [policy_no_open_db_port, policy_requires_region]

# কনফিগ ১ — কমপ্লায়েন্ট (শুধু অ্যাপ-টিয়ার থেকে DB পোর্টে অ্যাক্সেস)
compliant_config = {
    "resources": {"db-01": {"region": "dhaka-1"}, "app-01": {"region": "dhaka-1"}},
    "security_group_rules": [
        {"allow": True, "port": DB_PORT, "source_cidr": "10.0.1.0/24"},   # শুধু অ্যাপ-টিয়ার সাবনেট
    ],
}
print_validation("কনফিগ ১: কমপ্লায়েন্ট", validate_config(compliant_config, policies))

print()

# কনফিগ ২ — লঙ্ঘনকারী (DB পোর্ট পুরো ইন্টারনেটের জন্য উন্মুক্ত)
violating_config = {
    "resources": {"db-01": {"region": "dhaka-1"}, "app-01": {"region": "dhaka-1"}},
    "security_group_rules": [
        {"allow": True, "port": DB_PORT, "source_cidr": "0.0.0.0/0"},     # বিপজ্জনক!
    ],
}
print_validation("কনফিগ ২: লঙ্ঘনকারী", validate_config(violating_config, policies))

    
লক্ষ্য করুন — কনফিগ ১ উভয় পলিসি পাস করেছে, তাই apply-এর জন্য অনুমোদিত। কনফিগ ২ প্রথম পলিসি (no-open-db-port) ফেইল করেছে, তাই সম্পূর্ণ কনফিগারেশনটি ব্লক করা হয়েছে — এমনকি যদি অন্য পলিসি পাস করেও, একটি ফেইলিওরই যথেষ্ট একটি apply আটকানোর জন্য (M8-এর fail-fast CI দর্শনের সাথে সরাসরি সংযুক্ত, L33)।
মূল কথা · Key takeaway

IaC বেস্ট প্র্যাকটিস (ভার্সন কন্ট্রোল, মডিউল, আলাদা state, PR রিভিউ) ও তিন-স্তরের টেস্টিং (স্ট্যাটিক ভ্যালিডেশন, plan রিভিউ, স্বয়ংক্রিয় পলিসি-চেক) একসাথে নিশ্চিত করে ইনফ্রাস্ট্রাকচার পরিবর্তন নিরাপদ, পুনরাবৃত্তিযোগ্য ও অডিটযোগ্য থাকে। এই পুরো মডিউল ৫ জুড়ে আমরা দেখেছি কীভাবে ডিক্লারেটিভ দর্শন (L17), provider/resource/state (L18), মডিউল (L19), ইডেম্পোটেন্সি ও ড্রিফট (L20) এবং এই পাঠের পলিসি-চেক একসাথে একটি সম্পূর্ণ, নির্ভরযোগ্য IaC ওয়ার্কফ্লো তৈরি করে। পরের মডিউলে আমরা কন্টেইনারাইজেশন দিয়ে অ্যাপ্লিকেশন প্যাকেজিং শুরু করব — Docker দিয়ে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ কেন প্রতিটি এনভায়রনমেন্ট (dev/staging/production)-এর জন্য আলাদা state file রাখা গুরুত্বপূর্ণ, একটি একক শেয়ার্ড state file-এর বদলে?

একটি শেয়ার্ড state file মানে dev-এ পরীক্ষা করার সময় ভুল করে production resource-এ পরিবর্তন প্রয়োগ হয়ে যাওয়ার ঝুঁকি থাকে — একটি ভুল apply সরাসরি প্রোডাকশন সিস্টেমকে প্রভাবিত করতে পারে। আলাদা state file (আলাদা "ব্লাস্ট রেডিয়াস") নিশ্চিত করে dev-এ একটি ভুল শুধু dev-কেই প্রভাবিত করে, production সম্পূর্ণ বিচ্ছিন্ন ও নিরাপদ থাকে।

প্র ০২ স্ট্যাটিক ভ্যালিডেশন সবচেয়ে দ্রুত/সস্তা চেক কেন — এবং কেন এটি pipeline-এর সবচেয়ে প্রথম ধাপে রাখা উচিত (M8-এর L35-এর "সস্তা থেকে দামি" নীতির সাথে সংযুক্ত)?

স্ট্যাটিক ভ্যালিডেশন শুধু কনফিগ ফাইলের গঠন যাচাই করে (কোনো real ইনফ্রাস্ট্রাকচার কল বা এমনকি state file পড়ারও দরকার নেই) — তাই এটি সেকেন্ডের মধ্যে চলে। যদি একটি সহজ টাইপো বা মিসিং ফিল্ড থাকে, সেটি এই সস্তা ধাপেই ধরা ভালো, বরং অনেক পরে (ব্যয়বহুল plan/apply ধাপে) ধরার চেয়ে — ঠিক L35-এর "সস্তা চেক আগে চালান" পাইপলাইন-ডিজাইন নীতির মতোই।

প্র ০৩ উপরের কোড সেলে যদি validate_config প্রথম ফেইলিওর পাওয়ার সাথে সাথেই থেমে যেত (বাকি পলিসি না চালিয়ে), এটি কী তথ্য হারাতো?

যদি এটি প্রথম ফেইলিওরেই থেমে যেত, একজন ডেভেলপার শুধু প্রথম সমস্যাটি দেখতে পেতেন — ঠিক করার পর আবার পুরো পাইপলাইন চালিয়ে হয়তো দ্বিতীয় একটি ফেইলিওর আবিষ্কার করতেন, একটি ধীর "এক-এক করে ফিক্স" চক্র তৈরি হতো। সব পলিসি চালিয়ে সম্পূর্ণ রিপোর্ট একসাথে দেখানো (উপরের কোডের মতো) ডেভেলপারকে একবারেই সব সমস্যা ঠিক করার সুযোগ দেয় — একটি বাস্তব ট্রেড-অফ যা প্রতিটি IaC পাইপলাইন ডিজাইনে বিবেচনা করতে হয়।

অনুশীলন

  1. চিন্তা করুন: মডিউল ৫-এর পাঁচটি পাঠের (L17-L21) মধ্যে কোন ধারণাটি আপনার কাছে সবচেয়ে "সাধারণ প্রোগ্রামিং নীতির" (যেমন ফাংশন, ইডেম্পোটেন্সি, কোড রিভিউ) সবচেয়ে কাছাকাছি মনে হয়েছে? কেন IaC এই নীতিগুলো ইনফ্রাস্ট্রাকচারের জন্য ধার করেছে বলে মনে করেন?

    উদাহরণ: L19-এর মডিউল সরাসরি প্রোগ্রামিং-এর ফাংশনের ধার করা ধারণা। IaC মূলত ইনফ্রাস্ট্রাকচার ম্যানেজমেন্টে সফটওয়্যার ইঞ্জিনিয়ারিং-এর দশকের পুরনো, পরীক্ষিত নীতিগুলো (reusability, version control, review, ও testing) প্রয়োগ করে — কারণ ইনফ্রাস্ট্রাকচার এখন কোডের মতোই জটিল হয়ে উঠেছে, এবং কোড ম্যানেজমেন্টের পরীক্ষিত সমাধান পুনরায় উদ্ভাবন করার দরকার নেই।

  2. পরীক্ষা করুন: উপরের কোড সেলে একটি তৃতীয় পলিসি ফাংশন policy_no_public_admin_port(config) লিখুন যা পোর্ট ২২ (SSH)-এ 0.0.0.0/0 অ্যাক্সেস থাকলে ফেইল করে, এবং সেটি policies লিস্টে যোগ করে উভয় কনফিগে চালান।

    policy_no_open_db_port-এর মতোই একই কাঠামো — শুধু port == DB_PORT-এর বদলে port == 22 চেক করতে হবে। এই পরিবর্তনের পর, যেকোনো কনফিগে যদি পোর্ট ২২-এ 0.0.0.0/0 অ্যাক্সেস থাকে সেটিও ফেইল হিসেবে চিহ্নিত হবে — এটি দেখায় কীভাবে একটি পলিসি ভ্যালিডেটরে সহজে নতুন সিকিউরিটি নিয়ম যোগ করা যায়, প্রতিটি নতুন নিয়মের জন্য পুরো সিস্টেম পুনর্লিখন না করেই।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
Idempotency ও ড্রিফট ডিটেকশন