iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0
Build on AWS

最適合小型工作室精打細算的服務使用法系列 第 22

Day 22 - 讓 EC2 準時上下班,不再加班爆肝:EventBridge + Lambda 自動開關機指南

  • 分享至 

  • xImage
  •  

前一陣子我們才聊過怎麼讓 RDS 保持關機狀態,結果隔壁的 EC2 不開心了:「為什麼只有資料庫可以關機?我難道就該 24 小時待命嗎?」

在地端時代,伺服器就像老派工程師,開機就不敢關,因為誰知道下次能不能再活過來?一按電源鍵,可能要等到 IT 部門集體唸經才會開得起來。

不過搬到雲端後,遊戲規則變了:只要開機 = 錢錢開始燃燒。於是老闆立刻開口:「測試機下班要關掉啊,不然每天都在幫 AWS 打工送錢?」每天省一半時間等於每天省一半費用,這可是比發年終還刺激的 KPI。當然啦,除了那些 24 小時要跟 7-11 一樣營業的服務例外。

問題來了:要是每天都靠工程師手動去開關機,不就等於幫 EC2 打卡小弟?太浪費青春了。於是我們出動 AWS EventBridge + Lambda,打造一個超省心的「自動開關機」神器。時間一到,EC2 自動下班,不只幫公司省錢,還能順便提醒你:「兄弟,該下班啦!」

今天就來教大家怎麼用 AWS EventBridge + Lambda,幫 EC2 安排一個「朝九晚五」的幸福人生。從此以後,它準時上班、乖乖下班,保證不再偷偷加班爆肝。

架構示意:誰負責打卡?

https://ithelp.ithome.com.tw/upload/images/20251002/20141071eo2xx0IRJW.png
想像一下這個小劇場:

  • EventBridge:公司人資,負責每天喊「上班啦!下班啦!」
  • Lambda:工地包商,接到人資通知後,立刻去按開關。
  • EC2:小小打工仔,什麼都不懂,只能乖乖聽話。

流程就長這樣:
EventBridge(定時喊話) → Lambda(實際操作) → EC2(乖乖聽話)
簡單暴力,不拖泥帶水。

建立 Lambda 函數(專門去按開關的工人)

建立 Lambda 的細節我就不再像寫教科書那樣一條一條交代了,畢竟大家都是工程師,介面點一點應該不至於迷路吧?(如果真的迷路了,拜託回去翻前幾篇,當作課本重修一下。)

這次我們的目標很單純:建一個叫 OperationEC2 的 Lambda Function
參數?不用想太多,大部份照預設就好:

  • Function name:OperationEC2
  • Runtime:Python 3.13
  • Lambda 程式碼
import json
import boto3

def lambda_handler(event, context):
    # 從 event 中獲取參數
    instance_ids = event.get('instance_ids', [])
    region = event.get('region', None)
    force_stop = event.get('force_stop', False)
    action = event.get('action', None)

    try:
        # 驗證輸入參數
        if not instance_ids:
            raise ValueError("instance_ids 參數是必需的")

        if not action:
            raise ValueError("action 參數是必需的")

        ec2 = boto3.client('ec2', region_name='us-east-1')
        try:

            if action.lower() == 'stop':
                for instance_id in instance_ids:
                    restult = ec2.stop_instances(InstanceIds=[instance_id], Force=force_stop)
                    print("restult:", restult)
            elif action.lower() == 'start':
                for instance_id in instance_ids:
                    restult = ec2.start_instances(InstanceIds=[instance_id])
                    print("restult:", restult)

            return {
                'statusCode': 200,
                'body': json.dumps('Hello from Lambda!')
            }
        except ClientError as e:
            error_message = f"關閉實例時發生錯誤: {e.response['Error']['Message']}"
            return {
                        'statusCode': 500,
                        'body': json.dumps({
                            'error': error_message,
                        }, ensure_ascii=False)
                    }
    except ValueError as e:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': f'參數錯誤: {str(e)}'
            }, ensure_ascii=False)
        }

在這個範例裡,我們走懶人路線 —— 把開機跟關機塞在同一支程式裡。靠 EventBridge 傳進來的參數,就能決定到底要叫 EC2 起床上班,還是叫它去睡覺。這樣一支程式搞定兩個任務,程式碼精簡,維護輕鬆,還能少開幾支 Lambda,避免日後進 AWS Console 的時候看到滿天飛的 Function 名字搞到自己頭痛。

當然啦,如果你老闆很愛搞「開機要先跳個舞,關機要先點個頭」這種特別需求,那就拆成兩支 Lambda,各自獨立比較安心。簡單說,一支全能 vs. 各自專精,就看你偏好「懶」還是「細心」囉。

幫 Lambda 準備好通行證(IAM Role)

還記得我們之前碎念過的最佳實踐嗎?沒錯,就是那句老話:權限要最小化。別什麼都給,結果 Lambda 一個不小心就能幫你把整個 AWS 帳號刪掉,那可不是自動化,而是「自動 Game Over」。

因為這次我們只是要讓 EC2 乖乖開機下班關機,所以只需要加上這幾個權限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:StartInstances"
            ],
            "Resource": "*"
        }
    ]
}

接下來就是老套路 —— 先找到 Lambda 用的那個 Role,然後透過 Create Inline Policy 幫它塞權限。
https://ithelp.ithome.com.tw/upload/images/20251002/20141071HZ3cX8Fjkx.png

編輯 Policy 的時候,請直接切換到 JSON 模式。幫你避免一格一格點 UI 了,工程師哪有空玩拼圖?把上面那段 JSON 權限複製進去就搞定。
https://ithelp.ithome.com.tw/upload/images/20251002/20141071JGcNOeZz0B.png

最後,系統會很貼心地問你:「要幫這份 Policy 取什麼名字?」
這時候不要糾結,叫什麼都行,反正你半年後一定忘記。建議就來個直白的,例如 EC2-Permission,至少比 test123 有誠意。按下 Create Policy,完工!
https://ithelp.ithome.com.tw/upload/images/20251002/20141071XPVWIwtULA.png

設定完之後,回去檢查一下 Lambda 的 Role 裡面有沒有多出剛剛那個 Policy。如果有,那就代表你的 Lambda 已經被授予「開關 EC2」的超能力了。
https://ithelp.ithome.com.tw/upload/images/20251002/201410711E7jRdjMAW.png

另外友情提醒:Lambda 在執行 start_instancesstop_instances 的時候,很可能三秒鐘打不完卡。AWS 預設的 timeout 太短,會讓你 Lambda 直接翻車。記得去把 最大執行時間拉長一點,不然到時候看到紅通通的錯誤訊息,你會懷疑自己是不是設定錯誤,結果只是 AWS 太心急。

設定 EventBridge 排班表

想讓 EC2 準時上下班?沒問題,給它一張班表就行了。

  • 早上開機:每天 09:00 → Lambda 幫忙喊「起床上班!」
  • 晚上關機:每天 18:00 → Lambda 溫柔提醒「打卡下班!」

簡單來說,EC2 就是你公司最乖的員工:排班怎麼寫,它就怎麼走。
接下來我們要在 AWS EventBridge 幫 EC2 安排班表。詳細的點點選選,前幾篇文章都碎念過了,這裡直接看重點:

  • Schedule Name:StartEC2(字面意思就知道幹嘛用的)
  • Schedule Pattern:Recurring schedule(每天都得來一次,沒藉口)
  • Time zone:UTC +8(別再用預設 UTC,不然 EC2 半夜三點就會幫你打卡)
  • Cron expression
    • 早上 9 點:Minutes = 0, Hours = 9
    • 星期一到五:Day of the week = 2-6
    • 如果你老闆鐵了心要你禮拜六也上班,那就 2-7,EC2 陪你一起加班爆肝。
      https://ithelp.ithome.com.tw/upload/images/20251002/20141071nvzmfEx0wS.png

然後把 Schedule 指派給我們剛剛建立的 Lambda Function —— OperationEC2
https://ithelp.ithome.com.tw/upload/images/20251002/20141071VRh9gixHGe.png

這裡最關鍵的就是 Payload,因為它決定要叫 EC2 幹嘛:

{
  "instance_ids": [
    "i-08f21a48705e28xxxx"
  ],
  "action": "start"
}
  • action:填 start,意思就是「EC2 起床!該上班了!」
  • instance_ids:放你要開的 EC2 ID。它是陣列,所以可以一次開多台,簡單暴力,一次喚醒整個部門。

至於下班的規則?套路一樣,只是改成 18:00,payload 改成 stop

{
  "instance_ids": [
    "i-08f21a48705e28xxxx"
  ],
  "action": "stop"
}

這樣一來,EC2 每天早上 9 點打卡上班,下午 6 點準時下班。
唯一的風險就是 —— 比你還準時下班。到時候老闆看到伺服器下班了,卻發現你還在辦公室,可能會想你是不是該幫你加點薪(做夢比較快)。

好啦,現在你知道怎麼讓 EC2 每天比你還要準時的上下班了!


上一篇
Day 21 - 拆解 RDS 七天自動開機的神秘炸彈 - Part 2
下一篇
Day 23 - 用 AWS Lambda Layer 管 Python 套件
系列文
最適合小型工作室精打細算的服務使用法25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言