AWS/Project

Lambda를 활용해 다른 계정의 EC2 자동 중지

jih0ssang 2023. 11. 4. 17:41

참조 블로그:

 

Organizations 마스터 계정에서 멤버 계정의 EC2를 특정 시간대에 자동 중지되도록 스케줄을 설정하려고 한다.

 

해야할 일

  • Master 계정의 Lambda 코드 수정: 멤버들의 계정 다 적어야함 리스트로 몰아 넣기
  • Member 계정의 IAM Role, Policy 생성  CloudFormation Template 만들기     완료

멤버 계정(多) 모두 리스트로 몰아넣는 것이 정말 효율적인 선택인가

최적화 해 야 지

 

 

Master 계정에서 Member 계정의 EC2 자동 중지 설정

1. Master 계정에서 IAM Role, Policy 생성

2. Member 계정에서 IAM Role, Policy 생성

3. Master 계정에서 Lambda 생성

4. Master 계정 Lambda에서 Python Boto3 SDK를 사용하여 Member 계정의 EC2 리스트 조회 및 중지 코드 작성

 

빨간색 상자로 가린 건 Master계정, 초록색 상자로 가린 건 Member 계정이다.

 

1. Member 계정에서 IAM Role, Policy 생성

Master 계정에게 Member 계정의 "EC2의 리스트 조회, 중지" 권한을 부여하기 위해

Member 계정에 로그인 하여 IAM Role, Policy를 생성해야 한다.

권한을 좁여서 설정해도 되지만, 그냥 이미 있는 AmazonEC2FullAccess를 Policy로 지정하여 Role(EC2StopRole)을 생성했다.

 

[신뢰 관계] 에서 Member 계정은 Master 계정의 특정 Role(EC2StopMasterRole)만을 신뢰하겠다는 신뢰 관계를 기입한다.

여기서 "Principal"에는 master 계정ID(지운 부분)을 적어야 하고, EC2StopMasterRole은 Master 계정의 Role이다. 

 

2. Master 계정에서 IAM Role, Policy 생성

Master 계정에 로그인 하여 IAM Role, Policy를 생성해야 한다.

IAM Role(EC2StopMasterRole)을 먼저 생성한 후, 인라인 정책 생성으로 Policy를 생성했다.

(앞과 같이, 별도의 IAM Policy를 생성하여 지정해도 무방함)

 

{
	"Version": "2012-10-17",
    "Statement": [
    	{
        	"Sid": "Statement1",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::(MEMBER계정 ID):role/EC2StopRole"
        }
     ]
}

AssumePlicyForCrossAccount 정책(JSON 형식) 내용은 다음과 같다.

 

3. Master 계정에서 Lambda 생성

Lambda 이름: LambdaSchedule

런타임은 파이썬 코드로 작성할 것이므로 Python 3.8 버전으로 지정한다.

실행 역할은 생성해두었던 IAM Role(EC2StopMasterRole)을 지정한다.

Lambda를 생성하면 기본적으로 제한 시간이 3초로 걸려있는데 10초 혹은 그 이상으로 수정하기 바란다.

 

4. Master 계정 Lambda에서 Python Boto3 SDK를 사용하여 Member 계정의 EC2 리스트 조회 및 중지 코드 작성

 

lambda_function.py

import boto3
region = 'ap-northeast-2'
instances = []

def lambda_handler(event, context):
	sts_client = boto3.client('sts')
    another_account = sts_client.assume_role(
    	RoleArn="arn:aws:iam::(Member계정 ID):role/EC2StopRole",
        RoleSessionName="RoleSessionName"
    )
    ACCESS_KEY = another_account['Credentials']['AccessKeyId']
    SECRET_KEY = another_account['Credentials']['SecretAccessKey']
    SESSION_TOKEN = another_account['Credentials']['SessionToken']
    
    session = boto3.Session(
    	aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN
    )
    
    ec2_r = session.resource('ec2')
    ec2 = session.client('ec2'. region_name=region)
    
    for instance in ec2_r.instances_all():
    	instances.append(instance.id)
    ec2.stop_instances(InstanceIds=instances)

 

sts:assume_role을 사용하여 Member 계정의 Role을 사용할 수 있는 권한을

ACCESS_KEY, SECRET_KEY, SESSION_TOKEN을 통해 부여받게 된다.

해당 Token 값을 이용해 Member 계정에 대한 인증을 수행한 뒤, Member 계정의 EC2를 끄는 코드이다.

 

 

Member 계정 IAM Role, Policy 생성하는 CloudFormation 스크립트

 

원래는 저렇게 계정 ID 때려박으면 안되지만.... 때려박았다.