dshimizu/blog/alpha

とりとめのないITブログ

AWS SDK for Go v2 で Assume Role を実行するサンプル

はじめに

AWS SDK for Go v2 で Assume Role を実行しようと思ってのサンプルコードです。

準備

AWS SDK for Go v2 インストール

作業ディレクトリを作成します。

$ mkdir ~/hello-aws-sdk-go-v2

$ cd ~/hello-aws-sdk-go-v2

$ go mod init hello-aws-sdk-go-v2

パッケージをインストールします。

$ go get github.com/aws/aws-sdk-go-v2/aws

$ go get github.com/aws/aws-sdk-go-v2/config

$ go get github.com/aws/aws-sdk-go-v2/credentials/stscreds

$ go get github.com/aws/aws-sdk-go-v2/service/sts

利用したい AWS サービスに合わせて必要なものをインストールします。ここでは EC2 の一覧を取得しようとしているため、 ec2 のモジュールをインストールします。

$ go get github.com/aws/aws-sdk-go-v2/service/ec2

AWS CLI 用の Configuration and credentia の設定

ローカルで下記のような設定がなされているものとします。

# ~/.aws/credentials
# IAMユーザーのアクセスキー情報が foo という名前のprofileで定義されている

[foo]
aws_access_key_id=**********
aws_secret_access_key=******************************
# ~/.aws/config

[profile foo]
region=ap-northeast-1

アクセス元 AWS アカウントでの IAM Policy の設定

アクセス元の AWS アカウント(仮に 987654321098 とする)の IAM ユーザーに、 "arn:aws:iam:123456789012:role/TestRole" のロールを利用できる IAM ポリシーが作成され、アタッチされているものとします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:role/TestRole",
            ],
            "Effect": "Allow"
        }
    ]
}

アクセス先 AWS アカウントでの IAM Role の設定

アクセスしたい AWS アカウント(仮に 123456789012 とする)に "arn:aws:iam::123456789012:role/TestRole" という IAM ロールが作成されているものとします。 この IAM ロールには、下記のように、アクセス元となる 987654321098AWS アカウントから sts:AssumeRole, sts:TagSession を許可する旨の「信頼ポリシー」が設定されているものとします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::987654321098:root"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}

また、下記のサンプルでは EC2 の一覧を表示する処理を実行するようにしているため、AWS 管理ポリシーである arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess の IAM ポリシーも付与しておきます。

サンプルコード

下記のような main.go を作成します。

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/credentials/stscreds"
    "github.com/aws/aws-sdk-go-v2/service/sts"

    "github.com/aws/aws-sdk-go-v2/service/ec2"
)

func main() {

    ctx := context.TODO()
    cfg, err := config.LoadDefaultConfig(ctx,
        config.WithRegion("ap-northeast-1"),
        config.WithSharedConfigProfile("foo"),  // ~/.aws/config のプロファイル名に合わせる
    )
    if err != nil {
        log.Fatal(err)
    }

        // 利用するのロール名を設定する
    roleArn := "arn:aws:iam::*************:role/********"

    stsSvc := sts.NewFromConfig(cfg)
    creds := stscreds.NewAssumeRoleProvider(stsSvc, roleArn)
    cfg.Credentials = aws.NewCredentialsCache(creds)


        // ここから実行したい処理を記述する
        // 下記では EC2 の一覧を取得している
    cli := ec2.NewFromConfig(cfg)

    resp, err := cli.DescribeInstances(ctx, &ec2.DescribeInstancesInput{})
    if err != nil {
        log.Fatal(err)
    }

    for _, r := range resp.Reservations {
        for _, ins := range r.Instances {
            log.Printf("%s %v", *ins.InstanceId, ins.InstanceType)
        }
    }

    // second time, not need to input MFA code because credential is cached.
    resp, err = cli.DescribeInstances(ctx, &ec2.DescribeInstancesInput{})
    if err != nil {
        log.Fatal(err)
    }

    for _, r := range resp.Reservations {
        for _, ins := range r.Instances {
            log.Printf("%s %v", *ins.InstanceId, ins.InstanceType)
        }
    }
}

参考