AWS ECS Start and Stop Schedule
หลังจากที่ได้เขียนวิธีตั้งเวลาเปิด/ปิด EC2 ไปแล้วนั้น สามารถตามได้ที่ link นี้เลยครับ
Scheduling For Start and Stop AWS EC2 — ตั้งเวลาเปิด/ปิด EC2 เพื่อประหยัดค่าใช้จ่ายกันเถอะ
วันนี้ก็มีวิธีไปใช้กับ Service ECS กัน โดยการตั้งเวลาเปิด/ปิด จะมี AWS Service ที่เกี่ยวข้องด้วยกัน 3 Service คือ CloudWatch, Lambda และ IAM มาเริ่มกันเลย
1.Create Lambda and configure permission
วิธี Create Lamba ก็เหมือนกับตอนที่ทำกับ EC2 นะครับ จะต่างกันที่ตัว code กับ permission สามารถดูได้ตาม link ด้านบน
ไปที่ service “Lamba” → กดปุ่ม “Create Function”
เลือก Author from scratch → ตั้งชื่อ Function name → Runtime Python 3.8 (เพราะเราจะใช้ python ในการเขียน script กัน) → Create a new role
ใส่ code python ตามนี้ โดย CLUSTERNAME คือชื่อ ECS cluser และ SERVICENAME คือชื่อของ ECS Service ที่ต้องการให้ทำงานตาม script
import boto3
import logging
import time
from datetime import datetime, timedeltalogger = logging.getLogger()
logger.setLevel(logging.INFO)#Create connection
client = boto3.client('ecs')
clientas = boto3.client('application-autoscaling')
#Define Cluster and Service
cluster = "CLUSTERNAME"
service_name = "SERVICENAME"
startmax = 2
startdesired = 1
stopmax = 0
stopdesired = 0
starttime = '01'
stoptime = '12'
resourceid = 'service/CLUSTERNAME/SERVICENAME'def lambda_handler(event, context):logger.info("Starting update ECS desired of {0} service in {1} cluster".format(service_name, cluster))
response = client.list_services(cluster=cluster)
serviceARN = response.get('serviceArns', [])
print("serviceARN is", serviceARN)
responses = client.list_tasks(cluster=cluster)
tasks = responses.get('taskArns', [])
print("taskARN is", tasks)
responsess = clientas.describe_scalable_targets(ServiceNamespace='ecs',ResourceIds=[resourceid])
print("Current ASG setting is", responsess)
#Convert CurrentTime to String and substring
now = datetime.now()
str_now = datetime.strftime(now, '%H')print("NOW=", str_now, "HH-UTC")
print("STARTTIME=", starttime, "HH-UTC")
print("STOPTIME=", stoptime, "HH-UTC")
#Check Start Time
if str_now == starttime:
if len(tasks) != 0:
print("task running is/are", len(tasks))
client.update_service(cluster=cluster, service=service_name, desiredCount=startdesired)
clientas.register_scalable_target(ServiceNamespace='ecs',ResourceId=resourceid,ScalableDimension='ecs:service:DesiredCount',MinCapacity=startdesired,MaxCapacity=startmax,)
print("Completed update ECS desired of service:", serviceARN, "to", startdesired)
responsess = clientas.describe_scalable_targets(ServiceNamespace='ecs',ResourceIds=[resourceid])
print("New ASG setting is", responsess)
else:
print("task running is", len(tasks))
client.update_service(cluster=cluster, service=service_name, desiredCount=startdesired)
clientas.register_scalable_target(ServiceNamespace='ecs',ResourceId=resourceid,ScalableDimension='ecs:service:DesiredCount',MinCapacity=startdesired,MaxCapacity=startmax,)
print("Completed update ECS desired of service:", serviceARN, "to", startdesired)
responsess = clientas.describe_scalable_targets(ServiceNamespace='ecs',ResourceIds=[resourceid])
print("New ASG setting is", responsess)
elif str_now == stoptime:
if len(tasks) != 0:
print("task running is/are", len(tasks))
client.update_service(cluster=cluster, service=service_name, desiredCount=stopdesired)
clientas.register_scalable_target(ServiceNamespace='ecs',ResourceId=resourceid,ScalableDimension='ecs:service:DesiredCount',MinCapacity=stopdesired,MaxCapacity=stopmax,)
print("Completed update ECS desired of service:", serviceARN, "to", stopdesired)
responsess = clientas.describe_scalable_targets(ServiceNamespace='ecs',ResourceIds=[resourceid])
print("New ASG setting is", responsess)
else:
print("task running is", len(tasks))
print("Task running is 0. Ignoring update ECS desired of service", serviceARN)
else:
print("This is not time. Ignoring update ECS desired of service", serviceARN)
Script นี้จะรวมทั้ง start และ stop ไว้ใน code ชุดเดียวกัน (เนื่องจากผู้เขียนขี้เกียจสร้าง Lambda กับ CloudWatch Event rule ขึ้นใหม่นั่นเอง ฮาๆ) โดย starttime คือชั่วโมงที่ต้องการ start และ stoptime คือชั่วโมงที่ต้องการ stop เช่น 08.00น. ก็จะใช้ 01 หรือ 19.00น. ใช้ 12 (อย่าลืมลบชั่วโมงด้วย 7 เพื่อแปลงเป็นเวลา UTC/GMT นะครับ)
จากนั้นไปเพิ่ม permission ให้กับ role ของ Lambda ที่เราสร้าง โดยไปที่ Tab “Configuration” → “Permissions” → คลิ๊กที่ “Role Name”
เพิ่ม Inline Policy ชื่อ allow-logging-update-ecs ตามนี้ได้เลย

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:DescribeServices",
"ecs:UpdateService",
"ecs:ListServices",
"ecs:ListTasks",
"application-autoscaling:DescribeScalableTargets",
"application-autoscaling:RegisterScalableTarget"
],
"Resource": [
"*"
]
}
]
}
2. Create CloudWatch Event Rule
วิธีสร้าง CloudWatch Event Rule ตามไปดูได้ที่ link นี้เลยครับ
Scheduling For Start and Stop AWS EC2 — ตั้งเวลาเปิด/ปิด EC2 เพื่อประหยัดค่าใช้จ่ายกันเถอะ
จะต่างกันตรงที่ cron เราจะรวม start กับ stop time ใส่เข้าไปด้วยกันเลย
0 01,12 ? * MON-FRI *

หลังจากสร้าง Event Rule เสร็จ ก็จะได้ rule ของเราขึ้นมาดังรูป

เท่านี้เราก็จะประหยัดค่าใช้จ่ายจากการเปิด ECS ทิ้งไว้เสียไปฟรีๆ และช่วยให้งาน operation ที่เราต้องมาทำให้มีความเป็น Automation มากขึ้น ไม่ต้องมานั่ง start/stop ทุกวัน เราก็จะดู SMART ขึ้นมาทันที :)
ยังมีวิธีเปลี่ยนวิธีทำงานหลายๆ อย่างให้เป็น Automation มากขึ้นอีกนะ เดี๋ยวว่างๆ จะมานั่งเขียนให้อ่านกันอีก ฝากติดตามกันเช่นเดิมนะครับ