Course-এর সূচি

25.1

AWS CloudFormation

infrastructure as code, stack, change set, StackSet, আর iam:PassRole সহ service role।

20 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই lesson শেষে তুমি যা পারবে

  • infrastructure as code কী দেয় (বারবার একইভাবে বানানো যায়, review করা যায়, version রাখা যায়, এক চাপে মোছা যায়, stack ধরে খরচ দেখা যায়, দুর্যোগের পর দ্রুত আবার দাঁড় করানো যায়) আর কেন “Infrastructure as Code”, “repeatable deployment” বা “version control for infrastructure” শুনলেই AWS-এর উত্তর CloudFormation, সেটা বুঝিয়ে বলতে পারবে।
  • YAML template পড়তে আর লিখতে পারবে: Parameters (type, AllowedValues, SSM parameter type), Mappings, Conditions, Resources, export সহ Outputs, intrinsic function (Ref, Fn::GetAtt, Fn::Sub, Fn::Join, Fn::FindInMap, Fn::If, Fn::ImportValue) আর pseudo parameter।
  • একটা stack-এর পুরো জীবন অনুসরণ করতে পারবে: কোন ক্রমে তৈরি হয়, rollback আর ROLLBACK_COMPLETE, CreationPolicy আর cfn-signal দিয়ে instance-এর জন্য অপেক্ষা, change set দিয়ে update, আর DeletionPolicy মেনে delete।
  • production রক্ষা করতে পারবে: DeletionPolicy (Retain, Snapshot, RetainExceptOnCreate), UpdateReplacePolicy, stack policy আর termination protection দিয়ে।
  • drift খুঁজে বের করে ঠিক করতে পারবে, আর drift detection কী দেখতে পায় না, সেটাও বলতে পারবে।
  • service role ঠিকভাবে ব্যবহার করতে পারবে: user-এর লাগবে CloudFormation-এর permission আর iam:PassRole, resource-এর permission থাকবে role-এর কাছে।
  • cross-stack reference আর nested stack-এর মধ্যে বেছে নিতে পারবে, StackSets দিয়ে এক template অনেক account আর Region-এ পাঠাতে পারবে, আর custom resource, Infrastructure Composer, CDK, SAM, Terraform, CloudFormation Guard, IaC generator ও Git sync কোনটা কোথায় বসে, জানবে।

#কেন: console-এ click করা কোনো পদ্ধতি না

১.৩ lesson-এ infrastructure as code (IaC)-এর সঙ্গে পরিচয় হয়েছিল: তুমি একটা file-এ লিখে দাও কী চাও, আর একটা tool সেই অনুযায়ী API call করে। এই lesson সেই কাজের AWS-এর নিজস্ব tool AWS CloudFormation নিয়ে, পরীক্ষা আর বাস্তব team-এর যতটা গভীরে দরকার ততটা।

ভাবো, চারটা subnet, দুটো route table, একটা NAT gateway, তিনটা security group, একটা load balancer, একটা Auto Scaling group আর একটা database-সহ একটা VPC তুমি console-এ click করে করে বানাচ্ছ। একবার ঠিকঠাক হয়ে যায়। তারপর:

  • Staging-কে হুবহু production-এর মতো হতে হবে। কেউ ১৫০টা click আবার করে, একটা security group rule ভুলে যায়। শুধু production-এ যে bug দেখা দেয়, সেটা ওই হারানো rule।
  • কেউ বদলটা review করেনি। Console-এর click-এর কোনো pull request নেই, দ্বিতীয় কেউ দেখে না, ইতিহাস বলতে শুধু CloudTrail-এর একটা লাইন যে “কেউ AuthorizeSecurityGroupIngress ডেকেছিল”।
  • পরিষ্কার করে মোছা যায় না। কয়েক মাস পরে কারও মনে থাকে না ৪০টা resource-এর কোনগুলো ওই পরীক্ষার ছিল, তাই সেগুলো চলতেই থাকে, খরচও চলতে থাকে।
  • দুর্যোগে আবার লাগবে, দ্রুত। Outage-এর মধ্যে অন্য Region-এ হাতে হাতে আবার বানানো ধীর, আর ভুলে ভরা (২৩.১ lesson)।

CloudFormation হলো AWS infrastructure বর্ণনা করার একটা declarative উপায়। একটা template-এ তুমি বলো, “আমার একটা security group চাই, সেটা ব্যবহার করা দুটো EC2 instance চাই, একটা S3 bucket চাই, আর instance-গুলোর সামনে একটা load balancer চাই”। কোন ক্রমে বানাতে হবে, CloudFormation নিজেই বের করে, তুমি যেমন লিখেছ ঠিক তেমন configuration দিয়ে call করে, আর যা বানাল সবকিছু একটা ইউনিট হিসেবে হিসাব রাখে, যার নাম stack। প্রায় সব AWS resource type সমর্থিত, আর নতুন service সাধারণত launch-এর সময়ই বা তার কিছু পরেই CloudFormation-এ চলে আসে।

এতে যা পাও:

সুবিধাবাস্তবে এর মানে
হাতে বানানো resource নেইStack-এর সবকিছু template থেকে এসেছে, তাই template নিজেই documentation।
Code reviewInfrastructure-এর বদল application code-এর মতোই Git আর pull request দিয়ে যায় (“version control for infrastructure”)।
বারবার একই রকমএকই template দিয়ে dev, staging, prod, যেকোনো Region বা account-এ, শুধু parameter আলাদা।
এক চাপে মোছাStack delete করলে যা যা বানিয়েছিল সব মুছে যায়, ঠিক ক্রমে।
Stack ধরে খরচCloudFormation সমর্থিত resource-এ aws:cloudformation:stack-name tag বসায়; সেটা cost allocation tag হিসেবে চালু করলে কোন stack-এর কত খরচ দেখা যায় (২৫.৪ lesson)।
Dev-এ সাশ্রয়একটা schedule বিকেল ৫টায় dev stack মুছে সকাল ৮টায় আবার বানাতে পারে, নিরাপদে, কারণ template হুবহু আবার বানিয়ে দেয়।
Disaster recoveryRecovery Region-এ পুরো environment আবার দাঁড় করাতে শুধু template (আর ডেটার কপি) লাগে।
চাকা নতুন করে বানাতে হয় নাসাধারণ design-এর (WordPress site, public আর private subnet-সহ VPC) জন্য AWS আর community sample template প্রকাশ করে।

AWS resource type-এর জন্য CloudFormation নিজে বিনা পয়সায়: তুমি টাকা দাও তার বানানো resource-এর জন্য। Third-party বা private resource type আর hook-এর প্রতিটা operation-এ সামান্য charge আছে।

#Template: তুমি যা লেখো

#Template-এর গঠন

Template হলো একটা JSON বা YAML file। YAML ছোট হয় আর comment লেখা যায়, তাই বেশিরভাগ team এটাই ব্যবহার করে। নিচে wallet-এর file-upload service-এর জন্য একটা সম্পূর্ণ ছোট template, সাধারণ সব section-সহ:

AWSTemplateFormatVersion: '2010-09-09'          # optional; the only valid value
Description: Upload bucket and web security group for the wallet

Parameters:
  Env:
    Type: String
    AllowedValues: [dev, staging, prod]         # anything else is rejected before creation
    Default: dev
  VpcId:
    Type: AWS::EC2::VPC::Id                     # AWS-specific type: must be a real VPC in this Region
  LatestAmi:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64

Mappings:
  EnvSize:
    dev:     { InstanceType: t4g.micro }
    staging: { InstanceType: t4g.small }
    prod:    { InstanceType: m7g.large }

Conditions:
  IsProd: !Equals [!Ref Env, prod]

Resources:                                      # the only required section
  UploadBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain                      # keep customer files if the stack is deleted
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Sub 'wallet-uploads-${Env}-${AWS::AccountId}-example'
      VersioningConfiguration:
        Status: !If [IsProd, Enabled, Suspended]

  WebSg:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub 'Web tier ${Env}'
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - { IpProtocol: tcp, FromPort: 443, ToPort: 443, CidrIp: 0.0.0.0/0 }

  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmi
      InstanceType: !FindInMap [EnvSize, !Ref Env, InstanceType]
      SecurityGroupIds: [!GetAtt WebSg.GroupId]   # implicit dependency: WebSg first

Outputs:
  BucketArn:
    Value: !GetAtt UploadBucket.Arn
    Export:
      Name: !Sub '${AWS::StackName}-BucketArn'  # other stacks can import this
Sectionবাধ্যতামূলক?কী থাকে
AWSTemplateFormatVersionনাFormat-এর version; একমাত্র মান 2010-09-09।
Descriptionনাযা খুশি লেখা, সর্বোচ্চ ১,০২৪ byte।
Metadataনাবাড়তি তথ্য, যেমন console-এ parameter কীভাবে সাজানো দেখাবে, বা cfn-init-এর configuration।
ParametersনাCreate বা update-এর সময় দেওয়া input (সর্বোচ্চ ২০০টা)।
Rulesনাকিছু বানানোর আগে parameter-গুলো মিলিয়ে যাচাই (“prod-এ বড় instance type লাগবে”)।
Mappingsনাস্থির lookup table (Region ধরে, environment ধরে), পড়া হয় Fn::FindInMap দিয়ে।
Conditionsনাহ্যাঁ/না মান, যা ঠিক করে কোনো resource, property বা output থাকবে কি না।
TransformনাMacro, যা আগে template-টাকে নতুন করে লেখে, যেমন SAM-এর জন্য AWS::Serverless-2016-10-31।
Resourcesহ্যাঁযেসব resource বানাতে হবে (এক template-এ সর্বোচ্চ ৫০০টা), প্রতিটার একটা logical ID, একটা Type আর Properties।
Outputsনাযে মান দেখাতে বা অন্য stack-এর জন্য export করতে চাও (সর্বোচ্চ ২০০টা)।

Template সরাসরি পাঠানো যায় ৫১,২০০ byte পর্যন্ত; এর চেয়ে বড় হলে (১ MB পর্যন্ত) আগে S3-এ তুলতে হয়, aws cloudformation deploy --s3-bucket বা package সেটা তোমার হয়ে করে দেয়।

#Parameter, mapping আর condition

  • Parameter দিয়ে একটা template অনেক environment-এ চলে। Type-এর মধ্যে আছে String, Number, CommaDelimitedList, আর AWS::EC2::VPC::Id বা AWS::EC2::KeyPair::KeyName-এর মতো AWS-নির্দিষ্ট type, যেগুলো console drop-down list হিসেবে দেখায় আর CloudFormation যাচাই করে। AllowedValues, AllowedPattern, MinValue/MaxValue কিছু বানানোর আগেই ভুল input বাতিল করে। NoEcho: true console আর API-র output-এ মান লুকিয়ে রাখে, কিন্তু আসল secret-এর জায়গা Secrets Manager আর একটা dynamic reference (২১.৩ lesson)।
  • SSM parameter type deploy-এর সময় Parameter Store থেকে মান পড়ে। AWS::EC2::Image::Id type-এর AWS::SSM::Parameter::Value, সঙ্গে নতুনতম Amazon Linux AMI-র public parameter দিলে template-এ কখনো AMI ID লিখে রাখতে হয় না, যেটা এমনিতেও Region ভেদে আলাদা। মানটা প্রতিবার create বা update-এর সময় পড়া হয়, তাই stack update করলে তবেই AMI বদলায়।
  • Mapping হলো স্থির table: Region ধরে AMI, environment ধরে instance size। আগে থেকে জানা মানের জন্য mapping; যে deploy করছে সে যা বেছে নেবে, তার জন্য parameter।
  • Condition দিয়ে কিছু resource শুধু কিছু environment-এ বানানো যায়: দ্বিতীয় NAT gateway, versioning বা read replica শুধু Env যখন prod। Condition: IsProd দেওয়া resource dev-এ থাকেই না।

#Intrinsic function আর pseudo parameter

Function (YAML-এর ছোট রূপ)কী ফেরত দেয়উদাহরণ
!RefParameter-এর মান, বা resource-এর মূল পরিচয় (instance ID, bucket-এর নাম, security group ID…)!Ref VpcId
!GetAttResource-এর অন্য কোনো attribute!GetAtt UploadBucket.Arn, !GetAtt Db.Endpoint.Address
!Sub${...} জায়গাগুলো ভরে দেওয়া string!Sub 'arn:aws:s3:::${UploadBucket}/*'
!Joinএকটা চিহ্ন দিয়ে জোড়া মান!Join [',', [a, b, c]]
!FindInMapMappings থেকে একটা মান!FindInMap [EnvSize, !Ref Env, InstanceType]
!IfCondition অনুযায়ী দুটোর একটা মান!If [IsProd, Enabled, Suspended]
!ImportValueঅন্য stack-এর একটা export!ImportValue wallet-network-VpcId
!Equals, !And, !Or, !NotConditions-এর জন্য হ্যাঁ/না!Equals [!Ref Env, prod]
!Select, !Split, !GetAZs, !Cidr, !Base64List, AZ-এর নাম, subnet range, user data!Select [0, !GetAZs '']

Pseudo parameter CloudFormation আগে থেকেই ঠিক করে রাখে: AWS::Region, AWS::AccountId, AWS::StackName, AWS::StackId, AWS::Partition, AWS::URLSuffix, আর AWS::NoValue (একটা property সরিয়ে দেয়, প্রায়ই !If-এর ভেতরে)। এগুলোর জন্যই একটা template না বদলে যেকোনো account আর Region-এ চলে।

#নির্ভরতা আর তৈরির ক্রম

ক্রম তুমি কখনো লেখো না। CloudFormation template থেকে একটা dependency graph বানায়:

  • Implicit নির্ভরতা: যে resource অন্য resource-এর ওপর !Ref বা !GetAtt ব্যবহার করে, সে তার ওপর নির্ভরশীল। WebServer ব্যবহার করে WebSg.GroupId, তাই security group আগে তৈরি হয়।
  • Explicit নির্ভরতা: কোনো reference নেই কিন্তু ক্রম জরুরি, তখন DependsOn: [Name]। সবচেয়ে চেনা উদাহরণ: VPC-তে একটা Elastic IP বা NAT gateway-কে অপেক্ষা করতে হয় internet gateway attachment-এর জন্য, যেটা কোনো property-তে reference করা থাকে না।
  • একসঙ্গে তৈরি: যাদের মধ্যে কোনো নির্ভরতা নেই, তারা একই সময়ে তৈরি হয়, এ জন্যই ৬০টা resource-এর stack ঘণ্টা না, মিনিটে হয়ে যায়। Delete-এর সময় একই graph উল্টো দিকে চলে।

Template থেকে stack

Wallet team-এর template-এ আছে একটা security group, সেটা ব্যবহার করা একটা EC2 instance, আর DeletionPolicy Retain দেওয়া একটা S3 bucket। CloudFormation কোন ক্রমে বানায়, আর কিছু ব্যর্থ হলে কী হয়, দেখো।

পরিস্থিতি

CloudFormation একটা dependency graph বানায়, আর যাদের মধ্যে নির্ভরতা নেই তাদের একসঙ্গে বানায়।

Templatewallet.yaml
CloudFormationwallet-devCREATE_IN_PROGRESS
Security group
EC2 instance
S3 bucket
create-stack
ধাপ 1 / 4
1

Engineer wallet.yaml দিয়ে create-stack চালায়। কেউ ধাপের ক্রম লেখে না: template শুধু বলে কী কী থাকা উচিত।

#একটা stack-এর জীবন

#Stack-এর অবস্থা

Statusমানে
CREATE_IN_PROGRESS → CREATE_COMPLETEতৈরি চলছে, তারপর সফলভাবে শেষ।
CREATE_FAILEDকোনো resource ব্যর্থ; rollback বন্ধ থাকলে debug করার জন্য stack এখানেই থেকে যায়।
ROLLBACK_IN_PROGRESS → ROLLBACK_COMPLETEতৈরি ব্যর্থ, আর এ পর্যন্ত যা বানানো হয়েছিল সব মুছে ফেলা হয়েছে। এই stack শুধু delete করা যায়।
UPDATE_IN_PROGRESS → UPDATE_COMPLETE_CLEANUP_IN_PROGRESS → UPDATE_COMPLETEএকটা update, তারপর বদলে ফেলা পুরোনো resource সরানো।
UPDATE_ROLLBACK_IN_PROGRESS → UPDATE_ROLLBACK_COMPLETEUpdate ব্যর্থ, stack তার শেষ চালু অবস্থায় ফিরে গেছে। এটা ব্যবহারযোগ্য, আবার update করা যায়।
UPDATE_ROLLBACK_FAILEDRollback-ও ব্যর্থ (প্রায়ই কেউ হাতে কোনো resource মুছে ফেলেছে বলে)। কারণটা ঠিক করো, তারপর continue update rollback।
DELETE_IN_PROGRESS → DELETE_COMPLETE / DELETE_FAILEDDelete; যেমন খালি না হওয়া S3 bucket-এ ব্যর্থ হয়। আটকে থাকা resource রেখে দিয়ে আবার চেষ্টা করো।

#তৈরি ব্যর্থ হলে

CloudFormation একটা stack-কে হয় পুরোটা, নয় কিছুই না হিসেবে দেখে। তৈরির সময় কোনো একটা resource ব্যর্থ হলে, default-এ সে rollback করে: ইতিমধ্যে বানানো প্রতিটা resource মুছে দেয়, আর stack শেষ হয় ROLLBACK_COMPLETE-এ। সেই stack update বা মেরামত করা যায় না; এটা শুধু ব্যর্থতার একটা রেকর্ড। Events tab-এ প্রথম CREATE_FAILED-এর কারণ পড়ো, stack delete করো, template ঠিক করো, আবার বানাও।

কারণটা যখন স্পষ্ট না (instance-এর ভেতরে bootstrap script মরে যাচ্ছে), rollback ঠিক সেই প্রমাণটাই মুছে দেয় যেটা তোমার দরকার। Debug করার জন্য:

  • --disable-rollback (বা --on-failure DO_NOTHING) resource-গুলো রেখে দেয়, stack থাকে CREATE_FAILED-এ। Instance আর তার log দেখো, তারপর ঠিক করে update দিয়ে আবার চেষ্টা করো, বা rollback-stack দিয়ে নিজে rollback করো।
  • --retain-except-on-create যেসব resource-এর DeletionPolicy বলে Retain, সেগুলো রেখে দেয়, শুধু এই operation-এই তৈরি হওয়াগুলো ছাড়া।

Update ব্যর্থ হলে rollback stack-কে আগের template-এ ফিরিয়ে নেয়, আর stack শেষ হয় UPDATE_ROLLBACK_COMPLETE-এ, যেটা একটা চালু অবস্থা। একমুখী ROLLBACK_COMPLETE আসে শুধু তৈরি ব্যর্থ হলে।

#Instance তৈরি হওয়া পর্যন্ত অপেক্ষা: CreationPolicy আর cfn-signal

EC2 যেই বলে instance চলছে, সেই মুহূর্তেই instance “তৈরি”, অথচ তোমার application-এর হয়তো তারপরও দশ মিনিট installation লাগবে। কোনো load balancer বা test যদি ওই instance-এর ওপর নির্ভর করে, CloudFormation-এর অপেক্ষা করা উচিত software-এর জন্য, শুধু server-এর জন্য না। এই কাজ CreationPolicy-এর:

WebServer:
  Type: AWS::EC2::Instance
  CreationPolicy:
    ResourceSignal: { Count: 1, Timeout: PT15M }   # wait up to 15 minutes for 1 success signal
  Metadata:
    AWS::CloudFormation::Init:                     # what cfn-init installs
      config:
        packages: { dnf: { nginx: [] } }
        services: { systemd: { nginx: { enabled: true, ensureRunning: true } } }
  Properties:
    UserData:
      Fn::Base64: !Sub |
        #!/bin/bash
        /opt/aws/bin/cfn-init   -s ${AWS::StackName} -r WebServer --region ${AWS::Region}
        /opt/aws/bin/cfn-signal -e $? -s ${AWS::StackName} -r WebServer --region ${AWS::Region}

CloudFormation helper script (package aws-cfn-bootstrap, Amazon Linux-এ আগে থেকেই থাকে): cfn-init AWS::CloudFormation::Init metadata পড়ে package install করে, file লেখে, service চালু করে; cfn-signal CloudFormation-কে সফল (exit code 0) বা ব্যর্থ হওয়ার খবর পাঠায়; cfn-hup metadata-র ওপর নজর রাখে, stack update-এ সেটা বদলালে কাজগুলো আবার চালায়; cfn-get-metadata সেটা দেখায়। Timeout (সর্বোচ্চ ১২ ঘণ্টা)-এর আগে success signal না এলে resource ব্যর্থ হয় আর stack rollback হয়। একই policy Auto Scaling group-এও চলে (“৩টা instance signal না দেওয়া পর্যন্ত অপেক্ষা করো”)। Signal পাঠাতে instance-এর CloudFormation endpoint-এ পৌঁছানোর পথ লাগে: private subnet-এ NAT gateway বা interface VPC endpoint।

#নিরাপদে stack বদলানো

#Update তিন রকম

তুমি কোনো property বদলালে CloudFormation চলমান resource-টা তিনভাবে update করতে পারে। কোন property-তে কোনটা লাগে, resource reference-এ লেখা থাকে:

Update-এর ধরনকী ঘটেউদাহরণ
No interruptionজায়গাতেই বদলায়; resource চলতে থাকে, ID একই থাকেSecurity group rule, tag, S3 lifecycle rule
Some interruptionজায়গাতেই বদলায়, তবে অল্প সময় বন্ধ থাকেEC2 instance type (instance বন্ধ করে আবার চালু হয়)
Replacementএকটা নতুন resource বানানো হয়, reference তার দিকে ঘোরে, তারপর পুরোনোটা মোছা হয়EC2-র ImageId, RDS-এর DBInstanceIdentifier, S3-এর BucketName

বিপজ্জনক হলো replacement: নতুন resource-এর নতুন physical ID, নতুন IP address, আর database হলে snapshot restore না করলে কোনো ডেটাই নেই। যে resource-এর নাম তুমি নিজে ঠিক করে দিয়েছ, পুরোনোটা থাকা অবস্থায় সেটা replace করাই যায় না, কারণ নামটা দখল হয়ে আছে; খুব দরকার না হলে নাম দেওয়ার কাজ CloudFormation-কেই করতে দাও।

#Change set: প্রয়োগের আগে দেখে নাও

Change set হলো একটা diff, যা CloudFormation কিছু না বদলেই হিসাব করে: প্রতিটা resource-এর জন্য action (Add, Modify, Remove, Import), আর modify হলে replacement লাগবে কি না (True, False বা Conditional)। তুমি সেটা দেখো, তারপর execute করো বা মুছে দাও। Stack সরাসরি update করলে এই আগাম দেখা বাদ পড়ে; অনেক team production-এ বদল শুধু change set দিয়েই হতে দেয়।

Action   LogicalId    Type                         Replacement
Modify   WebSg        AWS::EC2::SecurityGroup      False
Modify   WebServer    AWS::EC2::Instance           True      <- new instance, new IP
Add      AlarmHigh    AWS::CloudWatch::Alarm       -

Change set দেখায় CloudFormation কী করতে চায়; সাফল্যের নিশ্চয়তা দিতে পারে না (quota বা নামের সংঘর্ষে update তখনো ব্যর্থ হতে পারে), যদিও নভেম্বর ২০২৫ থেকে change set pre-deployment validation চালায়, যা এমন অনেক ভুল আগেই ধরে।

#যা জরুরি, তাকে রক্ষা করা

Controlকীসের বিরুদ্ধে রক্ষাকীভাবে
DeletionPolicyTemplate থেকে সরালে বা stack delete করলে resource হারানোDelete (default), Retain (রেখে দাও, যেকোনো resource type-এ), Snapshot (শেষ একটা snapshot নিয়ে তারপর মোছো), RetainExceptOnCreate (রেখে দাও, যদি না যে operation rollback হচ্ছে সেটাই এটা বানিয়ে থাকে)
UpdateReplacePolicyUpdate-এ replace হলে পুরোনো resource হারানোএকই মান: Delete, Retain, Snapshot
Stack policyCloudFormation দিয়ে জরুরি resource-এর updateStack-এ লাগানো একটা JSON document: লাগানোর পর allow না করা পর্যন্ত প্রতিটা resource সুরক্ষিত; সাধারণভাবে Update:* allow করো, আর production database-এ Update:Replace আর Update:Delete deny করো
Termination protectionকেউ পুরো stack delete করে ফেলাupdate-termination-protection --enable-termination-protection; nested stack এটা root stack থেকে পায়

Snapshot শুধু সেই resource-গুলোতে চলে যাদের snapshot হয়: AWS::EC2::Volume, AWS::RDS::DBInstance, AWS::RDS::DBCluster, AWS::ElastiCache::CacheCluster, AWS::ElastiCache::ReplicationGroup, AWS::Redshift::Cluster, AWS::Neptune::DBCluster আর AWS::DocDB::DBCluster। AWS::RDS::DBCluster-এর জন্য, আর cluster-এর অংশ নয় এমন AWS::RDS::DBInstance-এর জন্য default আগে থেকেই Snapshot। S3 bucket-এর snapshot হয় না; Retain ব্যবহার করো। ভেতরে object থাকলে bucket মোছাই যায় না, তাই খালি না হওয়া bucket-এ Delete শেষ হয় DELETE_FAILED-এ।

একটা stack policy-র উদাহরণ, যেটা team-কে database replace বা delete ছাড়া বাকি সব বদলাতে দেয়:

{
  "Statement": [
    { "Effect": "Allow", "Principal": "*", "Action": "Update:*", "Resource": "*" },
    { "Effect": "Deny",  "Principal": "*", "Action": ["Update:Replace", "Update:Delete"],
      "Resource": "LogicalResourceId/WalletDb" }
  ]
}

Stack policy একবার লাগালে সরানো যায় না, শুধু বদলানো যায়; ইচ্ছাকৃত কোনো বদলের জন্য ওই একটা update-এর সঙ্গে একটা সাময়িক override policy দিতে হয়। এটা শুধু CloudFormation দিয়ে করা update নিয়ন্ত্রণ করে: কেউ RDS console থেকে database বদলালে আটকায় না (সেটা drift), আর stack delete-ও আটকায় না (সেটা termination protection আর DeletionPolicy-এর কাজ)।

Change set দিয়ে stack update

Change set হলো একটা আগাম দেখা: CloudFormation হিসাব করে সে কী করবে, আর তুমি execute না করা পর্যন্ত কিছুই বদলায় না। সবচেয়ে মন দিয়ে পড়ার কলাম Replacement।

পরিস্থিতি

কিছু property বদল চলমান resource-এর ওপরই হয়, resource চলতেই থাকে।

Engineer
CloudFormationwallet-prod
Web serveri-0aaa
Wallet DB
create-change-set
ধাপ 1 / 3
1

Engineer web server-এ একটা cost-center tag যোগ করে, আর সরাসরি update না করে একটা change set বানায়।

#Drift: তবুও কেউ যখন click করে

CloudFormation শুধু নিজের করা কাজটুকু জানে। কেউ console থেকে stack-এর কোনো resource বদলালে stack তখনো বলে UPDATE_COMPLETE, অথচ বাস্তব আর template আর মেলে না। এই ফারাকটাই drift, আর সেটা খুঁজে বের করে drift detection: CloudFormation সমর্থিত প্রতিটা resource-এর চালু configuration পড়ে template আর parameter-এর সঙ্গে মেলায়।

Resource-এর drift statusমানে
IN_SYNCTemplate-এর সঙ্গে মেলে
MODIFIEDকোনো property আলাদা; বিস্তারিত অংশে প্রত্যাশিত বনাম আসল মান (NOT_EQUAL, ADD, REMOVE)
DELETEDResource-টা CloudFormation-এর বাইরে মুছে ফেলা হয়েছে
NOT_CHECKEDএই resource type drift detection সমর্থন করে না

Drift detection যা দেখতে পায় না:

  • Stack-এর বাইরের resource। কেউ হাতে চালু করা instance কোনো stack-এর চোখেই পড়ে না; পুরো account-এ নজর রাখার tool AWS Config (১৯.৭ lesson)।
  • Template-এ যে property লেখা নেই। শুধু স্পষ্ট করে লেখা property মেলানো হয়, default মান না। কোনো property-তে নজর চাইলে সেটা লিখে দাও, default মান হলেও।
  • যে মান service কখনো ফেরত দেয় না, যেমন password, আর যা CloudFormation আবার মেলাতে পারে না, যেমন Lambda function-এর code।
  • Nested stack parent-এর drift detection-এ যাচাই হয় না; প্রতিটা nested stack-এ আলাদা করে চালাও।
  • এটা সারাক্ষণ চলে না: তুমি চালু করলে চলে (অথবা তোমার বানানো schedule-এ, যেমন EventBridge rule আর AWS Config-এর managed rule cloudformation-stack-drift-detection-check দিয়ে)।

Drift ঠিক করার উপায়:

  1. হাতে resource-টা template-এর মতো ফিরিয়ে দাও, অথবা
  2. হাতের বদলটাই ঠিক হলে template বাস্তবের মতো করে লেখো, তারপর stack update করো, অথবা
  3. নভেম্বর ২০২৫ থেকে একটা drift-aware change set বানাও (--deployment-mode REVERT_DRIFT): CloudFormation template, শেষ deployment আর চালু অবস্থা, তিনটা মেলায়, আর update drift হওয়া resource-গুলোকে template-এর মতো ফিরিয়ে আনে।
  4. যে resource CloudFormation-এর বাইরে বানানো হয়েছিল কিন্তু এখন থেকে CloudFormation সামলাবে, তার জন্য resource import: DeletionPolicy সহ template-এ যোগ করো, আর IMPORT ধরনের একটা change set বানাও।

Drift: template বনাম বাস্তব

একজন junior admin console থেকে stack-এর resource বদলে ফেলে। কেউ drift detection না চালানো পর্যন্ত CloudFormation টেরই পায় না, আর চালালেও শুধু নিজের সামলানো জিনিসই দেখে।

পরিস্থিতি

Stack-এর resource-এ হাতে দেওয়া rule ধরা পড়ে MODIFIED হিসেবে, তফাতের ধরন ADD।

Junior adminconsole
Web SG
CPU alarm
CloudFormationorders-prodUPDATE_COMPLETE
Template
port 22 যোগ
ধাপ 1 / 5
1

রাত ২টায়, একটা incident-এর মধ্যে, junior admin console থেকে web security group-এ 0.0.0.0/0 থেকে SSH খুলে দেয় “দশ মিনিটের জন্য”, তারপর ভুলে যায়।

#Service role আর iam:PassRole

Default-এ CloudFormation কাজ করে যে operation শুরু করেছে তার permission নিয়েই: তোমার credential থেকে একটা অস্থায়ী session বানায়। Stack দিয়ে EC2 instance বানাতে হলে তোমার নিজেরই ec2:RunInstances লাগবে। নিয়মকানুনে বাঁধা কোনো company-তে security team ঠিক এটাই চায় না: developer অনুমোদিত stack deploy করবে, যা খুশি তা চালু করবে না।

সমাধান service role। এটা একটা IAM role, যেটা CloudFormation assume করে (এর trust policy-তে লেখা থাকে cloudformation.amazonaws.com), আর resource-এর permission থাকে এর কাছেই। User-এর শুধু লাগে stack নিয়ে কাজ করার permission, আর সেই role CloudFormation-এর হাতে দেওয়ার permission:

কেকী লাগেউদাহরণ
Usercloudformation:CreateStack, UpdateStack, DeleteStack, CreateChangeSet… (প্রায়ই stack-এর নাম দিয়ে সীমিত), আর role-টার ওপর iam:PassRolestack/app-*-এ cloudformation:*, role/cfn-app-deployer-এ iam:PassRole
Service roleTemplate-এর resource-গুলোর permissionInstance আর security group-এর জন্য ec2:*, bucket-এর জন্য s3:*Bucket
{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow",
      "Action": ["cloudformation:CreateStack", "cloudformation:UpdateStack", "cloudformation:DeleteStack",
                 "cloudformation:CreateChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:Describe*"],
      "Resource": "arn:aws:cloudformation:ap-southeast-1:111122223333:stack/app-*/*" },
    { "Effect": "Allow", "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::111122223333:role/cfn-app-deployer",
      "Condition": { "StringEquals": { "iam:PassedToService": "cloudformation.amazonaws.com" } } }
  ]
}

iam:PassRole কেন জরুরি (২.৪ lesson): এই যাচাই না থাকলে stack বানানোর অনুমতি থাকা একজন user service role হিসেবে কোনো administrator role-এর নাম দিয়ে যা খুশি বানিয়ে ফেলতে পারত। iam:PassRole শুধু একটা deployment role-এ সীমিত রাখাই এই design-কে least privilege বানায়।

যা জেনে রাখা ভালো:

  • একবার stack-এ service role লাগলে CloudFormation সেই stack-এর প্রতিটা কাজে সেটাই ব্যবহার করে, আর সেটা সরানো যায় না (শুধু বদলানো যায়, তাও এমন কেউ যার নতুন role pass করার অনুমতি আছে)।
  • ওই stack update বা delete করার অনুমতি যার আছে, সে iam:PassRole ছাড়াই তার role ব্যবহার করে। তাই role-কে সরু রাখো, আর স্পর্শকাতর stack-এ cloudformation:UpdateStack সীমিত করো।
  • Service role না থাকলে, ec2:RunInstances নেই এমন একজন user-ও CreateStack ডাকতে পারে; stack শুরু হয়, instance AccessDenied-এ ব্যর্থ হয়, stack rollback হয়।

Service role দিয়ে deploy

ব্যাংকের একজন developer stack deploy করতে পারে, কিন্তু নিজে EC2 instance চালু করতে পারে না। EC2-র permission আছে service role cfn-app-deployer-এর কাছে; তার নিজের আছে শুধু stack-এর permission আর iam:PassRole।

পরিস্থিতি

কাজ করে role; developer শুধু সেটা হাতে তুলে দেয়।

DeveloperEC2-র অনুমতি নেই
IAM
CloudFormation
EC2
create-stack --role-arn
ধাপ 1 / 6
1

সে payments API-র stack বানায়, আর --role-arn দিয়ে role cfn-app-deployer-এর নাম দেয়।

এই developer কি deploy করতে পারবে?

app-payments-api stack একটা EC2 instance বানায়। Permission আর role বদলাও, তারপর Deploy চাপো।

Developer-এর permission

Stack আর service role

Switch-গুলো ঠিক করো, তারপর Deploy চাপো।

#Stack ভাগ করা আর মান ভাগাভাগি

একটা বিশাল stack ধীর হয়ে যায়, ঝুঁকিপূর্ণ হয়ে যায়, আর এমন সব team সেটা ভাগ করে যাদের একে অপরের অংশে হাত দেওয়ার কথা না। ভাগ করার দুটো উপায় আছে, আর পরীক্ষা চায় তুমি এ দুটোকে আলাদা করে চেনো:

Cross-stack reference (export)Nested stack

  • Stack A একটা output export করে (Export: Name: wallet-network-VpcId); stack B সেটা পড়ে !ImportValue wallet-network-VpcId দিয়ে।
  • Stack-গুলোর জীবন আলাদা, প্রায়ই মালিকও আলাদা: network team network stack update করে, app team-গুলো তার ওপর নিজেদের stack deploy করে।
  • Export-এর নাম account আর Region-এ অনন্য; import চলে শুধু একই Region আর account-এর মধ্যে।
  • কোনো stack একটা export import করে রাখলে, export করা stack delete করা যায় না, আর export করা মান বদলানো যায় না।
  • কাজে লাগে: একটা VPC, subnet বা security group অনেক স্বাধীন stack-এর সঙ্গে ভাগাভাগি করতে।
  • একটা parent (root) stack-এর ভেতরে AWS::CloudFormation::Stack resource থাকে, যারা S3-এ রাখা child template দেখায়।
  • Child-গুলো parent-এর সঙ্গেই তৈরি, update আর delete হয়, এক ইউনিট হিসেবে; মান যায় parameter দিয়ে, ফেরে !GetAtt Child.Outputs.Name দিয়ে।
  • Child template একবার বদলালে, যে parent সেটা ব্যবহার করে সবাই পরের update-এ বদলটা পায়।
  • Update আর delete করো root-কে, child-কে সরাসরি না।
  • কাজে লাগে: একটা component (standard load balancer, শক্তপোক্ত bucket) অনেক stack-এর ভেতরে আবার ব্যবহার করতে, আর ৫০০ resource-এর সীমা পেরোতে।

মোটা দাগের নিয়ম: একটা component বারবার ব্যবহার → nested stack; আলাদা আলাদা জীবনের stack-এর মধ্যে output ভাগাভাগি → export আর ImportValue। ফেব্রুয়ারি ২০২৫ থেকে stack refactoring দিয়ে চালু resource নতুন করে না বানিয়েই এক stack থেকে আরেক stack-এ সরানো যায় (বা logical ID-র নাম বদলানো যায়), যেটা একটা বিশাল stack ভাঙার সময় কাজে আসে।

Stack-এর মধ্যে মান ভাগাভাগি

Export আলাদা আলাদা জীবনের stack-গুলোকে জোড়ে; nested stack হলো একটাই stack-এর টুকরো। তফাতটা বোঝা যায় কিছু delete করতে গেলে।

পরিস্থিতি

একটা team export করে, অনেক team import করে, যার যার সময়মতো।

Network stackVPC ID export করে
Orders stack
Payments stack

Exports

wallet-network-VpcId

vpc-0abc1234

wallet-network-PrivateSubnets

subnet-0a…, subnet-0b…

ধাপ 1 / 2
1

Network team-এর stack-এ একটা output আছে, Export Name wallet-network-VpcId। Export-এর নাম account আর Region-এর মধ্যে অনন্য হতে হয়।

#StackSets: এক template, অনেক account আর Region

একটা stack থাকে একটা account আর একটা Region-এ। ৪০টা account-ওয়ালা একটা প্রতিষ্ঠান যদি সবখানে একই guardrail চায় (একটা CloudTrail trail, একটা Config recorder, security team-এর জন্য একটা IAM role, একটা budget alarm), তাহলে লাগবে ৪০ × Region সংখ্যক stack। CloudFormation StackSets এক জায়গা থেকে সবগুলো বানায়, update করে আর মোছে:

  • StackSet বানানো হয় একটা administrator account-এ; সেখানে এটা একটা Regional resource। তুমি বেছে নাও target account (বা Organizations-এর OU) আর Region। প্রতিটা account আর Region-এর জোড়া একটা stack instance, যার পেছনে ওই account-এ একটা সাধারণ stack।
  • StackSet update করলে তার সব stack instance update হয়; কোনো একটা stack instance-কে আলাদা template দেওয়া যায় না (শুধু আলাদা parameter override দেওয়া যায়)।
  • Self-managed permission: IAM role তুমি নিজে বানাও, administrator account-এ AWSCloudFormationStackSetAdministrationRole আর প্রতিটা target account-এ AWSCloudFormationStackSetExecutionRole। যেকোনো account-এ চলে, organization-এর বাইরের account-এও।
  • Service-managed permission: AWS Organizations-এ trusted access থাকলে StackSets নিজেই role বানিয়ে নেয়। তুমি OU বেছে দাও, administrator হয় management account বা একটা delegated administrator, আর automatic deployment পরে OU-তে যোগ দেওয়া প্রতিটা account-এ stack বানিয়ে দেয় (আর কোনো account বেরিয়ে গেলে মুছে দেয় বা রেখে দেয়)। Management account-এ নিজে stack deploy হয় না।
  • Deployment-এর option: maximum concurrent accounts (সংখ্যা বা শতাংশ), প্রতি Region-এ failure tolerance (কতটা ব্যর্থতার পর operation থামবে), Region concurrency (sequential, যেটা default, বা parallel) আর Region-এর ক্রম।

এক template, সব account

একটা ISP তার workloads OU-র প্রতিটা account-এ, Singapore আর Mumbai-তে, একই guardrail stack পাঠায়, একটাই StackSets administrator account থেকে।

পরিস্থিতি

Service-managed permission: OU বেছে দাও, role আর stack StackSets নিজেই বানায়।

Workloads OU
Admin account
StackSetsorg-guardrails
Billing
Portal
Monitoring
create-stack-set
ধাপ 1 / 4
1

Security team service-managed permission দিয়ে StackSet বানায়। Organizations-এর trusted access থাকায় StackSets প্রতিটা member account-এ দরকারি role নিজেই বানিয়ে নেয়।

#Custom resource: যখন resource type-ই নেই

কখনো কখনো stack-কে এমন কিছু করতে হয় যার কোনো resource type CloudFormation-এ নেই: on-premises কোনো system থেকে একটা মান খুঁজে আনা, delete-এর আগে একটা S3 bucket খালি করা, নতুন server-কে third-party কোনো monitoring tool-এ নিবন্ধন করা। একটা custom resource (Type: Custom::EmptyBucket) ServiceToken দিয়ে একটা Lambda function (বা SNS topic) দেখায়। ওই resource-এর প্রতিটা create, update আর delete-এ CloudFormation সেটাকে ডাকে, request-এর ধরন আর property-সহ, সঙ্গে একটা pre-signed S3 URL; তোমার code কাজটা করে আর ওই URL-এ একটা SUCCESS বা FAILED উত্তর পাঠাতেই হবে। যা ডেটা ফেরত দেয়, !GetAtt দিয়ে পড়া যায়। Function উত্তর না দিয়ে crash করলে stack ServiceTimeout (default আর সর্বোচ্চ এক ঘণ্টা, ২০২৪-এর property) পর্যন্ত অপেক্ষা করে, তারপর ব্যর্থ হয়। বারবার ব্যবহারের extension-এর জন্য আছে registry resource type-ও (third-party আর তোমার নিজের, যেমন একটা Datadog monitor), যেগুলোর type ঠিক করা থাকে আর যাচাই হয়।

#CloudFormation-এর আশেপাশের tool

Toolএটা কীCloudFormation-এর সঙ্গে সম্পর্ক
AWS Infrastructure Composerএকটা visual designer: canvas-এ resource টেনে এনে জোড়া দাও, template সে লিখে দেয়; চালু template-এর diagram-ও আঁকতে পারে (slide-এর WordPress stack)অক্টোবর ২০২৪-এ Application Composer থেকে নাম বদল; CloudFormation console-এ পুরোনো CloudFormation Designer-এর জায়গা নিয়েছে। এখনকার অবস্থা (নভেম্বর ২০২৬): ২৯ অক্টোবর ২০২৬ থেকে নতুন customer নেয় না, আলাদা console-টা ৭ ডিসেম্বর ২০২৬-এ বন্ধ হয়ে যাবে; একই visual editor Visual Studio Code-এর AWS Toolkit-এ থাকছে, আর CloudFormation console নিজের built-in visual editor পাচ্ছে
AWS CDKTypeScript, Python, Java, C# বা Go-তে infrastructure (১.৩ lesson)cdk synth একটা CloudFormation template তৈরি করে; cdk deploy সেটা stack হিসেবে deploy করে
AWS SAMServerless resource-এর ছোট syntax (১৫.১ lesson)Transform: AWS::Serverless-2016-10-31-ওয়ালা template; CloudFormation AWS::Serverless::Function-কে পূর্ণ resource-এ খুলে দেয়
Elastic BeanstalkWeb app-এর platform (৯.৪ lesson)প্রতিটা environment একটা CloudFormation stack, যেটা Beanstalk তোমার হয়ে লেখে
TerraformHashiCorp-এর multi-cloud IaC tool, HCL-এ লেখা, নিজস্ব state file সহCloudFormation না: সরাসরি AWS API ডাকে। পরীক্ষার AWS-নিজস্ব উত্তর CloudFormation
CloudFormation GuardPolicy as code: “প্রতিটা bucket-এ encryption থাকতে হবে”-র মতো rule, pipeline-এ cfn-guard validate দিয়ে যাচাইAWS Config-এর custom policy rule-এও ব্যবহার হয় (১৯.৭ lesson), আর CloudFormation-এর hook-এ, যা deploy-এর আগেই নিয়মভাঙা resource আটকায় (২০.৩ lesson)
IaC generator (ফেব্রুয়ারি ২০২৪)Account-এ আগে থেকে থাকা resource scan করে তাদের থেকে template বানায়সেগুলো একটা stack-এ import করো, বা template-টা CDK app বানাও (cdk migrate)
Git sync (নভেম্বর ২০২৩)একটা stack-কে GitHub, GitLab বা Bitbucket repository-র একটা template আর deployment file-এর সঙ্গে জুড়ে দেয়Branch-এ push করলেই stack update

#কোন প্রশ্নে কোন উত্তর

প্রশ্নে যা বলেউত্তরকাছাকাছি ভুল উত্তর আর কেন হারে
Infrastructure as code, বারবার একই environmentCloudFormationElastic Beanstalk একটা app platform deploy করে, যেকোনো infrastructure না; OpsWorks বন্ধ হয়ে গেছে
TypeScript বা Python-এ IaCAWS CDK (CloudFormation বানায়)SAM হলো serverless-এর জন্য YAML
বদল preview, কোন resource replace হবেChange setDrift detection চালু অবস্থা আর template মেলায়
কেউ হাতে resource বদলেছেDrift detectionChange set দুটো template মেলায়; CloudTrail বলে কে করেছে, template থেকে কতটা সরে গেছে তা না
Stack delete হলেও database থাকুকDeletionPolicy: Retain বা SnapshotTermination protection পুরো delete আটকায়; stack policy শুধু update-এর জন্য
Stack দিয়ে production database-এর update আটকাওStack policyUser-এর IAM stack-এর ভেতরের logical resource আলাদা করে চেনে না
ভুল করে stack delete হওয়া আটকাওTermination protectionDeletionPolicy resource রাখে, কিন্তু stack তো মুছেই যায়
Developer deploy করবে, কিন্তু সরাসরি EC2 বানাতে পারবে নাService role + iam:PassRoleDeveloper-কে ec2:* দিলে least privilege ভাঙে
অনেক account আর Region-এ একই stack, নতুন account-এ নিজে থেকেইStackSets, service-managed, automatic deploymentNested stack এক account আর এক Region-এই থাকে
অনেক স্বাধীন stack-এর সঙ্গে VPC ID ভাগাভাগিExport-সহ output + Fn::ImportValueNested stack জীবনগুলো একসঙ্গে বেঁধে ফেলে
অনেক template-এ একটা standard component আবার ব্যবহারNested stack (বা module)Copy-paste করলে সময়ের সঙ্গে আলাদা হয়ে যায়
Instance-এর software install হওয়া পর্যন্ত অপেক্ষাCreationPolicy + cfn-signal (cfn-init-সহ)DependsOn শুধু resource তৈরি হওয়া পর্যন্ত অপেক্ষা করে
এমন কাজ যার resource CloudFormation-এ নেইCustom resource (Lambda দিয়ে)Stack-এর বাইরের script stack-এর জীবনের অংশ না
চালু resource থেকে templateIaC generatorDrift detection শুধু stack-এ থাকা resource মেলায়

#কোথায় গোলমাল হয়

  • Stack ROLLBACK_COMPLETE-এ আটকে: প্রথমবার তৈরিই ব্যর্থ হয়েছে। এটা update করা যায় না; প্রথম CREATE_FAILED event পড়ো, stack delete করো, ঠিক করো, আবার বানাও। পরের বার debug-এর জন্য resource রাখতে --disable-rollback দাও।
  • UPDATE_ROLLBACK_FAILED: rollback কিছু একটা ফিরিয়ে আনতে পারেনি, প্রায়ই কারণ কেউ হাতে কোনো resource মুছেছে বা বদলেছে। হাতে ঠিক করো, তারপর update rollback চালিয়ে যাও (resource বাদ দেওয়া একেবারে শেষ উপায়)।
  • S3 bucket-এ DELETE_FAILED: bucket খালি না। খালি করো (বা একটা custom resource করুক), অথবা ওই resource রেখে দিয়ে আবার delete করো।
  • একটা update database replace করে ফেলেছে: কেউ এমন property বদলেছে যেটায় replacement লাগে। Change set-এর Replacement কলাম সবসময় পড়ো; database রক্ষা করো stack policy, DeletionPolicy: Snapshot আর UpdateReplacePolicy: Snapshot দিয়ে।
  • “Export … cannot be deleted as it is in use by …”: অন্য কোনো stack এটা import করছে। আগে ব্যবহারকারীদের থেকে import সরাও।
  • তৈরি ঝুলে থাকে, তারপর CreationPolicy-র timeout-এ ব্যর্থ: cfn-signal চলেইনি (script-এ ভুল, helper script নেই), অথবা NAT বা endpoint ছাড়া private subnet থেকে CloudFormation-এ পৌঁছাতে পারেনি।
  • iam:PassRole-এ AccessDenied: user stack বানাতে পারে, কিন্তু ওই role pass করতে পারে না। নির্দিষ্ট role ARN-এ iam:PassRole allow করো।
  • তৈরির সময় EC2 থেকে AccessDenied, তারপর rollback: কোনো service role দেওয়া হয়নি আর user-এর resource-এর permission নেই, অথবা service role-এর নিজেরই নেই।
  • “Role … is invalid or cannot be assumed”: role-এর trust policy cloudformation.amazonaws.com-কে বিশ্বাস করে না।
  • Drift বলছে IN_SYNC, অথচ system-এ গোলমাল: বদলানো property template-এ কখনো লেখা হয়নি, resource-টা stack-এর বাইরে, অথবা এমন nested stack-এ যেটা তুমি যাচাই করোনি।
  • StackSet operation মাঝপথে থেমে গেছে: কোনো Region-এ ব্যর্থতা failure tolerance পেরিয়ে গেছে; বাকি Region বাতিল। ব্যর্থ account-গুলো ঠিক করে operation আবার চালাও; ততক্ষণ stack instance দেখাবে OUTDATED।
  • একটা custom resource এক ঘণ্টা ঝুলে আছে: Lambda function কখনো উত্তর পাঠায়নি (crash, অথবা S3-এ যাওয়ার network পথ নেই)। সবসময় finally block-এ উত্তর পাঠাও, আর ServiceTimeout ছোট করে দাও।

#System design-এ

  • স্তরে স্তরে stack: network (VPC, subnet, endpoint) → shared service (security group, KMS key) → application। নিচের স্তর export করে, ওপরের স্তর import করে, আর প্রতিটা স্তরের নিজস্ব মালিক আর pipeline।
  • Pipeline: template-এর বদল যায় Git → pipeline cfn-lint আর Guard চালায় → একটা change set বানায় → একজন মানুষ অনুমোদন দেয় → execute। Production stack-এ থাকে termination protection, একটা stack policy আর একটা service role।
  • Multi-account landing zone: Control Tower আর StackSets প্রতিটা account-এ guardrail পৌঁছে দেয়; account-নির্দিষ্ট stack deploy হয় service role-সহ pipeline দিয়ে।
  • Disaster recovery: একই template, pipeline দিয়ে recovery Region-এ deploy, AMI ID আর parameter আসে Parameter Store থেকে (২৩.১ lesson)।
  • খরচ নিয়ন্ত্রণ: dev stack প্রতি সন্ধ্যায় মুছে প্রতি সকালে আবার বানানো (ঢাকায় রবিবার থেকে বৃহস্পতিবার), আর খরচের report stack-name tag ধরে ভাগ করা।

#নিজে করে দেখো

ap-southeast-1-এ AWS CLI v2। “Template-এর গঠন” অংশের template-টা wallet.yaml নামে save করো। Resource চলার সময় সামান্য খরচ হয়; শেষে stack delete করো (bucket ইচ্ছে করেই রেখে দেওয়া হয়, তাই সেটা হাতে মোছো)।

# 1. Check the syntax and see the parameters
aws cloudformation validate-template --template-body file://wallet.yaml \
  --query 'Parameters[].ParameterKey'
# [ "Env", "VpcId", "LatestAmi" ]

# 2. Create (or update) the stack in one command; deploy builds and executes a change set
aws cloudformation deploy --stack-name wallet-dev --template-file wallet.yaml \
  --parameter-overrides Env=dev VpcId=vpc-0abc1234def567890 \
  --tags Project=wallet
# Waiting for changeset to be created..
# Waiting for stack create/update to complete
# Successfully created/updated stack - wallet-dev

aws cloudformation describe-stacks --stack-name wallet-dev \
  --query 'Stacks[0].[StackStatus,Outputs[0].ExportName]'
# [ "CREATE_COMPLETE", "wallet-dev-BucketArn" ]

# 3. Preview a change: what if this stack switched Env to staging? Create a named change set
aws cloudformation create-change-set --stack-name wallet-dev --change-set-name to-staging \
  --use-previous-template --parameters ParameterKey=Env,ParameterValue=staging \
  ParameterKey=VpcId,UsePreviousValue=true ParameterKey=LatestAmi,UsePreviousValue=true
aws cloudformation describe-change-set --stack-name wallet-dev --change-set-name to-staging \
  --query 'Changes[].ResourceChange.[Action,LogicalResourceId,Replacement]' --output table
# |  Modify |  UploadBucket |  True   |   <- BucketName contains Env: a NEW bucket (old one retained)
# |  Modify |  WebSg        |  True   |   <- GroupDescription cannot change in place
# |  Modify |  WebServer    |  False  |   <- instance type: stop and start, same instance
# Surprised by two replacements? That is exactly what change sets are for. Throw it away:
aws cloudformation delete-change-set --stack-name wallet-dev --change-set-name to-staging

# 4. Make drift on purpose: open port 22 in the console or with the CLI, then detect it
aws ec2 authorize-security-group-ingress --group-id sg-0123456789abcdef0 \
  --protocol tcp --port 22 --cidr 0.0.0.0/0
ID=$(aws cloudformation detect-stack-drift --stack-name wallet-dev --query StackDriftDetectionId --output text)
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id $ID \
  --query '[DetectionStatus,StackDriftStatus]'
# [ "DETECTION_COMPLETE", "DRIFTED" ]
aws cloudformation describe-stack-resource-drifts --stack-name wallet-dev \
  --stack-resource-drift-status-filters MODIFIED \
  --query 'StackResourceDrifts[].[LogicalResourceId,PropertyDifferences[0].DifferenceType]'
# [ [ "WebSg", "ADD" ] ]

# 5. Protect the stack from deletion
aws cloudformation update-termination-protection --stack-name wallet-dev \
  --enable-termination-protection

# 6. A stack created with a service role (needs iam:PassRole on it)
aws cloudformation create-stack --stack-name app-payments-api \
  --template-url https://templates-example.s3.amazonaws.com/payments-api.yaml \
  --role-arn arn:aws:iam::111122223333:role/cfn-app-deployer
# An error occurred (AccessDenied) ... is not authorized to perform: iam:PassRole ...   <- without PassRole

# 7. A StackSet for the whole organization, with automatic deployment to new accounts
aws cloudformation create-stack-set --stack-set-name org-guardrails \
  --template-body file://guardrails.yaml --capabilities CAPABILITY_NAMED_IAM \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false
aws cloudformation create-stack-instances --stack-set-name org-guardrails \
  --deployment-targets OrganizationalUnitIds=ou-ab12-cdef3456 \
  --regions ap-southeast-1 ap-south-1 \
  --operation-preferences MaxConcurrentPercentage=25,FailureToleranceCount=1,RegionConcurrencyType=PARALLEL

# 8. Clean up (turn termination protection off first)
aws cloudformation update-termination-protection --stack-name wallet-dev --no-enable-termination-protection
aws cloudformation delete-stack --stack-name wallet-dev
aws cloudformation wait stack-delete-complete --stack-name wallet-dev

Console-এও চেষ্টা করো: stack খুলে template-এর visual view খুলে diagram দেখো (AWS console-এর নিজের visual editor না আনা পর্যন্ত এর নাম View in Infrastructure Composer), আর Drifts tab-এ WebSg-এর প্রত্যাশিত আর আসল JSON পাশাপাশি মিলিয়ে দেখো।

#সারসংক্ষেপ

মূল কথা

  • CloudFormation = AWS-এর infrastructure as code: একটা template (JSON বা YAML) resource বর্ণনা করে, CloudFormation সেগুলো একটা stack হিসেবে নির্ভরতার ক্রমে বানায়, যেখানে সম্ভব একসঙ্গে, আর একসঙ্গেই মোছে। AWS resource type-এর জন্য বিনা পয়সায়।
  • Template-এর section: Parameters (type, AllowedValues, SSM parameter type), Mappings, Conditions, Resources (একমাত্র বাধ্যতামূলক), Export-সহ Outputs। Function: Ref, GetAtt, Sub, Join, FindInMap, If, ImportValue; pseudo parameter AWS::Region, AWS::AccountId।
  • ক্রম: Ref/GetAtt দিয়ে implicit, DependsOn দিয়ে explicit। তৈরি ব্যর্থ হলে rollback হয়ে ROLLBACK_COMPLETE, যেটা শুধু delete করা যায়; update ব্যর্থ হলে ফেরে UPDATE_ROLLBACK_COMPLETE-এ। --disable-rollback debug-এর জন্য resource রেখে দেয়।
  • CreationPolicy + cfn-init + cfn-signal CloudFormation-কে software-এর জন্য অপেক্ষা করায়, শুধু instance-এর জন্য না।
  • Update হয় no interruption, some interruption বা replacement; change set আগেভাগে সেটা দেখায়।
  • রক্ষা: DeletionPolicy (Delete default, Retain, EBS, RDS, ElastiCache, Redshift, Neptune, DocumentDB-তে Snapshot; RetainExceptOnCreate), UpdateReplacePolicy, stack policy (update), termination protection (stack delete)।
  • Drift detection চালু resource আর template মেলায়: MODIFIED, DELETED; stack-এর বাইরের resource বা template-এ না লেখা property দেখে না।
  • Service role: CloudFormation সেটা assume করে, resource-এর permission তার কাছে; user-এর লাগে CloudFormation-এর permission আর iam:PassRole; role না থাকলে caller-এর নিজের permission ব্যবহার হয়।
  • Export + ImportValue স্বাধীন stack-এর মধ্যে মান ভাগ করে; nested stack এক জীবনের ভেতরে component আবার ব্যবহার করে; StackSets এক template অনেক account আর Region-এ পাঠায়, Organizations-এর মাধ্যমে service-managed permission আর automatic deployment-সহ।
  • আশেপাশে: custom resource (Lambda), Infrastructure Composer, CDK, SAM, Terraform (AWS-এর না), Guard আর hook, IaC generator, Git sync।