Go言語がちょっと流行りだしてるのでやってみた。
Go環境整備
まずGo言語を入れる。環境はMac(Yosemite 10.10.2)でbrewを使用。
$ brew install go
$ echo 'export GOPATH=${HOME}/.golang' >> ~/.bash_profile
$ echo 'export PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin' >> ~/.bash_profile
$ source ~/.bash_profile
$ go version
go version go1.4.1 darwin/amd64
恒例のやつも試しておく。
$ vi Hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
$ go build Hello.go
$ ./Hello
Hello World!
buildしなくてもいける
$ go run Hello.go
Hello World!
AWS SDK fo Go インストール
GitHubにあるので取ってくる。
全部取ってみたらなんかエラーっぽいのが出たが、とりえあず行ってみる。(buildするソースがないってことだからOKっぽい?)
$ go get github.com/awslabs/aws-sdk-go
package github.com/awslabs/aws-sdk-go
imports github.com/awslabs/aws-sdk-go
imports github.com/awslabs/aws-sdk-go: no buildable Go source files in /Users/USERNAME/.golang/src/github.com/awslabs/aws-sdk-go
インスタンス情報取得
まずは恒例のアクセスキー関連の情報を仕込んでおく。
$ vi ~/.aws/credentials
[default]
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXX
そして、見慣れたdescribe-instancesを実行してみる。
$ vi ec2.go
package main
import (
"fmt"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
)
func main() {
svc := ec2.New(&aws.Config{Region: "ap-northeast-1"})
res, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
for _, r := range res.Reservations {
for _, i := range r.Instances {
var tag_name string
for _, t := range i.Tags {
if *t.Key == "Name" {
tag_name = *t.Value
}
}
fmt.Println(
tag_name,
*i.InstanceID,
*i.InstanceType,
*i.Placement.AvailabilityZone,
*i.PrivateIPAddress,
*i.State.Name,
)
}
}
}
$ go run ec2.go
TAGNAME-A i-XXXXXXXX c1.medium ap-northeast-1a X.X.X.X stopped
TAGNAME-B i-XXXXXXXX m1.medium ap-northeast-1b X.X.X.X stopped
TAGNAME-C i-XXXXXXXX t2.small ap-northeast-1c X.X.X.X running
TAGNAME-D i-XXXXXXXX m3.large ap-northeast-1a X.X.X.X stopped
:
:
そのまんまDescribeInstancesというAPIを使う。
実行結果としてDescribeInstancesOutputという型の構造体を返し、その中のメンバであるReservationの配列を参照する感じ。
んで、そのReservationに含まれるメンバのInstanceも配列なので二重ループでインスタンスの情報にアクセスしている。
インタンスの持っているメンバはほとんど文字列か数字なのでそのまま参照出来るが、Tagは構造体の配列なので、同じようにループさせて取得する。
Goにはforeach的なものが存在しないらしく、for文の応用技で for key, val := range Array
という書き方を使う。_
は使わないので捨ててるという意味。
ただ、このままだと綺麗に出力されないので、テーブルレイアウト表示させてみる。
ググって発見したtablewriterというのを使わせて頂く。
$ go get github.com/olekukonko/tablewriter
最終形はこんな感じ。
package main
import (
"os"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/service/ec2"
"github.com/olekukonko/tablewriter"
)
func main() {
svc := ec2.New(&aws.Config{Region: "ap-northeast-1"})
res, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Tag Name", "Instance Id", "Instance Type", "AZ", "IP", "Status"})
for _, r := range res.Reservations {
for _, i := range r.Instances {
var tag_name string
for _, t := range i.Tags {
if *t.Key == "Name" {
tag_name = *t.Value
}
}
table.Append([]string{
tag_name,
*i.InstanceID,
*i.InstanceType,
*i.Placement.AvailabilityZone,
*i.PrivateIPAddress,
*i.State.Name,
})
}
}
table.Render()
}
実行結果のイメージ。
+-----------+-------------+---------------+-----------------+---------+---------+
| TAG NAME | INSTANCE ID | INSTANCE TYPE | AZ | IP | STATUS |
+-----------+-------------+---------------+-----------------+---------+---------+
| TAGNAME-A | i-XXXXXXXX | m1.small | ap-northeast-1a | X.X.X.X | stopped |
| TAGNAME-B | i-XXXXXXXX | r3.2xlarge | ap-northeast-1b | X.X.X.X | stopped |
| TAGNAME-C | i-XXXXXXXX | m1.medium | ap-northeast-1c | X.X.X.X | stopped |
| TAGNAME-D | i-XXXXXXXX | c3.large | ap-northeast-1b | X.X.X.X | running |
以上。今度はTag名で絞ったりインスタンス起動停止とかやってみよう。