본문 바로가기
AWS/Lambda

Cloudwatch와 Lambda를 사용한 자동화 작업

by Ate1es 2022. 10. 17.

오늘은 Cloudwatch 에서 이벤트가 발생할 시 Lambda에 올려둔 코드가 실행되면서,

인스턴스들을 자동으로 컨트롤하는 실습을 해보려한다.

 

클라우드 인프라를 운영 시 Cloudwatch + Lambda 조합은 자동화 작업에 있어서 굉장히 다양하게 사용될 수 있다고 생각하기 때문에 직접 간소화하여 구현해보려한다.

 

구성


실습 아키텍처

사전 작업 1 - Lambda 작업을 위한 IAM Role 생성

아래와 같이 필요한 권한을 정의 후 Policy 생성 해준다.

Policy 생성


그 다음, Lambda 실행에 필요한 역할을 생성 후 위에서 만든 Policy 연결 해준다.

Policy 연결


사전 작업2 - 실습에 필요한 리소스 생성(웹서버로 생성되는 EC2 4개를 사용할 것. CloudFormation 으로 생성 자동화)

 

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: keyLambda.pem
  LatestAmiId:
    Description: (DO NOT CHANGE)
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
    AllowedValues:
      - /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: WebServer
      SecurityGroups:
        - !Ref MySG
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum install httpd -y
            systemctl start httpd && systemctl enable httpd
            echo "<h1>Test Web Server</h1>" > /var/www/html/index.html

 
  MyInstance2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: WebServer2
      SecurityGroups:
        - !Ref MySG
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum install httpd -y
            systemctl start httpd && systemctl enable httpd
            echo "<h1>Test Web Server2</h1>" > /var/www/html/index.html
  
 
  MyInstance3:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: WebServer3
      SecurityGroups:
        - !Ref MySG
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum install httpd -y
            systemctl start httpd && systemctl enable httpd
            echo "<h1>Test Web Server3</h1>" > /var/www/html/index.html
 
  MyInstance4:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: WebServer4
      SecurityGroups:
        - !Ref MySG
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            yum install httpd -y
            systemctl start httpd && systemctl enable httpd
            echo "<h1>Test Web Server4</h1>" > /var/www/html/index.html
  
  MySG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0

사전 작업 3 - Lambda가 자동으로 Start, Stop 시킬 인스턴스들은 태그를 입력해준다.

(CloudFormation에 할수도 있지만, 콘솔에서 따로 해줌)


3, 4번 서버에 AutoStart, AutoStop 태그 걸어준다.

 

사전 작업 4 - Lambda 함수 및 트리거 생성

 

Lambda 함수는 Python 의 boto3 라이브러리를 사용해서 작성해주었다.

트리거가 발생되면 해당 코드로 ec2 리소스를 불러와 컨트롤 하는 코드이다.

 

코드 작성 후 꼭 Deploy 하자. 안하면 다날아감...

import boto3

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2')
    filters = [{
        'Name':'tag:AutoStart',
        'Values':['True']
    },
    {
        'Name':'instance-state-name',
        'Values':['stopped']
        }]
    instances = ec2.instances.filter(Filters=filters)
    StoppedInstances = [instance.id for instance in instances]
    
    if len(StoppedInstances) > 0:
        StartInstances = ec2.instances.filter(InstanceIds=StoppedInstances).start()
        print(StartInstances)
    else:
        print("Nothing")

 

Lambda 함수의 트리거는 CloudWatch Event로 구성하고,

예약 표현식을 통해 매일 우리나라 시간 기준 오후 3시에 EC2를 Start 하도록 구성했다.

 

이제 구성은 끝났다. Lambda 함수가 트리거 될때까지 (3시까지) 기다렸다가, EC2 3번 4번 서버가 Start 되고, 

Cloudwatch Log에 찍히는지 확인하면 됨.

[실제 저는 3시 16분으로 테스트함 빨리보려고]

 

아래 처럼 중지시켜뒀던, 3번 4번 서버가 자동으로 Start 된것을 볼 수 있다.

서버 Start

 

Cloudwatch Logs에 가보면, Lambda 함수가 생성한 로그 그룹이 있는데

그곳에도 3시 16분 기준으로 로그가 찍혀있는 것을 확인할 수 있다.

Cloudwatch logs

 

 

 

 

'AWS > Lambda' 카테고리의 다른 글

[AWS] Lambda - 1  (0) 2022.06.23