안녕하세요.


Cross Account 간에 AssumeRole을 활용하여 IAM 계정 및 Access Key 조회하는 방법을 확인해보겠습니다.


동일한 Account에서는 A 리소스에서 B 리소스에 접근하기 위해 고려해야 할 사항이 적습니다만, 다중 Account에서는 고려해야 할 사항이 증가하게 됩니다.

(IAM Policy, AssoumeRole, .. Session Token, ..)


그 중, IAM Role 및 AssumeRole을 활용한 교차 계정 간 IAM 제어하는 방법에 대해 알아보겠습니다.



목차는 다음과 같습니다.


1. 실습 아키텍처 설명


2. 실습


    1) A 계정에서 IAM Role, Policy 생성

        A 계정에서 B 계정을 신임하도록 설정합니다.


    2) B 계정에서 IAM Role, Policy 생성

        B 계정에서 A 계정을 신임하도록 설정합니다.


    3) B 계정에서 Lambda 생성


    4) B 계정 Lambda에서 Python Boto3 SDK를 사용하여 A 계정의 IAM User 리스트를 조회하는 방법 및 코드 설명



1. 아키텍처 설명


테스트를 진행할 아키텍처는 다음과 같습니다.


IAM Role, Policy


1) A 계정

    - A 계정 Role을 사용하여 B 계정의 Lambda에서 A 계정의 IAM 유저 내역을 조회해야 하기 때문에, IAM 유저 조회하는 권한이 필요합니다.

    - 신뢰 관계는 B 계정의 특정 Role을 신임할 수 있도록 설정해야 합니다. (이 부분이 중요합니다. Cross Account 간 IAM 제어를 하기 위해서는 A 계정에서 B 계정에 대한, B 계정에서 A 계정에 대한 권한 제어가 필요합니다.)


2) B 계정

    - A 계정의 특정 Role을 사용해야 하기 때문에 A 계정에 있는 Role에 대해 sts:AssumeRole을 Action을 Allow 해주는 Policy를 추가해야 합니다.

    - 신뢰 관계는 해당 Role이 B 계정 Lambda에서 수행되기 때문에, B 계정의 Lambda를 신뢰해야 합니다.




2. 실습


A 계정 : 11111111111 이라고 가정하며, B 계정 : 22222222222 라고 가정하겠습니다.


1) A 계정에서 IAM Role, Policy 생성 


[권한]

A 계정에서의 Role 권한은 평범하게 IAM 유저 및 Access Key를 조회하는 권한입니다.


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListIAMUserandListAccessKeys",
            "Action": [
                "iam:ListUsers",
                "iam:ListAccessKeys"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}


[신뢰 관계]

A 계정은 B 계정의 특정 Role(LambdaRole)만을 신뢰하겠다는 신뢰 관계를 기입해줍니다.

이로써 B 계정에서 sts:AssumeRole Action을 수행할 수 있게 됩니다.


{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::2222222222:role/LambdaRole"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}


위 내용을 Web Console을 통해 진행해보겠습니다.



A. 권한 생성




B. 역할 생성


신뢰할 수 있는 유형의 개체 선택 : 다른 AWS 계정

(해당 부분은 추후 B 계정의 특정 Role만 신뢰할 수 있도록 변경할 예정입니다.)

계정 ID : B 계정의 어카운트 넘버 ex)22222222222




적절한 이름을 부여한 뒤 생성해줍니다.




C. 역할 - 신뢰 관계 수정

역할에 들어간 뒤 신뢰 관계 - 신뢰 관계 편집을 클릭해줍니다.



Principle을 root에서 role/LambdaRole으로 변경해줍니다.

이로써, B 계정의 특정 Role만을 신뢰할 수 있도록 변경되었습니다.



2) B 계정에서 IAM Role, Policy 생성


이제, B 계정의 Lambda에서 A 계정의 IAM_AccessKey_List_Role에 대해 sts:AssumeRole을 수행할 수 있는 Role을 생성하면 됩니다.


[권한]


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::11111111111:role/IAM_AccessKey_List_Role"
        }
    ]
}


[신뢰 관계]


이 부분은 평소 하시던 대로 Lambda를 클릭하시면 되겠습니다.


위 내용을 웹 콘솔상에서 진행해보겠습니다.


A. 역할 생성

신뢰할 수 있는 유형의 개체 선택 : Lambda


권한의 경우 A 계정에서 한 내용과 다르게 'Inline Policy'로 하겠습니다.

(별도의 IAM Policy를 생성하지 않고 Role 내에 바로 부여할 수 있도록 하겠습니다. 별도로 IAM Policy를 생성해도 무방합니다.)



정책은 아래와 같이 생성해주었습니다.

'인라인 정책 추가'를 클릭하신 뒤 JSON 형식의 Policy를 추가하시면 됩니다.



3) B 계정에서 Lambda 생성


함수 이름 : 임의로 지어줍니다.

런타임 : Lambda 함수가 어떤 언어(런타임)에서 동작할 것인지 정하는 부분입니다.

권한 : 기 생성한 Role을 사용하도록 합니다.



4) B 계정 Lambda에서 Python Boto3 SDK를 사용하여 A 계정의 IAM User 리스트를 조회하는 방법 및 코드 설명


코드는 아래와 같이 간단히 A 계정의 IAM 유저를 조회할 수 있도록 작성해보았습니다.


import boto3

def lambda_handler(event, context):

    sts_client = boto3.client('sts')
    another_account = sts_client.assume_role(
        RoleArn="arn:aws:iam::11111111111:role/IAM_AccessKey_List_Role",
        RoleSessionName="cross_acct_lambda"
    )
    
    ACCESS_KEY = another_account['Credentials']['AccessKeyId']
    SECRET_KEY = another_account['Credentials']['SecretAccessKey']
    SESSION_TOKEN = another_account['Credentials']['SessionToken']

    # create service client using the assumed role credentials
    client = boto3.client(
        'iam',
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )
    
    response = client.list_users()
    print(response)


AWS는 API 기반으로 동작하며, 각 API(IAM, EC2, RDS, ..)를 Python,NodeJS, Java 등에서도 사용할 수 있도록 SDK(Software Development Kit)를 제공합니다.


Python에서는 Boto3를 사용할 수 있겠습니다.


Boto3는 Client(Low Level)와 Resource(High Level)을 제공하며, 선호에 맞게 사용하실 수 있습니다.


Client의 경우 Json 형식으로 값을 받아오게 됩니다.



위 코드를 살펴보자면, 


sts:assume_role을 사용하여 A 계정의 Role을 사용할 수 있는 권한ACCESS_KEY, SECRET_KEY, SESSION_TOKEN을 통해서 부여받게 됩니다.

해당 Token 값을 이용하여 A 계정에 대한 인증, 인가를 수행한 뒤 list_users() 메서드를 사용하여 response를 받는 코드입니다.


< 참고 문헌 >

Boto3 IAM Docs : https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iam.html

Boto3 STS Docs : https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html


Deploy를 클릭하여 해당 소스 코드를 배포한 뒤, Test를 해보겠습니다. 



Input Parameter는 해당 코드랑 영향도가 없기 때문에 default로 만들었습니다.



성공적으로 Lambda 코드에서 A 계정의 IAM 유저 내역을 불러왔습니다.



이로써 간단히 A 계정과 B 계정간 Cross Account에서의 AssumeRole을 활용한 테스트를 진행해보았습니다.


감사합니다.