1. 목적
-
AutoScaling을 사용하는 중 매일 AMI 갱신 자동화가 필요한 고객사에 적용하기 위함
2. 내용
-
구성 정보
-
참고
- Lambda는 AMI 생성과 ASG AMI 갱신 두개로 나뉘어 동작 한다.
- 이유는 AMI 생성 시 State : Available로 되기까지 길게는 수십분 소요되는데, Lambda 동작 제한시간은 최대 15분이기 때문에 한 코드로 진행이 불가하다.
- Pending 상태에서도 AMI 갱신까지 처리는 가능하지만, 만약 Available이 되지 않았는데 AutoScaling이 발생할 경우 정상적으로 Scale-Out이 될 수 없어 장애로 이어질 수 있다.
- 위 내용을 해소하기 위해 두가지 작업을 분리하였다.
-
코드 설명
1. AMI 생성
- 필수 수정 항목
: c2id 에 원본 AMI 대상이 될 인스턴스 ID를 입력한다.
- 코드import boto3
ec2id = 'i-xxxxxxxxx'
def AMI(ec2client):
AMIName = ['[ASG]Auto_AMI_1','[ASG]Auto_AMI_2']
try:
if ec2client.describe_images(
Filters=[
{
'Name': 'name',
'Values': [AMIName[0]]
}])['Images'][0]['Name'] == AMIName[0]:
Ceimg = str(AMIName[1])
except IndexError:
Ceimg = str(AMIName[0])
ec2client.create_image(
InstanceId = ec2id,
Name = Ceimg,
NoReboot=True
)
def lambda_handler(event, context):
ec2client = boto3.client('ec2')
AMI(ec2client)
2. ASG AMI 갱신
- 필수 수정 항목
: ASGName 에 대상이 될 오토스케일링그룹 이름을 입력한다.
: userdata 에 기존 시작구성 > 사용자 데이터란에 있는 명령어 정보를 입력한다. 줄바꿈의 경우 \n을 입력한다.
: 원본 시작구성 정보에 따라 주석을 해제 또는 설정한다(코드 내용 개별 수정 필요).
-코드import boto3
ASGName = 'TEST_AutoChangeLC'
userdata = "systemctl stop nimbus\nrpm -e nimsoft-robot-7.90.beta3-1.x86_64"
def AMI(ec2client):
global AMIID
AMIName = ['[ASG]Auto_AMI_1','[ASG]Auto_AMI_2']
img1 = ec2client.describe_images(Filters=[{'Name': 'name','Values': [AMIName[0]]}])['Images'][0]
img2 = ec2client.describe_images(Filters=[{'Name': 'name','Values': [AMIName[1]]}])['Images'][0]
Ceimg = str(AMIName[1]) if img1['CreationDate'] < img2['CreationDate'] else str(AMIName[0])
Deimg = str(AMIName[0]) if img1['CreationDate'] < img2['CreationDate'] else str(AMIName[1])
ec2client.deregister_image(
ImageId=ec2client.describe_images(
Filters=[
{
'Name': 'name',
'Values': [Deimg]
}])['Images'][0]['ImageId'])
AMIID = ec2client.describe_images(
Filters=[
{
'Name': 'name',
'Values': [Ceimg]
}])['Images'][0]['ImageId']
def ASG(asgclient):
LCName = ['AutoLC_#1','AutoLC_#2']
try:
if asgclient.describe_launch_configurations(LaunchConfigurationNames=[LCName[0]])['LaunchConfigurations'][0]['LaunchConfigurationName'] == LCName[0]:
CeName = str(LCName[1])
DeName = str(LCName[0])
except IndexError:
CeName = str(LCName[0])
DeName = str(LCName[1])
Deslc = asgclient.describe_launch_configurations(LaunchConfigurationNames=[DeName])
SGList = []
for i in range(len(Deslc['LaunchConfigurations'][0]['SecurityGroups'])):
SGList.append(Deslc['LaunchConfigurations'][0]['SecurityGroups'][i])
asgclient.create_launch_configuration(
LaunchConfigurationName=CeName,
ImageId=AMIID,
KeyName=Deslc['LaunchConfigurations'][0]['KeyName'],
SecurityGroups=SGList,
# ClassicLinkVPCId=Deslc['LaunchConfigurations'][0]['ClassicLinkVPCId'],
ClassicLinkVPCSecurityGroups=Deslc['LaunchConfigurations'][0]['ClassicLinkVPCSecurityGroups'],
UserData=userdata,
# InstanceId=Deslc['LaunchConfigurations'][0]['InstanceId'],
InstanceType=Deslc['LaunchConfigurations'][0]['InstanceType'],
# KernelId=Deslc['LaunchConfigurations'][0]['KernelId'],
# RamdiskId=Deslc['LaunchConfigurations'][0]['RamdiskId'],
InstanceMonitoring={'Enabled': Deslc['LaunchConfigurations'][0]['InstanceMonitoring']['Enabled']},
# SpotPrice=Deslc['LaunchConfigurations'][0]['SpotPrice'],
IamInstanceProfile=Deslc['LaunchConfigurations'][0]['IamInstanceProfile'],
EbsOptimized=Deslc['LaunchConfigurations'][0]['EbsOptimized']
# AssociatePublicIpAddress=Deslc['LaunchConfigurations'][0]['AssociatePublicIpAddress'],
# PlacementTenancy=Deslc['LaunchConfigurations'][0]['PlacementTenancy']
)
asgclient.update_auto_scaling_group(AutoScalingGroupName = ASGName,LaunchConfigurationName = CeName)
asgclient.delete_launch_configuration(
LaunchConfigurationName=DeName
)
def lambda_handler(event, context):
ec2client = boto3.client('ec2')
AMI(ec2client)
asgclient = boto3.client('autoscaling')
ASG(asgclient)
-
사용 방법
1. Lambda 생성
- Python 버전은 3.8로 생성한다.
: AMI 생성과 ASG갱신 두가지 Lambda로 생성해야 한다.
- Rule은 Policies:AmazonEC2FullAccess 와 AutoScalingFullAccess로 생성한다.
: 위 정책만 있으면 기본 동작은 가능하나 시작구성 내용 중 IAMInstanceProfile에 등록되어있는 역할에 따라 정책 정보가 추가 된다. 내용 확인하여 필요한 정책을 추가한다.
:크게 이슈사항이 없다면 AdministratorAccess 추가한다.(권장하지 않음)
2. 함수 업로드
- 첨부된 파일을 이용하여 각각에 파일 업로드 진행한다.
- Lambda 구성 > 일반구성 > 제한시간 값을 3초에서 10초로 변경한다.
3. 시작구성 복사
- 기존 사용하던 시작구성을 복사하여 AutoLC_#1 또는 AutoLC_#2로 생성한다.
4. ASG_AMI_AutoUpdate_Step1 두번 실행하여 AMI를 2개 생성(필수!)
- [ASG]Auto_AMI_1, [ASG]Auto_AMI_2 두개 생성 확인(상태 available 체크)
5. ASG_AMI_AutoUpdate_Step2 실행
- Lambda로 생성된 AMI 중 먼저 생성된 AMI는 제거되며, 최신 AMI ID를 이용해 시작구성 복사 및 ASG 정보갱신
- 기 생성된 AutoLC_#1를 기반으로하여 신규 AMI정보 i-~1f6b 정보로 업데이트 된 시작구성 AutoLC_#2가 생성
- 등록된 AutoScaling그룹의 시작구성 변경 확인
- ASG 수량 증가시 해당 시작구성으로 인스턴스 올라오는 것 확인
-
[참고] 생성된 람다 리스트
-
참고
3. [추가]CloudWatch Event 적용
-
트리거 추가
-
각 람다마다 개별로 트리거 추가하여 cron 동작하도록 설정
- AMI 생성 소요시간에 따라 cron 개별 조정
-
각 람다마다 개별로 트리거 추가하여 cron 동작하도록 설정