วิธีบังคับปิด EC2 และ RDS กรณีมีค่าใช้จ่ายเกินกำหนด

วิธีบังคับปิด EC2 และ RDS กรณีมีค่าใช้จ่ายเกินกำหนด

ป้องกันค่าใช้จ่ายที่เพิ่มขึ้นโดยการปิดระบบ EC2/RDS โดยอัตโนมัติเมื่อค่าบริการ AWS เกินกว่าจำนวนที่กำหนดไว้

บทความนี้แปลมาจากบทความที่เป็นภาษาญี่ปุ่นที่ชื่อว่า AWS利用料金が一定の金額を上回ったらEC2/RDSを強制シャットダウンしたい โดยเจ้าของบทความนี้คือ คุณ 吉井亮

ผมมักจะได้ยินความต้องการที่อยากให้ทีมมีอิสระในการพัฒนาและทดสอบ แต่ก็ต้องการควบคุมค่าใช้จ่าย AWS ให้อยู่ในระดับที่เหมาะสม
และยังได้รับเสียงบ่นว่าแม้จะมีการแจ้งเตือนผ่าน Budgets แต่ยังไม่สามารถจัดการลดค่าใช้จ่ายได้

ดังนั้น ผมจึงได้สร้างระบบที่จะปิด EC2/RDS โดยอัตโนมัติเมื่อได้รับการแจ้งเตือนจาก Budgets

ภาพรวม

เมื่อค่าใช้จ่าย AWS (รายเดือน) ถึงจำนวนที่กำหนดไว้ล่วงหน้า ระบบจะทำการปิด EC2 instances, RDS instances และ Aurora clusters ที่กำลังทำงานอยู่
เมื่อกำหนดวงเงินสูงสุดของค่าใช้จ่าย AWS และค่าเกณฑ์สามระดับ แล้วทำการ deploy CloudFormation template จะมีการสร้างทรัพยากรดังต่อไปนี้

Cost saver-1

ข้อควรระวัง

ระบบจะทำการปิด EC2/RDS ที่กำลังทำงานอยู่โดยบังคับ

แม้จะปิดระบบแล้ว ยังมีทรัพยากรบางอย่างที่ยังคงมีค่าใช้จ่าย เช่น Storage ต่างๆ และ EIP
ซึ่งต้องจัดการทรัพยากรเหล่านี้ด้วยตนเอง

RDS จะกลับมาเปิดทำงานโดยอัตโนมัติหลังจากปิดไป 8 วัน
หากไม่ต้องการให้เกิดค่าใช้จ่าย กรุณาลบด้วยตนเอง

การติดตั้งสภาพแวดล้อม

ให้ clone หรือดาวน์โหลดจากที่นี่

การดำเนินการทั้งหมดอ้างอิงจากการใช้งานบน Linux Bash
หากใช้งานบน Windows หรือระบบอื่นที่ไม่ใช่ Bash กรุณาปรับเปลี่ยนคำสั่งตามความเหมาะสม หรือใช้ CloudShell แทน

การตั้งค่าตัวแปรสภาพแวดล้อม (Environment Variables)

จะทำการตั้งค่าตัวแปรสภาพแวดล้อม

ชื่อตัวแปรสภาพแวดล้อม ค่า
MYS3BUCKETNAME ชื่อ S3 bucket สำหรับอัปโหลดไฟล์ lambda zip
MYS3BUCKETSTACKNAME ชื่อ CloudFormation stack สำหรับสร้าง S3 bucket ข้างต้น
DEPLOYSTACKNAME ชื่อ CloudFormation stack สำหรับ deploy สภาพแวดล้อมทั้งหมด
Amount วงเงินสูงสุดของค่าใช้จ่ายรายเดือนโดยหน่วยคือ USD (กรณีต้องการทดลอง อย่าระบุน้อยกว่าค่าใช้จ่ายปัจจุบัน เนื่องจากตอนที่ Cloudformation สร้าง resource นั้น budgets จะถูกสร้างขึ้นมาก่อนและจะทำการ trigger ทันทีก่อนที่ lambda จะสร้างเสร็จ)
Actual1 เกณฑ์ระดับที่ 1 (คิดเป็น % ของวงเงินสูงสุด)
Actual2 เกณฑ์ระดับที่ 2 (คิดเป็น % ของวงเงินสูงสุด)
Actual3 เกณฑ์ระดับที่ 3 (คิดเป็น % ของวงเงินสูงสุด)
EmailAddress อีเมลที่จะรับการแจ้งเตือนเมื่อค่าใช้จ่ายเกินเกณฑ์

รันคำสั่งต่อไปนี้โดยแก้ไขค่าให้เหมาะสมกับการใช้งานของคุณ

cd cfn
export MYS3BUCKETNAME=<your bucket name>
export MYS3BUCKETSTACKNAME=<your stack name>
export DEPLOYSTACKNAME=<your stack name>
export Amount=100
export Actual1=50
export Actual2=75
export Actual3=100
export EmailAddress=<your email address>

Create S3 Bucket lambda upload

สร้าง S3 bucket สำหรับเก็บโค้ด lambda ที่ zip ไว้ในเครื่องของคุณ
รันคำสั่งต่อไปนี้ในเทอร์มินัลเดียวกับที่ตั้งค่าตัวแปรสภาพแวดล้อมไว้ เพื่อสร้าง S3 bucket

aws cloudformation deploy \
  --stack-name ${MYS3BUCKETSTACKNAME} \
  --template-file lambda-bucket.yml \
  --parameter-overrides S3BucketName=${MYS3BUCKETNAME}

ตรวจสอบว่า S3 bucket ได้ถูกสร้างขึ้นเรียบร้อยแล้ว จากนั้นดำเนินการขั้นตอนต่อไป

CloudFormation Package

ทำการแพ็คเกจโค้ด Lambda

aws cloudformation package \
    --template-file aws-cost-saver.yml \
    --s3-bucket ${MYS3BUCKETNAME} \
    --output-template-file packaged-template.yml

CloudFormation Deploy

หากไฟล์ packaged-template.yml ถูกสร้างขึ้นแล้ว
ให้ทำการ deploy ด้วยคำสั่งต่อไปนี้

aws cloudformation deploy \
  --template-file packaged-template.yml \
  --stack-name ${DEPLOYSTACKNAME} \
  --parameter-overrides Amount=${Amount} EmailAddress=${EmailAddress} Actual1=${Actual1} Actual2=${Actual2} Actual3=${Actual3} \
  --capabilities CAPABILITY_NAMED_IAM

ทรัพยากรที่จะถูกสร้างขึ้น

ตรวจสอบทรัพยากรที่ถูกสร้างขึ้นผ่านทาง Management Console

Budgets

Cost saver-2

Lambda

Cost saver-3

SNS

Cost saver-4

สรุป

ผมได้สร้าง Function สำหรับปิดระบบ EC2 และ RDS ซึ่งมักเป็นส่วนที่มีสัดส่วนค่าใช้จ่ายสูงใน AWS

ระบบนี้ถูกออกแบบมาสำหรับใช้ในสภาพแวดล้อมที่มีงบประมาณจำกัด เช่น sandbox environment หรือ development environment

เนื่องจากเป็นการปิดระบบแบบบังคับ กรุณาปรึกษาและตกลงกับทีมก่อนนำไปใช้งาน เพื่อป้องกันปัญหาความขัดแย้งที่อาจเกิดขึ้นในภายหลัง

บทความต้นฉบับ

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.