iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
2
DevOps

用 CDK 定義 AWS 架構系列 第 28

Day 28 - 使用 CDK 創建 CloudWatch Alarm 的含圖告警同時發送到 LINE 與 Discord

昨天教大家怎麼簡單的在 LINE Notify 上面看到 CloudWatch 的 Alarm,不過這樣只有通知沒有目前的狀態圖對於平常判斷系統是否有問題好像少了什麼,所以今天來教大家怎麼讓 LINE Notify 上面除了可以看到 CloudWatch 的 Alarm 之外還可以看到 CloudWatch Graph

https://ithelp.ithome.com.tw/upload/images/20201012/20117701DXnf49N8qV.jpg

而今天的內容除了可以把訊息發到 LINE Notify 之外還加碼支援把訊息發送到 Discord

https://ithelp.ithome.com.tw/upload/images/20201012/20117701R5IkkogXCH.png

今日目標

  1. 更新 Lambda 程式
  2. Lambda 加入 Policy
  3. Lambda 加入 environment
  4. 加入壓測工具

創建一個 CloudWatch Alarm 的含圖告警

更新 Lambda 程式

先更新新版的 Lambda 程式,程式位置 GitHub

主要功能我都已經先寫好並且放到 GitHub 上面了,所以大家只要 pull 就可以取得新版程式了呦!

寫得很爛請大家見諒

$ cd lambda
$ git pull

Lambda 加入 Policy

我們需要讓 Lambda 可以吃到 CloudWatch 的資料,所以要修改一下它的權限,其實這邊權限還可以再給得更小不過今天就先開個 cloudwatch:Get* 吧 XD

myFunction.addToRolePolicy(
  new iam.PolicyStatement({
    actions: ["cloudwatch:Get*"],
    resources: ["*"],
  })
);

Lambda 加入 environment

還記得昨天的範例我們需要直接修改 "your-line-notify-token" 嗎?這個部分我做了一點改變,讓參數直接從 CDK 喂給 Lambda 的 environment

const myFunction = new lambda.Function(this, "Lambda", {
  handler: "index.handler",
  runtime: lambda.Runtime.NODEJS_10_X,
  code: lambda.Code.fromAsset("lambda"),
  environment: {
    LINE_NOTIFY_TOKEN: "your-line-notify-token",
    DISCORD_URL: "your-discord-webhook-url",
  },
});

取得 Discord Webhook 的方法可以參考官方文件

加入壓測工具

昨天的教學因為篇幅關係沒有介紹到如何使用人為方法給予機器負載做測試,今天來把這段補起來

我們平常使用的 AMI 為 AMAZON LINUX 2 所以以此介紹,首先我們需要先安裝 epel 不然我們沒有軟體包可以使用

$ sudo amazon-linux-extras install epel -y

如果對 epel 有問題可以參考 AWS 的文件 How do I enable the EPEL repository for my Amazon EC2 instance running CentOS, RHEL, or Amazon Linux?

安裝 stress-ng

這次我們選用 stress-ng 作為我們的測試工具,還是記得我們前面有教大家使用 User Data 嗎?我們就直接請 User Data 安裝這樣我們開啟系統的時候就可以直接使用了

$ sudo yum install stress-ng -y

製造 CPU Load

我們範例定義的 CPU Utilization threshold 為 5 基本上只要給他一點壓力 CloudWatch Alarm 就會有反應了,所以我們先給予他 CPU 40% 的壓力作為測試給予壓力的指令如:

$ stress-ng -c 1 -l 40
stress-ng: info:  [1084] defaulting to a 86400 second run per stressor
stress-ng: info:  [1084] dispatching hogs: 1 cpu
stress-ng: info:  [1084] successful run completed in 74.43s (1 min, 14.43 secs)

整理一下範例

今天的範例建立了

  • EC2
    • 放入 Default VPC 加速部署
    • 等級 t3a.nano
    • Security Group 22 全開
    • Image:AMAZON_LINUX_2
    • Subnet:PUBLIC
    • User Data:
      • amazon-linux-extras install epel -y
      • yum install stress-ng tmux htop -y
  • SNS
  • CloudWatch
  • Lambda
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
  isDefault: true,
});

const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
  vpc,
  allowAllOutbound: true,
});
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22));

const instance = new ec2.Instance(this, "Instance", {
  vpc,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3A,
    ec2.InstanceSize.NANO
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux({
    generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
  }),
  securityGroup,
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
  },
  keyName: "KeyPair",
});
instance.userData.addCommands(
  `amazon-linux-extras install epel -y`,
  `yum install stress-ng tmux htop -y`
);
new cdk.CfnOutput(this, "instance", {
  value: instance.instancePublicDnsName,
});

const topic = new sns.Topic(this, "Topic");

const metric = new cloudwatch.Metric({
  namespace: "AWS/EC2",
  metricName: "CPUUtilization",
  dimensions: {
    InstanceId: instance.instanceId,
  },
  period: cdk.Duration.minutes(1),
});

const alarm = new cloudwatch.Alarm(this, "Alarm", {
  metric,
  threshold: 5,
  evaluationPeriods: 1,
});

alarm.addAlarmAction(new cw_actions.SnsAction(topic));

const myFunction = new lambda.Function(this, "Lambda", {
  handler: "index.handler",
  runtime: lambda.Runtime.NODEJS_10_X,
  code: lambda.Code.fromAsset("lambda"),
  environment: {
    LINE_NOTIFY_TOKEN: "your-line-notify-token",
    DISCORD_URL: "your-discord-webhook-url",
  },
});
myFunction.addToRolePolicy(
  new iam.PolicyStatement({
    actions: ["cloudwatch:Get*"],
    resources: ["*"],
  })
);

topic.addSubscription(new subscriptions.LambdaSubscription(myFunction));

參考資料


今天介紹如何部署一個 CloudWatch Alarm 的含圖告警,有機會我會在修改目前的程式讓它變得更靈活使用或是支援更多的通訊程式,希望對大家有幫助 ~

想要看更多嗎?歡迎到我的部落格參觀

文章內容主要是網路或是程式開發類型的文章

本文同步刊載於 Clarence 部落格:Day 28 - 使用 CDK 創建 CloudWatch Alarm 的含圖告警同時發送到 LINE 與 Discord


「AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC」
本書改編並延伸自第 12 屆 iT 邦幫忙鐵人賽獲得 DevOps 組冠軍的《用 CDK 定義 AWS 架構》系列文章,以簡單、好讀的行文風格詳述技術細節,並提供完整的程式碼範例與說明,一步一步帶領新手從零開始踏上 AWS CDK 技術達人之路。

有興趣的朋友歡迎至天瓏書局選購!

購書連結 https://bit.ly/2ZMAebE

https://ithelp.ithome.com.tw/upload/images/20211103/20117701W7l6fQnn2L.jpg


上一篇
Day 27 - 使用 CDK 創建 CloudWatch 也能發送 Alarm 到 LINE 的系統
下一篇
Day 29 - 使用 CDK 創建 WordPress
系列文
用 CDK 定義 AWS 架構30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Arien
iT邦新手 5 級 ‧ 2021-06-09 13:52:12

您好:

我嘗試與您文章Day 27 - 使用 CDK 創建 CloudWatch 也能發送 Alarm 到 LINE 的系統以及Day 28 - CPU加壓測試,cloudwatch顯示in alarm沒錯,但是不論是line或discord皆無收到訊息通知,想請問可能是哪裡有誤呢?lambda程式複製您提供GitHub的index.js,貼上後裡面的程式有哪裡需要修正嗎?
還請幫忙解惑!!!謝謝。

Clarence iT邦新手 3 級 ‧ 2021-06-09 15:22:46 檢舉

先查看一下 CloudWatch 的 Log 看一下有沒有噴錯

我要留言

立即登入留言