Total Pageviews

2024/02/13

如何在 EC2 安裝 AWS SDK for Python (Boto3)

步驟 1: 安裝 Python

[ec2-user@ip-172-31-28-226 ~]$ sudo yum install python3 python3-pip -y


步驟 2: 驗證安裝

ec2-user@ip-172-31-28-226 ~]$ python3 --version
Python 3.9.16


步驟 3: 安裝 AWS SDK for Python (Boto3)

[ec2-user@ip-172-31-28-226 ~]$ pip3 install boto3
Defaulting to user installation because normal site-packages is not writeable
Collecting boto3
  Downloading boto3-1.34.40-py3-none-any.whl (139 kB)
     |████████████████████████████████| 139 kB 5.7 MB/s            
Collecting botocore<1.35.0,>=1.34.40
  Downloading botocore-1.34.40-py3-none-any.whl (12.0 MB)
     |████████████████████████████████| 12.0 MB 41.5 MB/s            
Collecting s3transfer<0.11.0,>=0.10.0
  Downloading s3transfer-0.10.0-py3-none-any.whl (82 kB)
     |████████████████████████████████| 82 kB 378 kB/s              
Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /usr/lib/python3.9/site-packages (from boto3) (0.10.0)
Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /usr/lib/python3.9/site-packages (from botocore<1.35.0,>=1.34.40->boto3) (2.8.1)
Requirement already satisfied: urllib3<1.27,>=1.25.4 in /usr/lib/python3.9/site-packages (from botocore<1.35.0,>=1.34.40->boto3) (1.25.10)
Requirement already satisfied: six>=1.5 in /usr/lib/python3.9/site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.35.0,>=1.34.40->boto3) (1.15.0)
Installing collected packages: botocore, s3transfer, boto3
Successfully installed boto3-1.34.40 botocore-1.34.40 s3transfer-0.10.0


步驟 4: 配置 AWS CLI (請自行設定自己的 AK 與 SK)

[ec2-user@ip-172-31-28-226 ~]$ aws configure
AWS Access Key ID [None]: AKIASHY4YDRZJLQSTQNU
AWS Secret Access Key [None]: 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
Default region name [None]: us-east-1
Default output format [None]: json


步驟 5: 寫一個 Python 程式來列出 S3 bucket

[ec2-user@ip-172-31-28-226 ~]$ vi list_s3_buckets.py 
[ec2-user@ip-172-31-28-226 ~]$ cat list_s3_buckets.py 
import boto3

def list_buckets():
    # 創建一個 S3 服務客戶端
    s3 = boto3.client('s3')
    
    # 列出所有buckets
    response = s3.list_buckets()
    
    # 輸出 bucket name
    print("S3 Buckets:")
    for bucket in response['Buckets']:
        print(f"- {bucket['Name']}")

if __name__ == '__main__':
    list_buckets()


步驟 6: 執行 Python 程式

[ec2-user@ip-172-31-28-226 ~]$ python3 list_s3_buckets.py
S3 Buckets:
- albert-buckert-154142252146

如何安裝與驗證 AWS CLI

安裝 AWS CLI

1. 下載 AWS CLI

[ec2-user@ip-172-31-28-226 ~]$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 57.3M  100 57.3M    0     0   260M      0 --:--:-- --:--:-- --:--:--  261M


2. 解壓縮下載檔案

[ec2-user@ip-172-31-28-226 ~]$ unzip awscliv2.zip


3. 安裝 AWS CLI

[ec2-user@ip-172-31-28-226 ~]$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version


4. 驗證安裝結果

[ec2-user@ip-172-31-28-226 ~]$ aws --version
aws-cli/2.15.19 Python/3.11.6 Linux/6.1.75-99.163.amzn2023.x86_64 exe/x86_64.amzn.2023 prompt/off


5. 配置 AWS CLI

- AWS Access Key IDAWS Secret Access Key:你可以在 AWS 管理控制台的 IAM 服務中建立一個新的使用者或使用現有的使用者憑證。
- Default region name:輸入你想要操作的 AWS 區域的代碼,例如 us-east-1
- Default output format:輸入你偏好的輸出格式,常見的選項包括 jsontexttable

[ec2-user@ip-172-31-28-226 ~]$ aws configure
AWS Access Key ID [None]: AKIASHY4YDRZJLQSTQNU
AWS Secret Access Key [None]: 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
Default region name [None]: us-east-1
Default output format [None]: json


透過 AWS CLI 進行 S3 操作

1. Create S3 bucket

[ec2-user@ip-172-31-28-226 ~]$ aws s3 mb s3://albert-buckert-154142252146 --region us-east-1
make_bucket: albert-buckert-154142252146


2. List S3 bucket

[ec2-user@ip-172-31-28-226 ~]$ aws s3 ls
2024-02-13 10:02:24 albert-buckert-154142252146


3. Create a file and upload it to S3 bucket

[ec2-user@ip-172-31-28-226 ~]$ echo "Hello World" > hello.txt
[ec2-user@ip-172-31-28-226 ~]$ cat hello.txt
Hello World
[ec2-user@ip-172-31-28-226 ~]$ aws s3 cp hello.txt s3://albert-buckert-154142252146
upload: ./hello.txt to s3://albert-buckert-154142252146/hello.txt 



2024/02/12

Send Fanout Event Notifications with Amazon Simple Queue Service (SQS) and Amazon Simple Notification Service (SNS)

步驟 1: 建立 SNS Topic

[cloudshell-user@ip-10-138-176-84 ~]$ aws sns create-topic --name MyFanoutTopic
{
    "TopicArn": "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic"
}


步驟 2: 建立兩個 SQS Queue
[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs create-queue --queue-name MyQueue1
{
    "QueueUrl": "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue1"
}
[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs create-queue --queue-name MyQueue2
{
    "QueueUrl": "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue2"
}


步驟 3: 取得兩個 SQS Queue 的 Queue Arn
[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs get-queue-attributes --queue-url "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue1" --attribute-names "QueueArn"
{
    "Attributes": {
        "QueueArn": "arn:aws:sqs:us-east-1:473993628677:MyQueue1"
    }
}
[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs get-queue-attributes --queue-url "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue2" --attribute-names "QueueArn"
{
    "Attributes": {
        "QueueArn": "arn:aws:sqs:us-east-1:473993628677:MyQueue2"
    }
}


步驟 4: 到 SQS 編輯 policy

{
  "Id": "Policy1707705888884",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1707705887802",
      "Action": [
        "sqs:SendMessage"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:sqs:us-east-1:473993628677:MyQueue1",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic"
        }
      },
      "Principal": "*"
    }
  ]
}

{
  "Id": "Policy1707705888884",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1707705887802",
      "Action": [
        "sqs:SendMessage"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:sqs:us-east-1:473993628677:MyQueue2",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic"
        }
      },
      "Principal": "*"
    }
  ]
}


步驟 5: 將 SQS Queue 訂閱到 SNS Topic
[cloudshell-user@ip-10-138-176-84 ~]$ aws sns subscribe --topic-arn "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic" --protocol sqs --notification-endpoint "arn:aws:sqs:us-east-1:473993628677:MyQueue1"
{
    "SubscriptionArn": "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic:de6e8885-824b-4450-99ae-8fc3351870d8"
}
[cloudshell-user@ip-10-138-176-84 ~]$ aws sns subscribe --topic-arn "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic" --protocol sqs --notification-endpoint "arn:aws:sqs:us-east-1:473993628677:MyQueue2"
{
    "SubscriptionArn": "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic:0300ef05-afed-480c-9590-a3797e1dd4dc"
}


步驟 6: 向 SNS Topic 發送 message
[cloudshell-user@ip-10-138-176-84 ~]$ aws sns publish --topic-arn "arn:aws:sns:us-east-1:473993628677:MyFanoutTopic" --message "Hello, fanout world!"
{
    "MessageId": "45c4b5e9-0e8c-56b5-a0ff-ebaa871ffe09"
}


步驟 7: 從 SQS Queue 接收 message
[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs receive-message --queue-url "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue1"
{
    "Messages": [
        {
            "MessageId": "336c2883-0b0b-429c-ada0-c496b40b86ad",
            "ReceiptHandle": "AQEB170H0mtie0ePMmG/g2ZAwS3RZtz1sO7UZO9pEnwHvscXNUsIEBHDh1OY5ekAZeTO6iQsJ8Crlau8DXMzx8UBctfk6w1k9ZpMaoD9x+ykM1t2/wbOksIymRMTbJvpuOSAWemyewXI5aWbIkMyO4oBZ7QSe/CEeV0LQzA+2ddziOZFEmeuCTwZ+eZ3u7GNiei7dB0YZuyKdyp7EJrc/3LZngKj105vUoZGTQbQOBcflWLSB0aofNQTMhjQc2e20zg2SD5tBkkQklX5KZWhv+WCS+nJUuP9VNdw0bGAK4+Hr8SnLbRXfAGsN7zy9cgBd7jydjJJFCULBaCl/8bYGWGHzNWSVIBnCfnStt0ndHDRyjuq7+7dWC9QIK1Zq7KhmDJH",
            "MD5OfBody": "f52631ba39cad6f0e3c0833c106281b0",
            "Body": "{\n  \"Type\" : \"Notification\",\n  \"MessageId\" : \"45c4b5e9-0e8c-56b5-a0ff-ebaa871ffe09\",\n  \"TopicArn\" : \"arn:aws:sns:us-east-1:473993628677:MyFanoutTopic\",\n  \"Message\" : \"Hello, fanout world!\",\n  \"Timestamp\" : \"2024-02-12T02:49:55.386Z\",\n  \"SignatureVersion\" : \"1\",\n  \"Signature\" : \"Ir40tezuo9eSyMDBYnyCzvi5apaKzjsVXC3JinnEYUUN/JkJuB67uYb0RWVbfFLWAGAxMRmTVJ5FOX04ABCpDTcp8b8IlyJ3P09Ekn3wExBmXO4dXyf8VnSLb3D1oFB8FxyqYlb1z1yGJ+bNZIhvcSluJldD/CWGpQVD148rSSdRWEPK8yj89EMlwvUC2t+OTDa58kPnDKdHovdPY7xhfycKCy2yt0Ft2ExOFdFhxTU1ICujKUUbIdVYtRq9LpubgphskfVwq6qYW8dgvr5Ry5Bo2dvjePjK1KqyQYURDmcsnSd1k1cl+N8gOGDbMKP3ooGV0KzCMd52cXXYV3ws3g==\",\n  \"SigningCertURL\" : \"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n  \"UnsubscribeURL\" : \"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:473993628677:MyFanoutTopic:de6e8885-824b-4450-99ae-8fc3351870d8\"\n}"
        }
    ]
}

[cloudshell-user@ip-10-138-176-84 ~]$ aws sqs receive-message --queue-url "https://sqs.us-east-1.amazonaws.com/473993628677/MyQueue2"
{
    "Messages": [
        {
            "MessageId": "c4e5cef0-5923-4f4f-b045-13df08dc163d",
            "ReceiptHandle": "AQEB5eDDWgy7KmvsxCXF2Yu7t88PlKEZksq47lm9eFoFdfommA8vkrAGN32SuqHXP2f5oZarAybumHGi3/U13nY/3wbOPmbXzRWEi5sTVN2NWhLnPrFLuPAh2DVh8HFQMj9NevNv9IQxn8uI96PgJtZs1NgUiD4w6TutSD0aPoJdNbdaGYcgbbCCUvEPRUcCczcpEhRvFMg+H4ZaeXccFOrEm8ecbNvZINa67/CWyse4gGBKWk//Qz7l38xNBWBPG3e/1HTLqNl0IFG0PhyXqU1CJnBUAaHHpEoK2gvMJVAivcpuOQaBabotwg8KXkKBposfHajPa2ULCVa/8T2F27w2ONgrFPcaCgq+jbFo71PPi3PcVNVP8y4Vke7SKxAAaQTg",
            "MD5OfBody": "6734da73366cc6dd7ca67628bbaba918",
            "Body": "{\n  \"Type\" : \"Notification\",\n  \"MessageId\" : \"45c4b5e9-0e8c-56b5-a0ff-ebaa871ffe09\",\n  \"TopicArn\" : \"arn:aws:sns:us-east-1:473993628677:MyFanoutTopic\",\n  \"Message\" : \"Hello, fanout world!\",\n  \"Timestamp\" : \"2024-02-12T02:49:55.386Z\",\n  \"SignatureVersion\" : \"1\",\n  \"Signature\" : \"Ir40tezuo9eSyMDBYnyCzvi5apaKzjsVXC3JinnEYUUN/JkJuB67uYb0RWVbfFLWAGAxMRmTVJ5FOX04ABCpDTcp8b8IlyJ3P09Ekn3wExBmXO4dXyf8VnSLb3D1oFB8FxyqYlb1z1yGJ+bNZIhvcSluJldD/CWGpQVD148rSSdRWEPK8yj89EMlwvUC2t+OTDa58kPnDKdHovdPY7xhfycKCy2yt0Ft2ExOFdFhxTU1ICujKUUbIdVYtRq9LpubgphskfVwq6qYW8dgvr5Ry5Bo2dvjePjK1KqyQYURDmcsnSd1k1cl+N8gOGDbMKP3ooGV0KzCMd52cXXYV3ws3g==\",\n  \"SigningCertURL\" : \"https://sns.us-east-1.amazonaws.com/SimpleNotificationService-60eadc530605d63b8e62a523676ef735.pem\",\n  \"UnsubscribeURL\" : \"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:473993628677:MyFanoutTopic:0300ef05-afed-480c-9590-a3797e1dd4dc\"\n}"
        }
    ]
}

2024/02/11

透過 AWS API Gateway (Rest API) 呼叫 Lambda

設定步驟如下

1.  在 Lambda 撰寫簡單的 Python 程式

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': 'Hello from Lambda!'
    }

2. 測試此程式是否如預期正確執行

Test Event Name
my-test

Response
{
  "statusCode": 200,
  "body": "Hello from Lambda!"
}

Function Logs
START RequestId: 131fa0f2-faa0-4ca3-a11d-4c63b6383b1c Version: $LATEST
END RequestId: 131fa0f2-faa0-4ca3-a11d-4c63b6383b1c
REPORT RequestId: 131fa0f2-faa0-4ca3-a11d-4c63b6383b1c	Duration: 1.37 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 34 MB

Request ID
131fa0f2-faa0-4ca3-a11d-4c63b6383b1c

3.  至 API Gateway Build Rest API


4. 選擇「New API」、指定「API Name」、click「Create API」


5. click 「Create Resource」


6. 指定 「Resource name」 、click 「Create Resource」


7. create GET method 與指定 Lambda function name (i.e. HelloFunction)



8. Deploy API 與指定 stage name 為 dev



9. 回到原本的 Lambda function,click "Add tirgger"


10. 指定 API Gateway、選擇 "Use existing API"


11. 指定既有 API name (i.e. HelloFunction)、stage 設定為 "dev"、click "Add"


12. 設定成功,並取得 API endpoint



13. 測試成功




2024/02/10

使用 AWS API Gateway 整合 Lambda

以下是我的 Lambda code,他會取得網址的 name 參數值,並組成 "Hello World~"+name參數值的字串

def lambda_handler(event, context):
    # 從事件對象的 queryStringParameters 中獲取 "name" 參數
    name = event.get('queryStringParameters', {}).get('name', 'World')
    
    # 拼接字符串並返回結果
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json'
        },
        'body': f'Hello World~{name}'
    }


以下是 API Gateway 的設定

1. 在 Create API 選擇 HTTP API => Click Build


2. 指定欲整合的 Lambda function name 與 API name


3. 指定 http method 與 resource path


4. 指定 stage name


5. 在 review page click Create button


Postman 測試畫面

1. 在 Stages 頁面取得 http url


2. 使用以下網址到 Postman 驗證結果

https://vo6ltr8xrl.execute-api.us-east-1.amazonaws.com/dev/hello?name=Mandy




2024/02/09

執行 AWS PutMetricData operation 出現錯誤:The parameter MetricData.member.1.Timestamp must specify a time no more than two hours in the future

Problem

AWS PutMetricData operation 內容如下

#!/bin/bash
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:05:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:06:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:07:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:08:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:09:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:10:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:11:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:12:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:13:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:14:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:15:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:16:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:17:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:18:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:19:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:20:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T11:21:00.000Z


執行後出現以下錯誤

An error occurred (InvalidParameterValue) when calling the PutMetricData operation: The parameter MetricData.member.1.Timestamp must specify a time no more than two hours in the future.

An error occurred (InvalidParameterValue) when calling the PutMetricData operation: The parameter MetricData.member.1.Timestamp must specify a time no more than two hours in the future.
An error occurred (InvalidParameterValue) when calling the PutMetricData operation: The parameter MetricData.member.1.Timestamp must specify a time no more than two hours in the future. An error occurred (InvalidParameterValue) when calling the PutMetricData operation: The parameter MetricData.member.1.Timestamp must specify a time no more than two hours in the future.


Root Cause

設定的 timestamp 時間不能比當前時間超過 2小時,此限制是為了防止因時間錯誤設置而導致數據不一致。


How-To

重新修正 timestamp

#!/bin/bash
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:05:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:06:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:07:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:08:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:09:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:10:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:11:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:12:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:13:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:14:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:15:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:16:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:17:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:18:00.000Z 
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:19:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:20:00.000Z
aws cloudwatch put-metric-data --metric-name CriticalError --namespace MyService --value 1 --timestamp 2024-02-09T03:21:00.000Z


在 CloudWatch Metrics 也如預期找到所執行的結果





AWS CloudWatch log group 未如預期出現所設定的 log group name

Problem

安裝 CloudWatch Agent 至 EC2,並將設定的 metrics 資料傳送至AWS CloudWatch log group,但在畫面未能找到所指定的 log group name。

config.json 的內容如下

{
        "agent": {
                "metrics_collection_interval": 1,
                "run_as_user": "cwagent"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/messages",
                                                "log_group_class": "STANDARD",
                                                "log_group_name": "messages",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": 1
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "aggregation_dimensions": [
                        [
                                "InstanceId"
                        ]
                ],
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "cpu": {
                                "measurement": [
                                        "cpu_usage_idle",
                                        "cpu_usage_iowait",
                                        "cpu_usage_user",
                                        "cpu_usage_system"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ],
                                "totalcpu": false
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent",
                                        "inodes_free"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ]
                        },
                        "diskio": {
                                "measurement": [
                                        "io_time"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 1
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 10,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        },
                        "swap": {
                                "measurement": [
                                        "swap_used_percent"
                                ],
                                "metrics_collection_interval": 1
                        }
                }
        }
}


Root Cause

到此目錄 /opt/aws/amazon-cloudwatch-agent/logs/ 檢查 CloudWatch Agent Log,發現是權限問題,我應該要把 run_as_user 改成 root

[inputs.logfile] Failed to tail file /var/log/messages with error: open /var/log/messages: permission denied


How-To

將 config.json 修改如下即可

{
        "agent": {
                "metrics_collection_interval": 1,
                "run_as_user": "root"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/messages",
                                                "log_group_class": "STANDARD",
                                                "log_group_name": "messages",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": 1
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "aggregation_dimensions": [
                        [
                                "InstanceId"
                        ]
                ],
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "cpu": {
                                "measurement": [
                                        "cpu_usage_idle",
                                        "cpu_usage_iowait",
                                        "cpu_usage_user",
                                        "cpu_usage_system"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ],
                                "totalcpu": false
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent",
                                        "inodes_free"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ]
                        },
                        "diskio": {
                                "measurement": [
                                        "io_time"
                                ],
                                "metrics_collection_interval": 1,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 1
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 10,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        },
                        "swap": {
                                "measurement": [
                                        "swap_used_percent"
                                ],
                                "metrics_collection_interval": 1
                        }
                }
        }
}


2024/02/07

如何透過 AWS Lambda 呼叫 SES (Simple Email Service) 發信

實作步驟如下

1. 建立 Verified Identities來做為測試用途的 Sender 與 Receiver email address


2. 建立 Lambda Function 後,進入 Configuration => Permission,確認該 Role 具備 SES 角色權限


3. 呼叫 SES 的 Python code

import boto3
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    # 建立 SES 客戶端
    ses_client = boto3.client('ses', region_name='us-east-1')  # 請根據需要替換為您的 SES 區域

    # 電子郵件參數
    SENDER = "hekarey795@giratex.com"  # 替換為您的發件人地址
    RECIPIENT = "hekarey795@giratex.com"  # 替換為您的收件人地址
    SUBJECT = "AWS SES Test Email from Lambda"
    BODY_TEXT = ("This is a test email sent from AWS Lambda using SES")
    CHARSET = "UTF-8"

    # 嘗試發送電子郵件
    try:
        response = ses_client.send_email(
            Destination={
                'ToAddresses': [
                    RECIPIENT,
                ],
            },
            Message={
                'Body': {
                    'Text': {
                        'Charset': CHARSET,
                        'Data': BODY_TEXT,
                    },
                },
                'Subject': {
                    'Charset': CHARSET,
                    'Data': SUBJECT,
                },
            },
            Source=SENDER,
        )
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("Email sent! Message ID:"),
        print(response['MessageId'])

4. 執行結果


5. 檢查信箱






透過 AWS EC2 Connect 連入編輯檔案,出現 "index.html" E212: Can't open file for writing 錯誤

Problem

透過 AWS EC2 Connect 連入編輯檔案,出現 "index.html" E212: Can't open file for writing 錯誤


Root Cause

會出現上述問題是因為權限不足所導致


How-To

[ec2-user@ip-172-31-43-197 html]$ vi index.html 
[ec2-user@ip-172-31-43-197 html]$ sudo vi index.html