年中アイス

いろいろつらつら

aws-sdk-go-v2でassume roleしてAPIを呼ぶ

クロスアカウントを使うことがあったのと、そろそろv2をちゃんと使わないとなということでaws-sdk-go-v2を使ってassume roleする方法を調べました。EC2のDescribeInstancesを呼んでインスタンスリストを出すだけのサンプルを実装しています。コード全体はここに上げてあるのでみてみてください。MFAは無しとstdinからの入力のパターンに対応しています。

github.com

使い方はSDKドキュメントにしっかり書いてあってその通りなんですが、最初からそこは見つけられず、stack overflowでパッケージを把握して見に行きました。

サンプルからの抜粋

cfg, err := config.LoadDefaultConfig(ctx,
    config.WithRegion("ap-northeast-1"),
)
if err != nil {
    log.Fatal(err)
}

// ...中略...

if optRoleArn != "" {
    stsClient := sts.NewFromConfig(cfg)
    var provider *stscreds.AssumeRoleProvider
    if optMFAArn != "" {
        provider = stscreds.NewAssumeRoleProvider(stsClient, optRoleArn, func(o *stscreds.AssumeRoleOptions) {
        o.SerialNumber = aws.String(optMFAArn)
        o.TokenProvider = stscreds.StdinTokenProvider
        })
    } else {
        provider = stscreds.NewAssumeRoleProvider(stsClient, optRoleArn)
    }

    cfg.Credentials = aws.NewCredentialsCache(provider)
}

// 後はEC2など必要なAPIの呼び出し
cli := ec2.NewFromConfig(cfg)
  • aws-sdk-go-v2で必ずやるcfg, err := config.LoadDefaultConfig()
  • stsサービスのクライアントを作り、変身先のRoleARN(arn:aws:iam::<account id>:role/<role-name>)、必要な場合はMFAのARN(arn:aws:iam::<account id>:mfa/<user name>)と今回は標準入力からのMFA codeの受付を担うstscreds.StdinTokenProviderを使ってAssumeRoleProviderを作成
  • cfgにそのAssumeRoleProviderを設定し、その先はassume roleを行わない場合と同じ各種APIの呼び出し方法

ちなみに同じcfgを使っていれば処理中ではMFAは1回目だけ*1聞かれます。サンプルではその確認のために2回呼んでいます。もちろんコマンド起動ごとにはMFAを聞かれます。

他にも、Stack overflowの回答ではコメントアウトしてありましたが、ClientLogModeという設定があるのもわかりました。サンプルではSigningのログを出すオプションを付けています。リクエスト/レスポンスログなども出せるようなのでデバッグに便利そうです。

参考

*1:デフォルトは1時間の有効期限です。