개요

AWS EC2 를 사용 하다보면 비용을 줄이고자 미사용 시간에 정지를 해야할 필요가 있다

이를 Lambda 와 EventBridge 로 구성하면 모든 EC2 에 대하여 자동으로 관리가 가능하다

 


 

작업내용

Lambda 코드 작성

EventBridge 설정

 


 

상세 작업

 

1. Lambda 코드

  • boto3 ec2 client 를 사용한다
  • ec2.describe_instances() 를 사용하여 현재 생성된 전체 EC2의 Instance_id 를 추출한다
  • ec2 client 의 ec2.stop_instances 를 사용하여 추출한 Instance_id 의 EC2를 종료 한다
import boto3

def lambda_handler(event,context):
    # Get the EC2 client
    ec2 = boto3.client('ec2')
    
    # Get the list of all instances
    describe_instance_assets = ec2.describe_instances()

    
    ec2_instance_list =[]
    for reservation in describe_instance_assets['Reservations']:
        for instance in reservation['Instances']:
            instance_id = instance['InstanceId']
            
            ec2_instance_list.append(instance_id)
            ec2.stop_instances(InstanceIds=[instance_id])
            
    # print(ec2_instance_list)

 

※주의사항

Lambda의 정상적인 실행을 위해서는 Lambda 권한에 EC2 제어 권한이 필요하다

 

 

2. EventBridge 설정

  • EventBridge - 일정 부분에 스케줄을 생성 한다

  • 일정 패턴 편집
  • 원하는 시간대로 설정
  • 시간대를 Asia/Seoul 로 설정하면 현지 시간으로 지정이 가능하다

  • 대상으로 람다 지정
  • 추가 설정 확인(불필요함으로 미지정)

 

  • 위와같이 생성하면 Eventbidge 에서 자동으로 Lambda 를 실행할 권한을 생성하게 된다
  • 설정한 시간대에 EventBridge 가 실행 되고, Lambda 를 호출하여 모든 EC2를 종료 하게 된다

 

 

 

 

'AWS' 카테고리의 다른 글

RDS 이벤트 구독을 통한 RDS 관리  (1) 2024.01.07
EKS fargate 생성을 위한 설정  (0) 2023.12.18
AWS EKS LB Controller Install  (0) 2023.09.29
AWS EC2/RDS Instance 정보 조회 Lambda 코드  (0) 2023.09.24
Route53 라우팅 정책  (0) 2023.08.05

EventBridge 는 AWS 및 3rd Party 에서 발생하는 이벤트들을 수집하는 역할을 담당 하고 있다.

AWS 에는 여러가지 많은 서비스 들이 있는데 EventBridge 는 각 서비스들에서 발생 시키는 Event 에 대하여 트리거 설정을 할 수 있다.

 

[이해를 돕기위한 그림]

CloudTrail -----①----- EventBridge -----②----- SNS

설명
CloudTrail 에서 특정 이벤트가 발생 하였을 경우 그에 대한 이벤트 로그가 AWS 내부에 남게 된다
이때 발생한 이벤트 로그중 일부분을 EventBridge 에 설정(트리거 역할)
트리거조건이 충족되면 EventBridge 에서 설정한 다음 동작이 수행된다
SNS 뿐만아니라 Lambda 등 다양한 AWS 서비스를 연계시킬수 있다

설정 방법

 

1. EventBridge 생성

2. 샘플 이벤트 설정

  • 해당 샘플에서는 CloudTrail 에 대한 설정을 진행할 예정
  • 샘플 이벤트에서 CloudTrail 을 입력하면 여러가지가 나오는데 그중 아래와 같이 AWS API Call via CloudTrail 을 선택

 

3. 이벤트 샘플 JSON 확인

  • 이벤트 샘플을 선택하면 나오는 JSON 을 확인하여 필요한 조건을 지정
  • 해당 예시에서는 CloudTrail 을 사용해서 누가 특정한 Role 을 사용하는지 확인 하고 싶을때에 대한 예이다
  • 밑에 Json 구분중 userName 이 적힌 부분이 있을 것이다. 이부분을 트리거로 잡아서 알람을 발생 시킬예정
{
  "version": "0",
  "id": "a1aa69ff-66e8-c3eb-2e47-3776ac5935dd",
  "detail-type": "AWS API Call via CloudTrail",
  "source": "aws.resource-groups",
  "account": "123456789012",
  "time": "2022-02-17T09:42:52Z",
  "region": "us-east-1",
  "resources": [],
  "detail": {
    "eventVersion": "1.08",
    "userIdentity": {
      "type": "AssumedRole",
      "principalId": "XYZZYOR:admin",
      "arn": "arn:aws:sts::123456789012:role/admin",
      "accountId": "123456789012",
      "accessKeyId": "XYZZY",
      "sessionContext": {
        "sessionIssuer": {
          "type": "Role",
          "principalId": "XYZZYOR",
          "arn": "arn:aws:iam::123456789012:role/Admin",
          "accountId": "123456789012",
          "userName": "Admin"
        },
        "webIdFederationData": {},
        "attributes": {
          "creationDate": "2022-02-17T09:41:02Z",
          "mfaAuthenticated": "false"
        }
      }
    },
    "eventTime": "2022-02-17T09:42:52Z",
    "eventSource": "resource-groups.amazonaws.com",
    "eventName": "CreateGroup",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "52.94.133.138",
    "userAgent": "aws-cli/2.2.31 Python/3.8.8 Darwin/20.6.0 exe/x86_64 prompt/off command/resource-groups.create-group",
    "requestParameters": {
      "Description": "test6",
      "Name": "test301",
      "ResourceQuery": {
        "Type": "CLOUDFORMATION_STACK_1_0",
        "Query": "{ \"ResourceTypeFilters\": [ \"AWS::AllSupported\" ], \"StackIdentifier\": \"arn:aws:cloudformation:us-east-1:123456789012:stack/test/aa434df0-fe92-11eb-bde9-0a03f460991d\"}"
      }
    },
    "responseElements": {
      "Group": {
        "GroupArn": "arn:aws:resource-groups:us-east-1:123456789012:group/test301",
        "Name": "test301",
        "Description": "test6",
        "OwnerId": "123456789012"
      },
      "ResourceQuery": {
        "Type": "CLOUDFORMATION_STACK_1_0",
        "Query": "{ \"ResourceTypeFilters\": [ \"AWS::AllSupported\" ], \"StackIdentifier\": \"arn:aws:cloudformation:us-east-1:123456789012:stack/test/aa434df0-fe92-11eb-bde9-0a03f460991d\"}"
      }
    },
    "requestID": "31cabb57-0931-4cdb-b66b-137267531dd1",
    "eventID": "4d51d885-3d1f-4579-bf42-96924aadbc3f",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
  }
}

4. 트리거 설정

  • 위에 있는 Json 전체 코드중 userName 만 필요
  • userName 이 User-Name 인경우를 트리거 하는 코드는 아래와 같다
  • 생성방법에서 사용자 지정 패턴을 사용하여 아래 코드를 입력

{
    "source": ["aws.cloudtrail"],
    "detail": {
        "userIdentity": {
            "sessionContext": {
                "sessionIssuer": {
                    "userName": ["User-Name"]
                }
            }
        }
    }
}

5. 대상 동작 설정

  • 위와같은 트리거가 발생 하였을때 실행할 대상을 선택하는 곳

 

6. 결과 확인

  • 위와같이 설정을 하게되면 CloudTrail 에서 이벤트 발생시 EventBridge 가 작동해서 SNS 를 보내게 된다
  • SNS 메일로 오는 결과 값은 CloudTrail 전체 Json 에 있던 내용을 받게 된다

※참고자료

  • AWS 에서 발생하는 이벤트들은 AWS 에서 자체적으로 이벤트를 발생시켜 주기때문에 샘플을 사용하여 확인하면됨
  • AWS가 아닌 3rd Party 에서 발생하는 이벤트는 Lambda 를 통해 이벤트 발생을 시킬 수 있다.
  • 3rd Party 에서 Lambda 를 바로 호출 할 수 있다면 Lambda 를 바로 사용하면 되고, 그렇지 않을경우(대부분이 사설망이다보니 바로호출이 불가함) API Gateway 를통해서 Lambda 를 호출하면 된다.
  • 3rd Party[webhook] -> API gateway URL -> Lambda -> EventBridge -> SNS 순으로 완성되게 된다.

[Event 발생시키는 Lambda Code]

from datetime import datetime
import json
import boto3
import datetime

client = boto3.client('events')

def lambda_handler(event, context):

    response = client.put.events(
        Entries=[
            {
                'Time': datetime.datetime.now(),
                'Source': 'Lambda Publish',
                'Resources': [],
                'DetailType': 'Custom event demo'
                'Detail': json.dumps(event),
                'EventBusName': 'arn:aws:events:ap-northeast-2:xxxxxxxxxxxxxxxxxxxxxxxxxx:event-but/default'
            }
        ]
    )
return response

 

'AWS' 카테고리의 다른 글

EKS 최초 생성 권한 문제  (0) 2023.04.16
AWS LB Annotations  (0) 2023.01.23
AWS EKS nodegroup 생성 시 필요 조건  (0) 2023.01.20
AWS Instance Network Bandwidth  (0) 2022.10.30
AWS Certification 종류  (0) 2022.10.30

+ Recent posts