0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

aws-sdk-go-v2での実行をAssumeRoleで行うようにする

Posted at

AccessKeyやSecretAccessKeyによる長期認証情報はセキュリティリスクが高いだろうなと感じ、AssumeRoleを使用して短期認証情報で実行する方法を調査しました。

AssumeRoleとは

AWS Security Token Service (AWS STS) を開始して、IAMユーザーやAWSリソースが、一時的に特定のIAMロールの権限を受け取ることができる機能です。

これを使うことで、IAMユーザーを多く発行せずとも、IAMユーザーやAWSリソースに権限を振ることができるようになります。

AssumeRoleを使用したsdkの実装

LoadDefaultConfigでcredential情報を取得します。

WithSharedConfigProfileオプションでIAMロールを指定します。~/.aws/configに設定したプロファイルが各ロールに対応しています。

WithAssumeRoleCredentialOptionsでAssumeRoleの設定を行います。

  • config/config.go
package config

import (
	"context"
	"os"
	"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"
)

type Config struct {
	AWSConfig *aws.Config
}

func NewConfig() *Config {
	ctx := context.Background()
	awsConfig, err := config.LoadDefaultConfig(
		ctx,
		config.WithDefaultRegion("ap-northeast-1"),
		config.WithSharedConfigProfile(os.Getenv("AWS_PROFILE")),
		config.WithAssumeRoleCredentialOptions(func(options *stscreds.AssumeRoleOptions) {
			options.TokenProvider = func() (string, error) {
				return os.Getenv("MFA_TOKEN"), nil
			}
		}),
	)
	if err != nil {
		panic(err)
	}
	
	return &Config{
		AWSConfig: &awsConfig,
	}
}

今回は例として、S3からバケット一覧を取得するラッパーメソッドを実装します。

  • s3_wrapper/s3_wrapper.go
package s3wrapper

import (
	"context"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/maooz4426/aws-sdk-go-playground/config"
)

type S3Wrapper struct {
	Client *s3.Client
}

func NewS3Wrapper() (*S3Wrapper, error) {
	sdkConfig := config.NewConfig()
	s3Client := s3.NewFromConfig(*sdkConfig.AWSConfig)
	return &S3Wrapper{s3Client}, nil
}

func (s S3Wrapper) ListObject() (*s3.ListBucketsOutput, error) {
	result, err := s.Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
	if err != nil {
		return nil, err
	}
	return result, nil
}
  • main.go
package main

import (
	"fmt"
	"github.com/joho/godotenv"
	s3wrapper "github.com/maooz4426/aws-sdk-go-playground/s3_wrapper"
)

func main() {
	if err := godotenv.Load(); err != nil {
		panic(err)
	}
	
	s3wrapper, err := s3wrapper.NewS3Wrapper()
	if err != nil {
		panic(err)
	}
	
	result, err := s3wrapper.ListObject()
	if err != nil {
		panic(err)
	}
	
	for _, bucket := range result.Buckets {
		fmt.Println(*bucket.Name)
	}
}

実行結果

MFAトークンを環境変数として渡して実行すると、以下のようにS3バケット一覧が取得できます。

MFA_TOKEN=xxxxxxx go run main.go
front-test-cloudfront
pandator-assets

本番稼働した場合はどうなるのか

AssumeRoleの実装において、下記のような書き方をしていたと思います。

~/.aws/configに設定したプロファイルが各ロールに対応しています。

本番稼働の際はどのロールを使うのか気になった方がいると思いますが、本番稼働ではEC2やECSにアタッチされたインスタンスロールやタスクロールを使って実行されます。

つまり

  • 開発時: ~/.aws/configで定義したプロファイル(AssumeRoleで切り替え)
  • 本番時: EC2/ECSに直接アタッチされたロール(自動的にAssumeRole)

本番環境では明示的なプロファイル指定は不要になるので、環境変数でstagingやproduction環境では使わないといったコードを書くことができます。

まとめ

AssumeRoleを使うことで、わざわざアプリケーションのためにIAMユーザーとCredentialを発行せずとも実行させることが可能になります。
こうすることで安全にアプリケーションを動かせるようになるのでぜひ参考にしてみてください!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?