AWS StepFunction을 이용하여 AutoScaling Group의 인스턴스를 정기적으로 재부팅하기

AWS StepFunction을 이용하여 AutoScaling Group 내의 EC2 인스턴스를 정기적으로 재부팅하는 방법에 대하여 알아보는 글입니다.
2024.03.30

안녕하세요 클래스메소드의 수재입니다.
AutoScaling Group(이하 ASG)를 도입하여 운용할 떄 그룹 내의 인스턴스를 StepFunction을 이용하여 정기적으로 재부팅하는 방법에 대해 알아보겠습니다.

EC2를 바로 재부팅하면 안되나요?

ASG에 포함되어 있는 인스턴스를 그대로 재부팅하게 되면 상태확인에 실패하게 되어 그대로 인스턴스가 종료(terminated)됩니다.
따라서 이를 피하기 위해서는 다음 방법 중 한가지를 적용한 후 인스턴스를 재부팅 할 필요가 있습니다.

  • 인스턴스 상태를 대기로 설정
  • ASG에서 인스턴스 분리
  • AutoScalling의 상태 확인 프로세스 중지

위의 방법은 AWS 콘솔에서 수동으로 설정하는 것도 가능합니다.
이미 AWS의 지식 섹터에 관련 내용의 절차가 있으므로 해당 글을 참고해보세요.

이번 글에서는 Lmagda와 EventBridge를 이용하여 해당 절차를 자동화하는 방법에 대해 설명하려 합니다.

정기적인 재부팅이 필요한가요?

평범하게 컴퓨터를 사용할 때도 한번씩 재부팅을 해줘야하는 것 처럼 EC2도 정기적으로 재부팅하는 것을 권장하고 있습니다.
또한 운영체제 내부에서 재부팅을 실행하는 것보다 인스턴스 자체를 재부팅하는 것을 추천하고 있습니다.

이 외에 중요한 보안 패치 등을 이유로 재부팅이 요구될 때도 있습니다.

자동화해보기

자동화를 위해서 Lambda와 EventBridge를 조합하여 하는 경우도 많습니다.

이번에는 AWS Stepfunction을 이용해서 코드를 이용하지 않고 구현하는 방법에 대해 알아보겠습니다.

IAM 작성

StepFunction을 이용하여 각 리소스를 조작하기 위해서는 IAM Policy를 설정할 필요가 있습니다.
StepFunction에는 최소 아래의 Policy가 필요합니다.

  • "autoscaling:EnterStandby"
  • "autoscaling:ExitStandby"
  • "autoscaling:DescribeAutoScalingGroups"
  • "ec2:RebootInstances"

리소스는 필요한 리소스를 조정해주시면 됩니다.
인스턴스가 항상 바뀐다면 특정 태그를 가지고 있는 리소스에 대해 권한을 가지도록 설정하면 리소스를 쉽게 재한할 수 있습니다.

그리고 정기적으로 이를 실행하기 위해 EventBridge를 설정하는데 필요한 IAM Role에는 다음 Plicy가 필요합니다.

  • "states:StartExecution"

State Machine 작성

State의 흐름은 다음과 같습니다.

  • 특정 ASG의 이름을 입력 받으면 인스턴스 목록 가져오기
    • ASG를 운용하다 보면 인스턴스가 바뀌는 경우가 빈번하기 때문에 가동중인 인스턴스 목록을 가져오는게 좋을 것 같다고 생각되어 이렇게 작성했습니다
  • 인스턴스 ID만 추출
  • 해당 인스턴스 StandBy로 설정
  • 인스턴스 재부팅
  • 인스턴스를 InService로 설정

디자이너로 보면 위와 같습니다.
ID를 추출하는 방법 등은 더 효율적인 방법이 있을지도 모르겠네요.
StandBy로 바꾸는 과정에서 [ShouldDecrementDesiredCapacity]옵션은 필요에 따라 true,false를 지정해주세요.

코드로 보면 다음과 같습니다.

{
  "Comment": "A description of my state machine",
  "StartAt": "DescribeAutoScalingGroups",
  "States": {
    "DescribeAutoScalingGroups": {
      "Type": "Task",
      "Parameters": {
        "AutoScalingGroupNames.$": "$.ASGName"
      },
      "Resource": "arn:aws:states:::aws-sdk:autoscaling:describeAutoScalingGroups",
      "Next": "Map",
      "OutputPath": "$.AutoScalingGroups[0]"
    },
    "Map": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": {
          "Mode": "INLINE"
        },
        "StartAt": "Pass",
        "States": {
          "Pass": {
            "Type": "Pass",
            "End": true,
            "OutputPath": "$.InstanceId"
          }
        }
      },
      "InputPath": "$.Instances",
      "ResultPath": "$.Instances",
      "Next": "EnterStandby"
    },
    "EnterStandby": {
      "Type": "Task",
      "Parameters": {
        "AutoScalingGroupName.$": "$.AutoScalingGroupName",
        "ShouldDecrementDesiredCapacity": "true",
        "InstanceIds.$": "$.Instances"
      },
      "Resource": "arn:aws:states:::aws-sdk:autoscaling:enterStandby",
      "Next": "RebootInstances",
      "ResultPath": null
    },
    "RebootInstances": {
      "Type": "Task",
      "End": true,
      "Parameters": {
        "InstanceIds.$": "$.Instances"
      },
      "Resource": "arn:aws:states:::aws-sdk:ec2:rebootInstances"
    }
  }
}

IAM Role을 지정하고 테스트를 해본 후 문제가 없으면 다음으로 넘어갑니다.

EventBridge 작성

마지막으로 정기적으로 State를 실행하기 위한 EventBridge Scheduler을 작성합니다.
이번에는 매달 마지막 일요일에 정지적으로 재부팅하도록 하는 일정을 작성하였습니다.

다음으로 실행할 State를 지정하고 Input을 입력합니다.

재실행 룰과 작성해두었던 IAM Role을 지정하고 문제가 없다면 작성합니다.

마지막으로 작성된 일정에 문제가 없는지 확인합니다.

마무리

ASG를 운용하며 EC2를 정기적으로 재부팅하여 서비스 운용에 문제가 없도록 합시다.
여기에 소개된 StepFunction 이외에 Lambda 를 활용하는 방법 등도 있으니 확인해보시길 바랍니다.

긴 글 읽어주셔서 감사합니다.
내용 및 오탈자 피드백은 must01940 지메일로 보내주시면 감사합니다.