📚
AWS SDK Go(v1)でクロスアカウントアクセス
概要
複数のAWSアカウントを用途に応じ、分けて運用することはよくあると思います。
この際、LambdaやECSなどAWS SDKやAWS CLIを使ったのプログラムから別アカウントのリソースへクロスアカウントアクセスすることがあると思いますが、その場合にはSTSを利用して一時的なセキュリティ認証情報を取得し、アクセスを行います。
今回は、その方法をまとめています。
環境
golang : 1.20.1
aws-sdk-go : v1.44.219
IAM Role設定
今回は、CloudWatch Logsのロググループ一覧を取得できるようにするケースを例にしています。
権限の委任元(=アクセスされる側)のアカウントでの作業(1/2)
許可するポリシーの作成
インラインポリシーでも良いですが、管理上ポリシーを作成します。
以下では、権限の委任元のアカウントのロググループ全体をDescribeできる権限を与えていますが、必要に応じて特定のロググループへ制限するようにしてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:DescribeLogGroups",
"Resource": "arn:aws:logs:*:<委任元のAccountID>:log-group:*"
}
]
}
委任するロールの作成
上記で作成したポリシーをアタッチしつつ、委任先のアカウントを信頼されたエンティティとして指定し、IAM Roleを作成します。
Management Consoleから作成すると、信頼ポリシーは以下のようになっているはずです。しかし、このままだと、委任先のどのユーザー/ロールでもこのポリシーを引き受けることができてしまうので、後ほど編集します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<委任先のAccountID>:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
権限の委任先(=アクセスする側)のアカウントでの作業
ポリシーの作成
先ほど委任元で作成したロールを引き受けるポリシーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<委任元のAccountID>:role/<委任元で作成したロール名>"
}
]
}
権限を引き受けるロールの作成
作成したポリシーをアタッチしつつ、権限を利用するサービス/ユーザーに応じてロールを作成します。
作成したロールのArnを次で使うため、メモしてください。
権限の委任元(=アクセスされる側)のアカウントでの作業(2/2)
委任先でAssume Roleできるロールやユーザーを制限するため、信頼ポリシーを更新します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<委任先のAccountID>:user/<ユーザー名>",
"arn:aws:iam::<委任先のAccountID>:role/<ロール名>"
]
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
サンプルコード
package main
import (
"fmt"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/aws/aws-sdk-go/service/sts"
)
func main() {
var (
region string = "ap-northeast-1"
assumeRoleArn string = "arn:aws:iam::<委任先のAccountID>:role/<ロール名>"
)
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
assumeRoler := sts.New(sess)
creds := stscreds.NewCredentialsWithClient(assumeRoler, assumeRoleArn)
svc := cloudwatchlogs.New(sess, aws.NewConfig().WithRegion(region).WithCredentials(creds))
logGroupsList, err := svc.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(logGroupsList)
}
肝となるのはここの箇所で、STSで認証情報を取得している部分となります。
assumeRoler := sts.New(sess)
creds := stscreds.NewCredentialsWithClient(assumeRoler, assumeRoleArn)
参考リンク
Discussion