পাঠ ২০ · ৫৭-এর মধ্যে · মডিউল ৫
Home / Courses / Cloud Computing & DevOps / Idempotency ও ড্রিফট ডিটেকশন

Idempotency ও ড্রিফট ডিটেকশন

Idempotency & drift detection
৮ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • ইডেম্পোটেন্সি কী এবং কেন এটি IaC-এর একটি মৌলিক গ্যারান্টি
  • কনফিগারেশন ড্রিফট কীভাবে হয় এবং এটি কেন IaC-এর সবচেয়ে বড় বাস্তব-জগতের ঝুঁকিগুলোর একটি
  • ড্রিফট ডিটেকশন কীভাবে কাজ করে — শুধু সনাক্তকরণ, স্বয়ংক্রিয়ভাবে ওভাররাইট নয়
  • Python দিয়ে একটি ড্রিফট-ডিটেকশন ফাংশন লেখা

১ · Idempotency — একই কনফিগ বারবার, একই ফলাফল

L17-এ আমরা দেখেছি ডিক্লারেটিভ অ্যাপ্রোচ স্বাভাবিকভাবেই ইডেম্পোটেন্ট। এখন এই ধারণাটি আরও স্পষ্টভাবে সংজ্ঞায়িত করা যাক — IdempotencyIdempotencyএকই অপারেশন একবার প্রয়োগ করা বা একাধিকবার প্রয়োগ করা — উভয় ক্ষেত্রেই একই চূড়ান্ত ফলাফল পাওয়া যায়। ইনফ্রাস্ট্রাকচারে: একবার apply করলে বা দশবার, ফলাফল একই। (cybersecurity ও system-design কোর্সের HTTP মেথড/API ডিজাইনের ইডেম্পোটেন্সি ধারণার সরাসরি প্রয়োগ, এখানে ইনফ্রাস্ট্রাকচারের প্রেক্ষাপটে)। ব্যবহারিক অর্থে — যদি কিছু পরিবর্তন না হয়ে থাকে, একই কনফিগারেশনের উপর apply চালানো একটি no-op হওয়া উচিত — নতুন কিছু তৈরি বা কোনো এরর নয়।

২ · Configuration drift — বাস্তবতা যখন কনফিগ থেকে সরে যায়

Configuration driftConfiguration Driftreal ইনফ্রাস্ট্রাকচার IaC কনফিগারেশনে যা বর্ণিত আছে তার থেকে ভিন্ন হয়ে যাওয়া — সাধারণত কেউ কনসোলে সরাসরি ম্যানুয়াল পরিবর্তন করলে, IaC প্রক্রিয়া সম্পূর্ণ বাইপাস করে। হলো IaC-এর সবচেয়ে সাধারণ বাস্তব-জগতের সমস্যাগুলোর একটি — কেউ হয়তো একটি জরুরি হটফিক্সের জন্য সরাসরি কনসোলে একটি সার্ভারের সাইজ পরিবর্তন করে দিলো, IaC কনফিগ ফাইল আপডেট না করেই। এখন real state ও IaC কনফিগের মধ্যে একটি অসামঞ্জস্য তৈরি হয়েছে যা IaC নিজে জানে না।

ড্রিফট কেন বিপজ্জনক

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

৩ · Drift detection — পর্যায়ক্রমে তুলনা করা

Drift detection মানে পর্যায়ক্রমে (স্বয়ংক্রিয়ভাবে, একটি শিডিউলে) real live ইনফ্রাস্ট্রাকচারের অবস্থা IaC কনফিগের সাথে তুলনা করা এবং যেকোনো পার্থক্য চিহ্নিত করা — মানুষকে সতর্ক করার জন্য, স্বয়ংক্রিয়ভাবে ওভাররাইট করার জন্য নয় (ওভাররাইট করার সিদ্ধান্ত মানুষের নেওয়া উচিত, কারণ ম্যানুয়াল পরিবর্তনটি একটি বৈধ জরুরি ফিক্স হতে পারে)।

৪ · Python-এ ড্রিফট ডিটেকশন সিমুলেট করা

নিচের সিমুলেশনে detect_drift(desired_config, actual_live_state) ফাংশন দুটো dict তুলনা করে চিহ্নিত করে কোন key-এ actual অবস্থা desired থেকে ভিন্ন — একটি পরিষ্কার (কোনো ড্রিফট নেই) এবং একটি ড্রিফটেড পরিস্থিতি (কেউ ম্যানুয়ালি একটি instance-এর সাইজ পরিবর্তন করেছে) দুটোই দেখানো হয়েছে।

Python
# toy সিমুলেশন — কোনো real Terraform CLI বা cloud API কল হচ্ছে না
desired_config = {
    "web-01": {"size": "medium", "region": "dhaka-1"},
    "web-02": {"size": "small", "region": "dhaka-1"},
    "cache-01": {"size": "small", "region": "dhaka-1"},
}

def detect_drift(desired, actual):
    """desired IaC কনফিগ ও actual live state তুলনা করে ড্রিফট রিপোর্ট করে।"""
    drift_report = {}
    for name, spec in desired.items():
        actual_spec = actual.get(name)
        if actual_spec is None:
            drift_report[name] = {"status": "missing_in_live", "desired": spec}
        elif actual_spec != spec:
            drift_report[name] = {"status": "drifted", "desired": spec, "actual": actual_spec}
    return drift_report

def print_drift_report(label, report):
    print(f"--- {label} ---")
    if not report:
        print("  কোনো ড্রিফট পাওয়া যায়নি — live state ঠিক IaC কনফিগের সাথে মিলে যায়।")
        return
    for name, info in report.items():
        if info["status"] == "drifted":
            print(f"  [ড্রিফট!] {name}: কনফিগ চায় {info['desired']}, কিন্তু live-এ আছে {info['actual']}")
        else:
            print(f"  [অনুপস্থিত] {name}: কনফিগে আছে কিন্তু live infrastructure-এ পাওয়া যায়নি")

# পরিস্থিতি ১ — কোনো ড্রিফট নেই, live অবস্থা কনফিগের সাথে হুবহু মিলে যায়
clean_live_state = {
    "web-01": {"size": "medium", "region": "dhaka-1"},
    "web-02": {"size": "small", "region": "dhaka-1"},
    "cache-01": {"size": "small", "region": "dhaka-1"},
}
print_drift_report("পরিস্থিতি ১: পরিষ্কার (কোনো ম্যানুয়াল পরিবর্তন হয়নি)", detect_drift(desired_config, clean_live_state))

print()

# পরিস্থিতি ২ — কেউ কনসোলে সরাসরি web-01-এর সাইজ পরিবর্তন করেছে, IaC কনফিগ আপডেট না করেই
drifted_live_state = {
    "web-01": {"size": "large", "region": "dhaka-1"},   # ম্যানুয়ালি "large"-এ পরিবর্তিত!
    "web-02": {"size": "small", "region": "dhaka-1"},
    "cache-01": {"size": "small", "region": "dhaka-1"},
}
print_drift_report("পরিস্থিতি ২: ড্রিফটেড (কেউ কনসোলে ম্যানুয়ালি web-01 পরিবর্তন করেছে)", detect_drift(desired_config, drifted_live_state))

    
লক্ষ্য করুন — detect_drift() শুধু রিপোর্ট করে, কোনো state mutate করে না। এই বিভাজন ইচ্ছাকৃত — ড্রিফট সনাক্ত হলে একজন মানুষের সিদ্ধান্ত নেওয়া উচিত: কনফিগকে live অবস্থার সাথে মেলাতে আপডেট করা হবে (যদি ম্যানুয়াল পরিবর্তনটি বৈধ ছিল), নাকি live অবস্থাকে আবার কনফিগের সাথে মিলিয়ে দিতে apply চালানো হবে (যদি ম্যানুয়াল পরিবর্তনটি অননুমোদিত ছিল)।
মূল কথা · Key takeaway

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

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

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

প্র ০১ ড্রিফট সনাক্ত হলে drift-detection সিস্টেম কেন স্বয়ংক্রিয়ভাবে live state-কে আবার কনফিগের সাথে মিলিয়ে দেয় না, শুধু রিপোর্ট করে?

কারণ ম্যানুয়াল পরিবর্তনটি হয়তো একটি বৈধ জরুরি প্রতিক্রিয়া ছিল (যেমন একটি প্রোডাকশন ইনসিডেন্টের সময় দ্রুত একটি ইনস্ট্যান্স বড় করা)। যদি সিস্টেম স্বয়ংক্রিয়ভাবে সেই পরিবর্তন revert করে দেয়, এটি সেই জরুরি ফিক্সটি নিঃশব্দে মুছে ফেলতে পারে এবং সমস্যাটি আবার ফিরিয়ে আনতে পারে। তাই মানুষের হাতে সিদ্ধান্ত রাখা হয় — এটি কি কনফিগে প্রতিফলিত করব (permanent করার জন্য), নাকি live অবস্থাকে কনফিগের সাথে ফিরিয়ে দেব।

প্র ০২ L19-এর মডিউল ব্যবহার করলে কি কনফিগারেশন ড্রিফট প্রতিরোধ হয়? না হলে, মডিউল আর ড্রিফট আসলে কোন ভিন্ন সমস্যা সমাধান করে?

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

প্র ০৩ উপরের কোড সেলে যদি কেউ live state-এ একটি সম্পূর্ণ নতুন resource (যেমন "web-03") যোগ করে যা desired_config-এ নেই, বর্তমান detect_drift() ফাংশন কি সেটি ধরতে পারবে? কেন বা কেন নয়?

না, বর্তমান ফাংশনটি শুধু desired-এর প্রতিটি key নিয়ে actual-এ খোঁজে — এটি actual-এ এমন কোনো key যা desired-এ নেই তা ধরে না। এটি ধরতে ফাংশনে একটি অতিরিক্ত লুপ যোগ করতে হবে (ঠিক L18-এর plan() ফাংশনে "remove" ক্যাটাগরির মতো) যা actual-এর key-গুলো desired-এর বিরুদ্ধে যাচাই করে — এটি "IaC-এর বাইরে তৈরি হওয়া" resource সনাক্ত করার একটি গুরুত্বপূর্ণ অতিরিক্ত ড্রিফট ক্যাটাগরি।

অনুশীলন

  1. চিন্তা করুন: আপনার দলে (বা কল্পনা করুন) কেউ একটি "শুধু এবারের জন্য" ম্যানুয়াল পরিবর্তন করেছে জরুরি ভিত্তিতে। এক সপ্তাহ পর সেই পরিবর্তনটি কীভাবে ভুলে যাওয়া বা হারিয়ে যাওয়া সম্ভব, যদি IaC কনফিগে সেটি প্রতিফলিত না করা হয়?

    পরবর্তী কোনো অসম্পর্কিত পরিবর্তনের জন্য কেউ যদি সেই একই resource-এর উপর apply চালায়, IaC কনফিগ ফাইলে থাকা পুরনো মান (ছোট instance size) আবার প্রয়োগ হয়ে যাবে — জরুরি ফিক্সটি নিঃশব্দে হারিয়ে যাবে, এবং যে সমস্যার জন্য ফিক্সটি করা হয়েছিল সেটি হয়তো আবার ফিরে আসবে, কেউ বুঝতেও পারবে না কেন।

  2. পরীক্ষা করুন: উপরের কোড সেলে drifted_live_state-এ cache-01-এর region-ও পরিবর্তন করে দিন (যেমন "chittagong-1") এবং আবার detect_drift() চালান — রিপোর্টে কী পরিবর্তন দেখবেন?

    এখন রিপোর্টে দুটো এন্ট্রি থাকবে ড্রিফট হিসেবে চিহ্নিত — web-01 (size ভিন্ন) এবং cache-01 (region ভিন্ন) — এটি দেখায় ফাংশনটি প্রতিটি resource-কে স্বাধীনভাবে যাচাই করে, একাধিক resource-এ একসাথে ড্রিফট থাকলেও প্রতিটি আলাদাভাবে রিপোর্ট করে।

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

আগের পাঠ
Terraform মডিউল ও রিইউজেবিলিটি