前回まででGoを使ってAWSを操作することができるところまでは確認出来ました。
今回は、実際にGoを使うとどれくらい早いかを、AWS CLIと比較してみたいと思います。
まずは計測用プログラムのプロトタイプを作成します。
ファイル名:aws.go
package main import ( "fmt" "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/iam" ) const ( debug = true ) func main() { svc := iam.New(session.New(), &aws.Config{}) params := &iam.GetPolicyInput{ PolicyArn: aws.String("arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly"), } policy, err := svc.GetPolicy(params) if err != nil { panic(err) } fmt.Println(policy) users, err := svc.ListUsers(nil) if err != nil { panic(err) } for i := 0; i < len(users.Users); i++ { if strings.Index(*(users.Users[i].UserName), "TestUser") > 0 { if debug { fmt.Println("Attach AmazonIAM-ReadOnly Policy to ", *(users.Users[i].UserName)) } params := &iam.AttachUserPolicyInput{ PolicyArn: aws.String("arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly"), UserName: aws.String(*(users.Users[i].UserName)), } resp, err := svc.AttachUserPolicy(params) if err != nil { panic(err) } if debug { fmt.Println(resp) } } } }
このプログラムでやっていることは以下の3つです。
1. AmazonIAM-ReadOnlyポリシーをGetして表示
2. IAMユーザの一覧を取得
3. 2.で取得したユーザのうち、"TestUser"と付くユーザに対してAmazonIAM-ReadOnlyポリシーをアタッチ
で、実行した結果は以下のようになりました。
>go run aws.go
{
Policy: {
Arn: "arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly",
AttachmentCount: 0,
CreateDate: 2016-05-04 13:21:14 +0000 UTC,
DefaultVersionId: "v1",
IsAttachable: true,
Path: "/",
PolicyId: "<ポリシーID>",
PolicyName: "AmazonIAM-ReadOnly",
UpdateDate: 2016-05-04 13:21:14 +0000 UTC
}
}
Attach AmazonIAM-ReadOnly Policy to TestUser0
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser1
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser2
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser3
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser4
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser5
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser6
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser7
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser8
{
}
Attach AmazonIAM-ReadOnly Policy to TestUser9
{
}
実際にポリシーがアタッチできているかも確認します。
<実行前>

<実行後>

うん、ちゃんとできていますね。
次に、WindowsのコマンドラインでAWSコマンドを使うために、以下のURLからインストーラをダウンロードして実行します。
http://docs.aws.amazon.com/cli/latest/userguide/installing.html
>aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxx
Default region name [None]:
Default output format [None]:
>aws iam list-users
{
"Users": [
{
"UserName": "TECRA",
"Path": "/",
"CreateDate": "2016-05-04T13:19:28Z",
"UserId": "<ユーザID>",
"Arn": "arn:aws:iam::<アカウントID>:user/TECRA"
}
]
}
無事ユーザを取得することが出来たと言うことで、まずはGoで計測用のプログラムを書いてみます。
ファイル名:aws_time.go
package main import ( "fmt" "strings" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/iam" ) const ( debug = false loop = 10 ) func main() { svc := iam.New(session.New(), &aws.Config{}) users, err := svc.ListUsers(nil) if err != nil { panic(err) } t1 := time.Now() for count := 0; count < loop; count++ { for i := 0; i < len(users.Users); i++ { if strings.Index(*(users.Users[i].UserName), "TestUser") > 0 { attachUserPolicyInput := &iam.AttachUserPolicyInput{ PolicyArn: aws.String("arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly"), UserName: aws.String(*(users.Users[i].UserName)), } attachUserPolicyOutput, err := svc.AttachUserPolicy(attachUserPolicyInput) if err != nil { panic(err) } detachUserPolicyInput := &iam.DetachUserPolicyInput{ PolicyArn: aws.String("arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly"), UserName: aws.String(*(users.Users[i].UserName)), } detachUserPolicyOutput, err := svc.DetachUserPolicy(detachUserPolicyInput) if err != nil { panic(err) } } } } t2 := time.Now() fmt.Println(t2.Sub(t1)) }
やっていることはユーザの一覧を取得して、ユーザ名に"TestUser"が含まれるユーザに対してポリシーを1つアタッチして、デタッチすると言うものになります("TestUser"に限定しているのは、実行用のユーザに影響を及ぼさないためです)。
これをループで回して、実行前後の時間を取得します。
これと比較するバッチファイルは以下のものになります。
@echo off
setlocal ENABLEDELAYEDEXPANSION
set loop=1
set users[0]=TestUser0
set users[1]=TestUser1
set users[2]=TestUser2
set users[3]=TestUser3
set users[4]=TestUser4
set users[5]=TestUser5
set users[6]=TestUser6
set users[7]=TestUser7
set users[8]=TestUser8
set users[9]=TestUser9
set users[10]=TECRA
set policy_arn="arn:aws:iam::<アカウントID>:policy/AmazonIAM-ReadOnly"
echo t1=%time:/=%
for /l %%c in (1, 1, %loop%) do (
for /l %%i in (0, 1, 10) do (
echo !users[%%i]! | find "TestUser" 1>nul
if not ERRORLEVEL 1 (
rem echo !users[%%i]!
aws iam attach-user-policy --user-name !users[%%i]! --policy-arn %policy_arn%
aws iam detach-user-policy --user-name !users[%%i]! --policy-arn %policy_arn%
)
)
)
echo t2=%time:/=%
うわ~かっこ悪い。でも幾ら調べても、aws iam list-usersの結果を配列としてusersに格納する方法が分からなかったのです。残念なことに。
そこは速度計測の本質ではないので泣く泣く妥協しました。
ループ回数を1回、5回、10回と変更した上で、それぞれ5回計測した値の平均を取りました。
結果は以下のとおりです(単位はsec)。
| 要素数 | 1回 | 5回 | 10回 |
| AWS CLI | 48.73 | 247.35 | 492.82 |
| Go | 0.00 | 0.00 | 0.00 |
Goが早すぎて計測できていない・・・。
仕方がないのでループ回数を増やして再計測。
1,000,000回実行して0.17秒、100,000,000回実行して15.19秒でした。Go早すぎだろ・・・。
もうちょっと考察をしてみると、今回の計測ではあくまでfor文の前後で時間を計測していたけど、実際にGoのプログラムは実行してから結果が返ってくるまでにラグがあった。
おそらくfor文の前の処理で何か時間がかかっているのだろう。具体的にはアクセスキーによる認証とか。
AWS CLIの場合はGoファイルのiam.Newに相当する部分が無く、直接attach-user-policy等を呼び出している。と言うことは都度認証を行っていて、それに時間がかかるのかな。もしそうだとしたらGoが早いというよりもAWS CLIが遅いのかなぁ。
そんなわけで、今日はこれまで。
それでは、ごきげんよう。