クロスアカウントを使うことがあったのと、そろそろv2をちゃんと使わないとなということでaws-sdk-go-v2を使ってassume roleする方法を調べました。EC2のDescribeInstancesを呼んでインスタンスリストを出すだけのサンプルを実装しています。コード全体はここに上げてあるのでみてみてください。MFAは無しとstdinからの入力のパターンに対応しています。
使い方は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のログを出すオプションを付けています。リクエスト/レスポンスログなども出せるようなのでデバッグに便利そうです。
参考
- amazon web services - How to assume role with the new AWS GO SDK-V2 for cross account access - Stack Overflow
- stscreds package - github.com/aws/aws-sdk-go-v2/credentials/stscreds - Go Packages
- aws package - github.com/aws/aws-sdk-go-v2/aws - Go Packages
- Logging | AWS SDK for Go V2
*1:デフォルトは1時間の有効期限です。