使用 aws cli 建立 現有 EC2 status check alarm 小記
aws-cli: 2.2.4
OS: container with openSUSE Leap 15.2
因為工作上面的需要, 雲端的資源如果是上線的服務大多需要設定告警機制.
如果是在 GCP 或是 Azure 的平台上, 是可以透過設定 Tag 的方式來進行告警條件的設定, 簡化設定告警的數量, 例如
AWS CloudWatch alarm 一次監控一個指標, 而指標的維度不同, 使得每個EC2 instance的指標都是唯一的, 因此目前並沒有直接的方法可以為相同指標的所有EC2 instance創建單一個通用的CloudWatch alarm.
所以解決的方式可能就是透過 aws cli 配合 shell script 方式來進行處理, 處理上大概有 2 個方向
將目前現有的 EC2 建立 CloudWatch Alarm
建立 EC2 時, 建立 CloudWatch Alarm
這一篇來寫將目前現有的 EC2 建立 CloudWatch Alarm
==== 將目前現有的 EC2 建立 CloudWatch Alarm ====
先來整理一下, 如果目前有現有的 EC2, 如何針對單一的 EC2 進行建立 CloudWatch Alarm
列出目前 Region 的 EC2 ID
測試 Region: us-east-2 (Ohio)
# aws ec2 --region us-east-2 --output text describe-instances --query "Reservations[*].Instances[*].{Instances:InstanceId}" --profile default
i-0864c1f7405d84941
i-0339fb4f575b549f9
因為我的環境有不同的 AWS ID, 所以利用 --profile 指定環境
因為我的 CloudWatch Alarm 有結合 SNS 進行通知, 等等建立 CloudWatch Alarm 要輸入 SNS ARN, 故使用 aws sns list-topics --region us-east-2 --profile xxxxx 列出 SNS 相關資訊
# aws sns list-topics --region us-east-2 --profile default
{
"Topics": [
{
"TopicArn": "arn:aws:sns:us-east-2:783127832903:Notity_EC2_CPU_50"
}
]
}
接下來使用 aws cloudwatch put-metric-alarm 指令來建立
# aws cloudwatch put-metric-alarm --alarm-name healthcheck --alarm-description "health check status failed" --metric-name StatusCheckFailed --namespace AWS/EC2 --statistic Maximum --period 60 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --dimensions "Name=InstanceId,Value=i-0864c1f7405d84941" --evaluation-periods 2 --alarm-actions arn:aws:sns:us-east-2:783127832903:Notity_EC2_CPU_50 --region us-east-2 --profile default
--dimensions 的 Value 請使用上面查詢到的 EC2 instance ID, SNS ARN 請換成要通知的 SNS Topic
使用 EC2 的 StatusCheckFailed 這個 Metric 來判斷, 所以如果是自行停止 EC2 的狀況, 也只是資料不足
--period 60 - 60 秒採樣進行採樣
--evaluation-periods 2 - 配合 上面的 --period 60 秒, 就是 data point 為 60 秒 x2 就是 120 秒
--threshold 1 - 門檻值為 1,
配合比對方式 GreaterThanOrEqualToThreshod, 當 status check fail 達到 120 秒(驗證單位為 2 個 perion) (門檻值 1), 就滿足告警
--alarm-actions - 使用 SNS 來通知
如果在使用 aws cloudwatch put-metric-alarm 指令建立的時候, 遇到同樣名稱的 alarm, 參考官網的說明是會覆蓋掉的, If an alarm with the same name already exists, it will be overwritten by the new alarm.
列出目前 Region 的 cloudwatch alarm 名稱來確認
# aws cloudwatch describe-alarms --region us-east-2 --profile default | grep 'AlarmName'
"AlarmName": "healthcheck",
再來就是寫成 shell script 來針對所有的 EC2 建立 CloudWatch Alarm
建立一個 aws_create_CloudWatchAlarm_existEC2_statusCheck.sh
內容如下
#!/bin/bash
# edit by sakana 2021/8/29
# 將特定的 Region 目前的 EC2 加上 CloudWatch 告警, 使用 StatusCheckFailed
echo ""
echo "將特定的 Region 目前的 EC2 加上 CloudWatch 告警, 使用 StatusCheckFailed"
# 設定使用 AWS 帳號
echo ""
echo "設定使用 AWS 帳號, 這邊請用您的 profile 名稱"
echo ""
read -e -p "Please enter aws account name: " -i "sakana" account_name
# 設定使用 AWS Region
echo ""
echo "設定使用 AWS Region"
echo "N.Virginia: us-east-1"
echo "Tokyo: ap-northeast-1"
echo ""
read -e -p "Please enter aws region name: " -i "ap-northeast-1" region_name
# 設定使用 SNS Topic
echo ""
echo "==== 列出目前的 SNS Topic ARN ===="
echo ""
aws sns list-topics --region $region_name --profile $account_name
echo "================================"
echo "設定使用 SNS Topic"
echo ""
read -e -p "Please enter sns arn: " -i "arn:aws:sns:xxxxxxxxx" sns_arn
echo ""
# 執行 新增 CloudWatch Alarm
echo "執行 新增 CloudWatch Alarm"
for InstanceId in `aws ec2 --region $region_name --output text describe-instances --query "Reservations[*].Instances[*].{Instances:InstanceId}" --profile $account_name`
do
echo ""
aws cloudwatch put-metric-alarm --alarm-name EC2_healthcheck_$InstanceId --alarm-description "health check status failed" --metric-name StatusCheckFailed --namespace AWS/EC2 --statistic Maximum --period 60 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --dimensions "Name=InstanceId,Value=$InstanceId" --evaluation-periods 2 --alarm-actions $sns_arn --region $region_name --profile $account_name
echo ""
done
這樣應該會把目前 Region 上面的 EC2 都建立 CloudWatch Alarm :)
後續思考
這個 script 的好處是目前 Region 的 EC2 都加上 StatusCheckFailed 的 Alarm, 但是如果 EC2 被移除後的管理是後續要思考的點
不過也算是又向 AWS 前進一步
~ enjoy it
Reference