AssumeRole을 적용해야하는지 판단하기
AssumeRole API를 적용할 필요성이 있는지 먼저 확인해봐야합니다.
AssumeRole이 필요한 상황
아래의 2가지 에러가 발생한 경우에는 AssumeRole이 대안이 될 수 있습니다.
- API를 호출할 권한이 없는 경우
- is not authorized to perform: aws-marketplace:ResolveCustomer because no identity-based policy allows the aws-marketplace:ResolveCustomer action
- AWS Marketplace Seller Account가 아닌 경우
- User is not authorized to call ResolveCustomer for this product.
직접 판단해보기
AWS Marketplace Seller 계정에서는 API를 사용하기 위해서 아래의 Role을 사용합니다.
// https://docs.aws.amazon.com/marketplace/latest/userguide/iam-user-policy-for-aws-marketplace-actions.html#iam-user-policy-for-saas-products
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"aws-marketplace:ResolveCustomer",
"aws-marketplace:BatchMeterUsage"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
그런데 운영 환경에 배포하려고 보니 아래와 같은 문제를 마주할 수 있습니다.
- AWS Marketplace 제품을 등록한 Seller 계정과 운영 환경의 EC2를 관리하는 계정을 분리하고 싶다.
- AWS Marketplace ResolveCustomer API는 반드시 Seller Account에서 호출되어야 한다
이러한 설명한 문제와 마주했다면 AssumeRole을 사용하면 해결할 수 있습니다.
권한 설정하기
AWS Marketplace Seller 계정에서 해야하는 것
AWS Marketplace API에 필요한 정책을 추가한 Role ARN을 생성합니다.
그리고 생성된 Role의 신뢰 관계에 EC2 관리 계정를 추가하면 됩니다.
EC2 관리 계정에서 해야하는 것
Seller 계정에서 생성된 Role에 대해 AssumeRole을 호출할 수 있는 EC2 관리 계정의 Role을 생성 (EC2 관리 계정에는 ResolveCustomer 권한이 없지만, Seller 계정의 권한을 가져와서(AssumeRole) ResolveCustomer를 호출할 수 있는 권한을 임시적으로 가진다.)
AssumeRole 코드에 적용하기
여기까지 설정되면 코드는 아래와 같이 작성할 수 있습니다.
StsClient stsClient = getStsClient();
Credentials credentials = assumeRole(stsClient, conf.aws_marketplace_assume_role_arn);
AWSMarketplaceMeteringClientBuilder builder = AWSMarketplaceMeteringClientBuilder.standard();
BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
credentials.accessKeyId(),
credentials.secretAccessKey(),
credentials.sessionToken());
builder.setCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials));
this.marketplaceClient = builder.build();
하나씩 뜯어보겠습니다. AssumeRole을 호출하기 위한 StsClient를 생성합니다.
private StsClient getStsClient() {
if (stsClient != null) {
return stsClient;
}
stsClient = StsClient.create();
return stsClient;
}
StsClient를 생성할 때 EC2 관리 계정에서 추가한 RoleARN이 필요합니다. 아래와 같이 SystemProperties를 사용하거나, EC2에 RoleARN을 지정합니다.
아래의 두 포스팅을 참고해주세요.
2024.01.16 - [개발/AWS Marketplace] - AWS API에 사용할 Access Key, Access Secret Key 발급하는 방법
2024.01.16 - [개발/AWS Marketplace] - AWS API에서 AccessKey, SecretAccessKey 대신 Role ARN 사용하기
private void setAwsRegionProps() {
System.setProperty("aws.region", conf.aws_marketplace_region);
}
private void setStsClientProps() {
// @See software.amazon.awssdk.services.sts.StsClient.create
// @See software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider
System.setProperty("aws.accessKeyId", conf.aws_marketplace_access_key);
System.setProperty("aws.secretAccessKey", conf.aws_marketplace_secret_access_key);
}
다음으로 생성된 StsClient로 AssumeRole을 호출합니다.
private Credentials assumeRole(StsClient stsClient, String roleArn) {
AssumeRoleRequest roleRequest = AssumeRoleRequest.builder()
.roleArn(roleArn)
.roleSessionName("whatap-aws-mp-session-" + DateUtil.now())
.build();
AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest);
Credentials myCreds = roleResponse.credentials();
Instant exTime = myCreds.expiration();
assumeRoleExpirationTime = exTime.toEpochMilli();
logger.info("[AWS AssumeRole] success. assumeRoleExpiredTime : {}", DateUtil.datetime(assumeRoleExpirationTime));
return myCreds;
}
주의할 사항은 AssumeRole에는 만료 시간이 있다는 것입니다. 기본 1시간동안만 권한을 가져올 수 있습니다. 이 시간이 지나면 다시 AssumeRole을 호출해야합니다.
이렇게 가져온 Credentials 정보로 아래와 같이 AWS Marketplace Client를 생성할 수 있습니다
Credentials credentials = assumeRole(stsClient, conf.aws_marketplace_assume_role_arn);
AWSMarketplaceMeteringClientBuilder builder = AWSMarketplaceMeteringClientBuilder.standard();
BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
credentials.accessKeyId(),
credentials.secretAccessKey(),
credentials.sessionToken());
builder.setCredentials(new AWSStaticCredentialsProvider(basicSessionCredentials));
this.marketplaceClient = builder.build();
만료 시간이 지났을 때 새로 AssumeRole을 호출하는 로직에는 아래의 Gist에 포함되어 있습니다. 자세한 코드는 gist를 확인해주세요.
'AWS > AWS Marketplace' 카테고리의 다른 글
AWS Marketplace 연동 가이드 | 02. AWS Marketplace Client 생성하기 (0) | 2024.01.17 |
---|---|
AWS Marketplace 연동 가이드 | 01. AWS Marketplace Seller 계정 생성부터 x-amzn-marketplace-token 토큰 수신까지 (0) | 2024.01.17 |
AWS API에서 AccessKey, SecretAccessKey 대신 Role ARN 사용하기 (0) | 2024.01.16 |
AWS API에 사용할 Access Key, Access Secret Key 발급하는 방법 (0) | 2024.01.16 |
AWS Marketplace API Region 확인하는 방법 (0) | 2024.01.16 |