1
1

More than 1 year has passed since last update.

AWS-SDKでアシュームロールをしてS3にアクセスする方法

Posted at

背景

Javaのバッチ処理でAWSのS3の操作を作成することになったのだが
バッチPGはAWSの外部(Dockerコンテナ上)で実行されるので認証が必要。
また認証には対象バケットにアクセス可能なIAMユーザのアクセスキーではなくアクセス用のIAMロールがあり、それに対してAssumeRole可能なIAMユーザのアクセスキーが発行される。

ということで、以下のような流れで認証を行う。
①IAMユーザで基本認証
②①からアクセス用のロールにAssumeRoleして一時認証用のセッションを生成
③②のセッションからS3にアクセス

PG構成

  • Java
  • AWS SDK for Java V2

ソース

gradle設定

lombokは無くてもいいけど入れておく。
とりあえずAssumeRoleとS3アクセスが出来る最小構成。

build.gradle
dependencies {
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	implementation platform('software.amazon.awssdk:bom:2.20.24')
	implementation 'software.amazon.awssdk:s3'
	implementation 'software.amazon.awssdk:sts'
}

PGソース

S3Client取得
検証用なのでキー等は定数で直書き。実装時はコンフィグファイルで設定するよ!

private S3Client getS3Client() {
  // 踏み台IAMの認証キー
  final String ACCESS_KEY_ID = "アクセスキー値";
  final String SECRET_KEY = "シークレットキー値";
  // アシュームロール
  final String ROLE_ARN = "arn:aws:iam::1234567890:role/hoge-S3OptimizationRole";
  final String ROLE_SESSION_NAME = "hoge_session";  // 適当なセッション名

  // 踏み台IAMの認証
  AwsCredentials bastionCredentials = AwsBasicCredentials.create(ACCESS_KEY_ID, SECRET_KEY);

  // S3アクセス用のロールにアシュームロール
  StsClient sts = StsClient.builder()
    .credentialsProvider(StaticCredentialsProvider.create(bastionCredentials))
    .build();
  AssumeRoleRequest asmRoleRequest = AssumeRoleRequest.builder()
    .roleArn(ROLE_ARN)
    .roleSessionName(ROLE_SESSION_NAME)
    .build();
    
  // アシュームロールしたセッションでS3Clientを生成
  StsAssumeRoleCredentialsProvider provider = StsAssumeRoleCredentialsProvider.builder()
    .stsClient(sts)
    .refreshRequest(asmRoleRequest)
    .build();
  S3Client s3Client = S3Client.builder()
    .credentialsProvider(provider)
    .build();

  return s3Client;
}

バケット内のファイル一覧をコンソール出力

public void printFileList() {
  final String BUCKET_NAME = "hogebkt";

  var s3Client = getS3Client();

  // バケット内のファイル一覧取得
  var lsRequest = ListObjectsRequest.builder()
    .bucket(BUCKET_NAME)
    .build();
  ListObjectsResponse objList = s3Client.listObjects(lsRequest);

  // 結果表示
  objList.contents().forEach(obj -> {
    System.out.println("key : ".concat(obj.key()));
  });
}

以上。

なかなかサンプルソースが見つからず公式ドキュメント読みながら作成したのでいろいろ拙い部分がありそうだけど、ひとまずアクセス検証は完了。

あとは上記の方法だと、S3Clientを生成するたびに一時認証セッションが発行されるので連続して処理を行うときはS3Clientを使いまわした方がよさそう。
ただし一時認証のセッション生存期間はデフォルトだと1時間らしいので処理に合わせて対応が必要。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1