안녕하세요.
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을 활용한 테스트를 진행해보았습니다.
감사합니다.