পাঠ ৫৪ · ৫৮-এর মধ্যে · মডিউল ১২
Home / Courses / Software Engineering Principles & Git / DevOps ও CI/CD প্রসেস

কন্টিনিউয়াস ডেলিভারি ও ডিপ্লয়মেন্ট প্রিন্সিপল

Continuous delivery & deployment principles
৮ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • Continuous Delivery ও Continuous Deployment-এর মধ্যে সঠিক, প্রায়ই-গুলিয়ে-ফেলা পার্থক্য
  • কেন Continuous Deployment ফিচার ফ্ল্যাগ ছাড়া বাস্তবে ঝুঁকিপূর্ণ
  • ব্লু-গ্রিন ও ক্যানারি ডিপ্লয়মেন্ট স্ট্র্যাটেজির মূল ধারণা
  • একটি DeploymentPipeline সিমুলেশন যা দুটো মোডের আচরণ প্রকৃতপক্ষে আলাদা দেখায়

১ · CI-এর পরে কী হয় — Delivery বনাম Deployment

L53-এর CI নিশ্চিত করে একটি পরিবর্তন বিল্ড ও টেস্ট পাস করেছে। এই পাঠ কভার করে তারপর কী হয় — দুটো সম্পর্কিত কিন্তু ভিন্ন পরিভাষার নির্ভুল সংজ্ঞা জরুরি:

Continuous DeliveryContinuous DeliveryCI পাস করা প্রতিটি পরিবর্তন স্বয়ংক্রিয়ভাবে রিলিজযোগ্য প্যাকেজ হিসেবে প্রস্তুত হয়, কিন্তু প্রোডাকশনে প্রকৃত ডিপ্লয় একটি ম্যানুয়াল সিদ্ধান্ত (approval) দাবি করে।
CI পাস করা প্রতিটি পরিবর্তন স্বয়ংক্রিয়ভাবে প্রস্তুত/প্যাকেজ হয়, যেকোনো সময় ডিপ্লয়যোগ্য — কিন্তু আসল ডিপ্লয়মেন্ট একটি ম্যানুয়াল ট্রিগার/অনুমোদন দাবি করে (ব্যবসায়িক সময়-সংক্রান্ত কারণে, ইচ্ছাকৃত মানুষ-সিদ্ধান্তের পয়েন্ট)।
Continuous DeploymentContinuous DeploymentCI পাস করা প্রতিটি পরিবর্তন কোনো ম্যানুয়াল অনুমোদন গেট ছাড়াই স্বয়ংক্রিয়ভাবে প্রোডাকশনে ডিপ্লয় হয়ে যায়।
এক ধাপ আরও এগিয়ে — CI পাস করা প্রতিটি পরিবর্তন কোনো ম্যানুয়াল অনুমোদন গেট ছাড়াই স্বয়ংক্রিয়ভাবে প্রোডাকশনে ডিপ্লয় হয়ে যায়। এটি বাস্তবে সত্যিকারের নিরাপদ হয় শুধু M9/L42-এর ফিচার ফ্ল্যাগ (অসম্পূর্ণ ফিচার ডিপ্লয় করা যায় কিন্তু ইউজারের কাছে লুকানো থাকে) এবং একটি শক্তিশালী অটোমেটেড টেস্ট স্যুট (M10) মিলিয়ে ব্যবহার করলে।

২ · ডিপ্লয়মেন্ট স্ট্র্যাটেজি — সংক্ষিপ্ত পরিচিতি

দুটো বাস্তব, ব্যাপকভাবে ব্যবহৃত স্ট্র্যাটেজি (গভীর অবকাঠামো-মেকানিক্স Cloud Computing & DevOps কোর্সে কভার হয়, এখানে শুধু ধারণা): ব্লু-গ্রিন ডিপ্লয়মেন্ট — দুটো সম্পূর্ণ প্রোডাকশন পরিবেশ (blue ও green) একসাথে চালু রাখা হয়, নতুন ভার্সন একটিতে ডিপ্লয় করে যাচাই করার পর একবারে সব ট্র্যাফিক পুরনো থেকে নতুনটিতে সুইচ করা হয় — সমস্যা দেখা দিলে তাৎক্ষণিকভাবে পুরনোটিতে সুইচ-ব্যাক করে রোলব্যাক করা যায়। ক্যানারি ডিপ্লয়মেন্ট — M9/L42-এর শতাংশ-ভিত্তিক রোলআউট লজিকের সরাসরি ডিপ্লয়মেন্ট-লেভেল প্রয়োগ: প্রথমে বাস্তব ট্র্যাফিকের একটি ছোট অংশ নতুন ভার্সনে পাঠানো হয়, সমস্যা না দেখা দিলে ধীরে ধীরে শতাংশ বাড়ানো হয়।

৩ · DeploymentPipeline সিমুলেশন — দুটো মোডের পার্থক্য

নিচের কোড সেলে একটি DeploymentPipeline ক্লাস prepare_release()-কে (সবসময় স্বয়ংক্রিয়, L53-এর CI পাস-শর্ত ব্যবহার করে) deploy_to_production() থেকে (মোড অনুযায়ী আলাদা আচরণ) আলাদা রাখে — একই সফল রিলিজের উপর Delivery মোড ও Deployment মোড দুটোই চালিয়ে দেখানো হয়েছে, যাতে পার্থক্যটি কোডের প্রকৃত আচরণে দেখা যায়, শুধু বর্ণনায় নয়।

Python
class DeploymentPipeline:
    def __init__(self, mode="delivery"):  # "delivery" অথবা "deployment"
        self.mode = mode
        self.releases = []
        self.production_log = []

    def prepare_release(self, commit_label, ci_status):
        if ci_status != "PASSED":
            print(f"  [{commit_label}] CI ব্যর্থ -- রিলিজ প্রস্তুত করা হলো না।")
            return None
        release = {"commit": commit_label, "ready": True}
        self.releases.append(release)
        print(f"  [{commit_label}] CI পাস -- রিলিজ প্রস্তুত (packaged, যেকোনো সময় ডিপ্লয়যোগ্য)।")
        if self.mode == "deployment":
            # Continuous Deployment মোডে কোনো ম্যানুয়াল অনুমোদন ছাড়াই সাথে সাথে ডিপ্লয়
            self.deploy_to_production(release)
        return release

    def deploy_to_production(self, release, manual_approval=False):
        if self.mode == "delivery" and not manual_approval:
            print(f"  [{release['commit']}] Continuous Delivery মোড -- ম্যানুয়াল অনুমোদনের অপেক্ষায়, ডিপ্লয় করা হয়নি।")
            return False
        print(f"  [{release['commit']}] প্রোডাকশনে ডিপ্লয় সম্পন্ন।")
        self.production_log.append(release["commit"])
        return True

print("=== Continuous Delivery মোড ===")
delivery_pipeline = DeploymentPipeline(mode="delivery")
release = delivery_pipeline.prepare_release("c4", "PASSED")
delivery_pipeline.deploy_to_production(release)                       # অনুমোদন ছাড়া -- আটকে যাবে
delivery_pipeline.deploy_to_production(release, manual_approval=True) # ম্যানুয়াল অনুমোদনের পর -- ডিপ্লয় হবে
print("  production_log:", delivery_pipeline.production_log)

print()
print("=== Continuous Deployment মোড ===")
deployment_pipeline = DeploymentPipeline(mode="deployment")
release2 = deployment_pipeline.prepare_release("c5", "PASSED")        # স্বয়ংক্রিয়ভাবেই ডিপ্লয় হয়ে যাবে
print("  production_log:", deployment_pipeline.production_log)

    
হাতে-যাচাই: Delivery মোডে — প্রথম deploy_to_production কল (manual_approval=False, ডিফল্ট) শর্ত mode=="delivery" and not manual_approval সত্য হওয়ায় আটকে যায়, production_log খালি থাকে। দ্বিতীয় কল (manual_approval=True) শর্তটি মিথ্যা করে দেয়, তাই ডিপ্লয় সম্পন্ন হয়, log-এ "c4" যুক্ত হয়। Deployment মোডে — prepare_release নিজেই deploy_to_production কল করে; যেহেতু mode != "delivery", শর্তটি মিথ্যা হয়, ডিপ্লয় সাথে সাথেই সম্পন্ন হয়, কোনো অনুমোদনের অপেক্ষা ছাড়াই — log-এ "c5" যুক্ত হয়।
মূল কথা · Key takeaway

Continuous Delivery ও Continuous Deployment উভয়ই CI-এর উপর নির্ভর করে, কিন্তু "ডিপ্লয় করার সিদ্ধান্ত কে নেয়" প্রশ্নে ভিন্ন উত্তর দেয় — একটিতে মানুষ, অন্যটিতে সিস্টেম নিজেই। কোনটি বেছে নেওয়া হবে তা নির্ভর করে টিমের টেস্ট স্যুট কতটা নির্ভরযোগ্য, এবং ফিচার ফ্ল্যাগের মতো নিরাপত্তা-জাল কতটা শক্তিশালী তার উপর।

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

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

প্র ০১ একটি ব্যাংকিং সিস্টেম কি Continuous Delivery নাকি Continuous Deployment বেছে নেওয়ার সম্ভাবনা বেশি, এবং কেন?

সম্ভবত Continuous Delivery — নিয়ন্ত্রক (regulatory) কারণে, বা ব্যবসায়িক সময়ের বিবেচনায় (যেমন ব্যস্ত লেনদেনের সময় ডিপ্লয় এড়ানো) একটি সচেতন মানুষ-সিদ্ধান্ত-পয়েন্ট প্রায়ই দরকার হয়। এটি প্রমাণ করে না যে Delivery "নিরাপদ" আর Deployment "ঝুঁকিপূর্ণ" — বরং দেখায় প্রতিটি সিস্টেমের নিজস্ব প্রেক্ষাপট অনুযায়ী সঠিক পছন্দ ভিন্ন হতে পারে।

প্র ০২ ফিচার ফ্ল্যাগ (M9/L42) ছাড়া Continuous Deployment ব্যবহার করলে কী বাস্তব সমস্যা হতে পারে?

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

প্র ০৩ ব্লু-গ্রিন ডিপ্লয়মেন্টে রোলব্যাক এত দ্রুত কেন হতে পারে, ক্যানারি ডিপ্লয়মেন্টের তুলনায়?

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

অনুশীলন

  1. চিন্তা করুন: DeploymentPipeline-এর prepare_release-এ যদি ci_status "FAILED" পাস করা হয়, কী ঘটবে এবং কেন এটি Continuous Delivery/Deployment উভয় মোডের জন্যই একটি জরুরি নিরাপত্তা-চেক?

    ci_status != "PASSED" শর্ত সত্যি হবে, ফাংশন সাথে সাথে None রিটার্ন করে কোনো রিলিজ তৈরি না করেই থেমে যাবে — self.releases এবং কোনো ডিপ্লয় ঘটবে না। এটি নিশ্চিত করে যে L53-এর CI স্তর ব্যর্থ হলে, তা কখনোই Delivery বা Deployment স্তরে পৌঁছাতে পারবে না — পুরো CI/CD চেইনের প্রতিটি ধাপ আগের ধাপের সাফল্যের উপর নির্ভরশীল।

  2. পরীক্ষা করুন: উপরের কোড সেলে একটি তৃতীয় DeploymentPipeline(mode="deployment") তৈরি করে prepare_release("c6", "FAILED") কল করে Run চেপে দেখুন আউটপুট কী দেখায়।

    শুধু "[c6] CI ব্যর্থ -- রিলিজ প্রস্তুত করা হলো না।" প্রিন্ট হবে, এবং deploy_to_production কখনোই কল হবে না (যেহেতু prepare_release ব্যর্থ CI-তে আগেই return None করে বেরিয়ে যায়) — production_log খালিই থাকবে, প্রমাণ করে Deployment মোডেও একটি ব্যর্থ CI বিল্ড কখনো স্বয়ংক্রিয়ভাবে প্রোডাকশনে পৌঁছায় না।

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

আগের পাঠ
কন্টিনিউয়াস ইন্টিগ্রেশন প্রিন্সিপল