AWS monitoring - Cloud Watch 기반 CPU 10%미만 EC2 정보 수집
- -
글을 읽기에 앞서 해당 코드는 python 및 개발 지식이 없는 제가 직접 만든 코드 입니다. 개발자 분이 보시기에 많이 이상 할 수 있습니다. 최적화가 되어 있지 않으며, 코드를 보기에 불편 할 수 있는 점 양해 부탁 드립니다.
1. 수집 조건
- Cloud Watch 상에서 하루 평균 CPU가 10%를 넘지 못하는 경우 수집
- limit를 조정 가능 합니다.
- 코드를 수정하면 MAX / MIN으로도 수정 가능 합니다.
- spot EC2를 수집 하지 않습니다.
2. 수집 내역
아래의 컬럼명은 수정이 가능하며, 기호에 맞게 사용 부탁 드립니다.
계속해서 수정하다 보니 수집하는 명칭이 이상할 수 있습니다.
|
3. 코드
변경하여 사용 가능한 부분 또는 설명이 필요한 부분만 설명 합니다.
나머지는 주석으로 되어 있습니다.
- import library
아래의 pymssql이 있는데, 사용자에 맞게 mysql , postgreSQL 등등 불러서 사용하시면 사용 가능 합니다.
1
2
3
4
|
import boto3
import sys
import pymssql
import datetime
|
cs |
- AWS 연결 정보 부분
아래의 key_list 부분에서 여러개의 Account를 관리 할 수 있도록 해당 Account 및 access,secret key만 넣으면 전부 수집하도록 해놨습니다. 각각의 정보 구분자는 | 이며 서로 다른 Account를 구분하는 것은 , 콤마 입니다.
1
2
3
4
5
6
7
8
9
10
|
#AWS information
#"," multiple entries available
#key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY','ACCOUNT2|ACCESS KEY2|SECRET KEY2','ACCOUNT2|ACCESS KEY2|SECRET KEY2']
key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY']
#Enter desired region information
region_list = ['us-east-2','us-west-1','us-west-2','ap-south-1','ap-northeast-2','ap-southeast-1','ap-southeast-2','ap-northeast-1','eu-central-1','eu-west-1','eu-west-2','eu-west-3','sa-east-1']
access_key = ''
secret_key = ''
region = ''
boto3.session.Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key)
|
cs |
region_list의 경우 원하는 region만 넣으면 가능합니다.
- tag 수집 부분
tag를 이용해서 EC2의 이름 및 생성자를 가져옵니다.
꼭 Name , name 으로 입력해야지 가져올 수 있습니다. 생성자 또한 create / creator을 통해서 가져 옵니다.
여담으로 AWS쪽에 관리를 위해서는 tag는 필수라고 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#Import EC2 tag
#EC2 tag name > tag name : Name
#EC2 tag creator or create team > tag name : create or creator
def get_instance_tag(fid):
global result, result2
result = ''
result2 = ''
ec2client = boto3.resource('ec2',aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=region)
ec2instance = ec2client.Instance(fid)
if ec2instance.tags is None: #tag가 아에 없을 경우 PASS
return (result,result2)
for tags in ec2instance.tags:
if tags.get("Key") is None: continue #tags key 체크
if tags.get("Key").lower() == 'Name'.lower():
result = tags.get("Value")
if tags.get("Key").lower() == 'create'.lower() or tags.get("Key").lower() == 'creator'.lower():
result2 = tags.get("Value")
return (result,result2)
|
cs |
- 전체 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
import boto3
import sys
import pymssql
import datetime
# -----------------------------------------------------------------------------------------------------------------------------------------------
#AWS information
#"," multiple entries available
#key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY','ACCOUNT2|ACCESS KEY2|SECRET KEY2','ACCOUNT2|ACCESS KEY2|SECRET KEY2']
key_list = ['ACCOUNT|ACCESS KEY|SECRET KEY']
#Enter desired region information
region_list = ['us-east-2','us-west-1','us-west-2','ap-south-1','ap-northeast-2','ap-southeast-1','ap-southeast-2','ap-northeast-1','eu-central-1','eu-west-1','eu-west-2','eu-west-3','sa-east-1']
access_key = ''
secret_key = ''
region = ''
boto3.session.Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key)
# -----------------------------------------------------------------------------------------------------------------------------------------------
#Import date
now = datetime.datetime.now()
today = str(now)
today = today.split(' ')[0]
yesterday = str(now + datetime.timedelta(days=-1))
yesterday = yesterday.split(' ')[0]
# -----------------------------------------------------------------------------------------------------------------------------------------------
#Database information
conn = pymssql.connect(server='HOST',port= 'PORT', user='USER', password='PASS WORD',database='DATABASE NAME')
cur = conn.cursor()
# -----------------------------------------------------------------------------------------------------------------------------------------------
#CPU mean value calculation
def CPUUtilization_check(isinstance_id):
cloudwatch = boto3.client('cloudwatch', aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=region)
cpu_limit = 10 #Modifying here allows you to change the collection conditions.
response = cloudwatch.get_metric_statistics(
Namespace='AWS/EC2',
MetricName='CPUUtilization',
Dimensions=[
{
'Name': 'InstanceId',
'Value': isinstance_id
},
],
StartTime=yesterday ,
EndTime=today,
Period=86400, #시간 단위 (1시간 = 3600)
Statistics=['Minimum','Maximum','Average'], #Cloudwatch의 그래프는 Average
Unit='Percent'
)
for cpu in response['Datapoints']:
if 'Average' in cpu:
result = 'CPUUtilization'+'/'+str(cpu['Average'])+'/'+str(cpu['Timestamp'])[0:16]+'/'+str(cpu['Minimum'])+'/'+str(cpu['Maximum'])
metric_type = result.split('/')[0]
cpu_persent = result.split('/')[1]
timestamp = result.split('/')[2]
cpu_max = result.split('/')[3]
cpu_min = result.split('/')[4]
if float(cpu_persent) <= cpu_limit:
param = (account,isinstance_id,InstanceType,InstanceName,InstanceCreate,region,metric_type,cpu_max,cpu_min,cpu_persent,timestamp,SubnetId,Keypair)
cur.callproc('dbo.usp_insert_permon', param) # mssql procprocedure
conn.commit()
# -----------------------------------------------------------------------------------------------------------------------------------------------
#Import EC2 tag
#EC2 tag name > tag name : Name
#EC2 tag creator or create team > tag name : create or creator
def get_instance_tag(fid):
global result, result2
result = ''
result2 = ''
ec2client = boto3.resource('ec2',aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=region)
ec2instance = ec2client.Instance(fid)
if ec2instance.tags is None: #tag가 아에 없을 경우 PASS
return (result,result2)
for tags in ec2instance.tags:
if tags.get("Key") is None: continue #tags key 체크
if tags.get("Key").lower() == 'Name'.lower():
result = tags.get("Value")
if tags.get("Key").lower() == 'create'.lower() or tags.get("Key").lower() == 'creator'.lower():
result2 = tags.get("Value")
return (result,result2)
# -----------------------------------------------------------------------------------------------------------------------------------------------
for key in key_list:
account = key.split('|')[0]
access_key = key.split('|')[1]
secret_key = key.split('|')[2]
print((account, access_key, secret_key))
# -----------------------------------------------------------------------------------------------------------------------------------------------
for region_name in region_list :
region = region_name
ec2client = boto3.client('ec2', aws_access_key_id=access_key, aws_secret_access_key=secret_key,region_name=region)
response = ec2client.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['stopped', 'running']}])
if response is None:
continue
for reservation in response.get("Reservations"):
if reservation is None:
continue
for instance in reservation["Instances"]:
SpotInstanceRequestId = (instance.get("SpotInstanceRequestId")) #Spot instance check
if SpotInstanceRequestId is None:
isinstance_id = (instance.get("InstanceId"))
InstanceType = (instance.get("InstanceType"))
InstanceName = (get_instance_tag(isinstance_id)[0])
InstanceCreate = (get_instance_tag(isinstance_id)[1])
SubnetId = (instance.get("SubnetId"))
Keypair = (instance.get("KeyName"))
if None in [SubnetId,InstanceName,isinstance_id,InstanceType,InstanceCreate,Keypair,InstanceName,InstanceCreate]:
continue
#print((isinstance_id,SpotInstanceRequestId,InstanceType,InstanceName,InstanceCreate,SubnetId,Keypair))
CPUUtilization_check (isinstance_id)
print ('insert ok',account,'-',region)
# -----------------------------------------------------------------------------------------------------------------------------------------------
|
cs |
위에서 수집 된 내용을 토대로 비용 관리 및 불 필요하게 가동 중인 EC2 등을 중지 시킬 수 있습니다.
비용 정보는 https://ec2instances.info/ 사이트를 통해서 가져 올 수 있습니다. (AWS 공식 제공)
'AWS > 운영관련 개발' 카테고리의 다른 글
[boto3] Your pagination token does not match your request (0) | 2023.07.27 |
---|---|
AWS monitoring - Cloud Watch 기반 S3 size 수집 (0) | 2019.11.16 |
소중한 공감 감사합니다