Coding Gun

รู้จักกับ CloudFormation

CloudFormation คือ Infrastructure as Code(IaC) บน AWS ซึ่งเราสามารถสร้าง Resources ต่างๆขึ้นมาใช้งานได้ด้วยการเขียน Cloudformation Template

ข้อดีของ CloudFormation

CloudFormation vs Terraform

AWS CloudFormation และ Terraform เป็น Infrastructure as Code (IaC) ที่ช่วยให้เราสามารถสร้างและจัดการทรัพยากรบน Cloud ได้แบบอัตโนมัติทั้งคู่ แต่มีความแตกต่างกันในหลายด้านดังนี้

Feature AWS CloudFormation Terraform
ผู้พัฒนา AWS HashiCorp
รองรับ Cloud Provider AWS เท่านั้น รองรับหลายแพลตฟอร์ม (AWS, GCP, Azure, Kubernetes ฯลฯ)
รูปแบบไฟล์ (Syntax) JSON / YAML HashiCorp Configuration Language (HCL)
State Management จัดเก็บ State โดย AWS (ไม่ต้องดูแลเอง) จัดเก็บ State เอง หรือใช้ Terraform Cloud / Remote Backend
การรองรับ Multi-Cloud ❌ ไม่รองรับ ✅ รองรับหลายแพลตฟอร์ม
การประมวลผล สร้าง Stack และอัปเดตผ่าน Change Set ใช้ Plan และ Apply

ข้อดีและข้อเสีย

เปรียบเทียบข้อดีและข้อเสียของ CloudFormation และ Terraform ดังตารางต่อไปนี้

Feature CloudFormation Terraform
✅ ใช้งานง่าย ใช้งานผ่าน AWS Console ได้ง่าย ต้องติดตั้งและเรียนรู้ CLI
✅ บริหารจัดการ State AWS ดูแลให้ ต้องจัดการเอง (S3, Terraform Cloud)
✅ รองรับ Multi-Cloud ❌ ไม่รองรับ ✅ รองรับ AWS, GCP, Azure ฯลฯ
✅ รองรับ Reusability ❌ ซับซ้อนกว่า (Nested Stack) ✅ แยก Modules ได้ง่าย
✅ รองรับ Automation ✅ ใช้ร่วมกับ AWS Service ได้ดี ✅ ทำงานร่วมกับ CI/CD ได้ดี

องค์ประกอบของ CloudFormation

Cloud Formation ประกอบไปด้วยส่วนประกอบหลักๆที่เราต้องรู้จักดังต่อไปนี้

  1. Template – ไฟล์ที่กำหนดทรัพยากรต่างๆ ที่ต้องการสร้าง (เขียนด้วย JSON หรือ YAML ก็ได้)
  2. Stack – การ Deploy หรือสร้าง Resources บน AWS จากเนื้อหาที่เขียนไว้ใน Template
  3. Change Set – ความแตกต่างของ Resources ที่สร้างไว้แล้วหรือมีอยู่ ณ ปัจจุบันกับสิ่งที่เขียนไว้ใน Template(การเปลี่ยนแปลงต่างๆที่เกิดขึ้นเมื่อเรา Deploy Template นี้)

วิธีการใช้งาน CloudFormation เบื้องต้น

เรามาดูวิธีการใช้งาน CloudFormation โดยจะแยกออกเป็น 2 ตัวอย่าง

  1. การสร้าง S3 Bucket
  2. การสร้าง EC2 Instance

ตัวอย่างการสร้าง S3 Bucket

สร้าง Cloudformation template

อันดับแรกให้เริ่มจากการสร้าง CloudFormation Template ขึ้นมาก่อน โดยระบุรายการของ AWS Resources ที่ต้องการสร้าง ซึ่งในตัวอย่างนี้เราจะสร้าง S3 Bucket ขึ้นมาใหม่

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: my-simple-bucket-12345

2. Deploy CloudFormation Template

ซึ่งวิธีการ Deploy เราจะแยกออกเป็น 2 วิธีดังนี้

  1. Deploy ผ่านทาง AWS Console
  2. Deploy ผ่านทาง AWS CLI
2.1 Deploy CloudFormation Template ผ่าน AWS Console
  1. ไปที่ AWS Management Console -> CloudFormation
  2. คลิก Create Stack
  3. เลือก “Template is ready” -> Upload ไฟล์ YAML หรือ JSON
  4. ตั้งชื่อ Stack เช่น DemoS3Bucket
  5. คลิก Next -> Review -> Create Stack
  6. รอให้สถานะเปลี่ยนเป็น CREATE_COMPLETE
  7. เข้าไปที่หน้า list รายการของ S3 Bucket เพื่อตรวจสอบว่าได้ S3 Bucket ใหม่ที่มีชื่อว่า my-simple-bucket-12345 หรือไม่
2.2 Deploy Cloudformation Template ผ่าน AWS CLI
  1. เปิด Terminal หรือ Command Prompt
  2. ใช้คำสั่งเพื่อสร้าง Stack:
    aws cloudformation create-stack --stack-name MyFirstStack \
        --template-body file://template.yaml
    
  3. เราสามารถตรวจสอบสถานะของ Stack ที่ได้สร้างขึ้นได้ โดยใช้คำสั่ง
    aws cloudformation describe-stacks --stack-name MyFirstStack
    
  4. หลังจากนั้นเข้าไปที่หน้า list รายการของ S3 Bucket เพื่อตรวจสอบดูว่ามี S3 Bucket ที่ชื่อว่า my-simple-bucket-12345 เพิ่มเข้ามาหรือไม่

โครงสร้างของ CloudFormation Template

CloudFormation Template มีองค์ประกอบหลักๆ ดังนี้

Section Description
AWSTemplateFormatVersion ระบุเวอร์ชันของ CloudFormation (เช่น 2010-09-09)
Description คำอธิบายของ Stack
Parameters กำหนดค่าตัวแปรให้ Template
Mappings กำหนดค่าคงที่ต่างๆ เช่น AMI ID ในแต่ละ region
Conditions กำหนดเงื่อนไข เพื่อสร้างหรือไม่สร้าง Reources
Resources ระบุทรัพยากรที่ต้องการสร้าง (จำเป็นต้องมี)
Outputs คืนค่าผลลัพธ์หลังจากสร้าง Stack สำเร็จ เช่น DNS ของ EC2 Instance ที่ได้สร้างขึ้น

การ Update Stack

หากต้องการ update stack ที่มีอยู่ เราจะต้องทำตามขั้นตอนต่างๆ ดังนี้

  1. แก้ไขไฟล์ Template
  2. ทำการ Update Stack ด้วยคำสั่ง
    aws cloudformation update-stack --stack-name MyFirstStack \
        --template-body file://template.yaml
    
  3. ใช้ Change Set เพื่อตรวจสอบก่อน Update
    aws cloudformation create-change-set --stack-name MyFirstStack \
        --template-body file://template.yaml \
        --change-set-name MyChangeSet
    
  4. ตรวจสอบ Change Set เพื่อระบุ Resources ที่ต้องสร้างเพิ่ม, แก้ไข หรือทำลาย
    aws cloudformation describe-change-set --change-set-name MyChangeSet --stack-name MyFirstStack
    
  5. Approve การ Update ครั้งนี้ด้วยคำสั่ง
    aws cloudformation execute-change-set --change-set-name MyChangeSet --stack-name MyFirstStack
    

ตัวอย่างการสร้าง EC2 ด้วย CloudFormation

ในตัวอย่างที่ 2 นี้เราจะสร้าง EC2 Instance ขึ้นมาใหม่ผ่านทาง CloudFormation Template โดยเริ่มจากการสร้าง Template ขึ้นมาเหมือนเดิม ดังนี้

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0abcdef1234567890
      KeyName: MyKeyPair
      SecurityGroups:
        - default

การใช้ Parameters

เราสามารถทำให้ Template ของเรายืดหยุ่นมากขึ้นได้ด้วยการรับ Parameters เข้ามาแบบนี้

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  InstanceType:
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t2.small
      - t2.medium
    Description: "เลือกประเภทของ EC2 instance"

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: ami-0abcdef1234567890
      KeyName: MyKeyPair

ซึ่งก็จะเหมือนกับการใช้งาน Functions ถ้าเรากำหนด Parameters ไว้มากเท่าไหร่ การทำงานของ Function ของเราก็จะยืดหยุ่นมากขึ้น ในตัวอย่างนี้เราสามารถเลือกขนาดของ EC2 Instance ได้ โดยมีทางเลือกอยู่ 3 ทางด้วยกันคือ t2.micro, t2.small และ t2.medium


Output

หลังจากที่เราสร้าง Resources ขึ้นมาเรียบร้อยแล้ว ถ้าเราอยากให้นำ Metadata ของ Resources ที่ได้สร้างขึ้นออกมาแสดงผล เราจะ Output นี่แหละ ยกตัวอย่างเช่น ถ้าเราต้องการให้นำชื่อของ S3 Bucket ออกมาแสดงผล เราจะต้องระบุ Output ลงใน Tempalte แบบนี้

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: my-bucket-12345

Outputs:
  BucketName:
    Description: "ชื่อของ S3 Bucket"
    Value: !Ref MyS3Bucket

หรือถ้าต้องการดึงออกไปใช้งานด้วย Command-line จะต้องใช้คำสั่ง

aws cloudformation describe-stacks --stack-name MyStack \
    --query "Stacks[0].Outputs"

Delete Stack

หลังจากที่เราไม่ใช้ Resources เหล่านี้แล้ว เราสามารถลบออกได้ด้วยคำสั่ง Delete ซึ่งนี่จะเป็นอีกหนึ่งข้อดีของ CloudFormation เลยคือ เราสามารถสร้างและลบ Resources ทิ้งได้ตลอดเวลา

aws cloudformation delete-stack --stack-name MyFirstStack

รอสถานะเปลี่ยนเป็น DELETE_COMPLETE เพื่อยืนยันว่าการลบเสร็จสมบูรณ์


สรุป

Phanupong Permpimol
Follow me