DRYな備忘録

Don't Repeat Yourself.

【Go言語】aws-sdk-goで Instance Profile の作成

CLIでやるのはこれ↓でやって概念理解したので、

otiai10.hatenablog.com

SDK使って同じことをコードからやる。

package main

import (
    "bytes"
    "encoding/json"
    "flag"
    "fmt"
    "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 (
    arnPolicyAmazonS3FullAccess = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
)

var (
    region string
    name   string
)

func init() {
    flag.StringVar(&region, "region", "ap-northeast-1", "Region")
    flag.StringVar(&name, "role-name", "testtest", "Role and profile name")
    flag.Parse()
}
func main() {

    // 0) APIクライアントの初期化
    sess := session.New(&aws.Config{
        Region: aws.String(region),
    })
    client := iam.New(sess)

    // 1) Roleをつくる
    assumepolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":       "",
                "Effect":    "Allow",
                "Action":    "sts:AssumeRole",
                "Principal": map[string]string{"Service": "ec2.amazonaws.com"},
            },
        },
    }
    buf := bytes.NewBuffer(nil)
    if err := json.NewEncoder(buf).Encode(assumepolicy); err != nil {
        panic(err)
    }

    createRoleOutput, err := client.CreateRole(&iam.CreateRoleInput{
        Path:                     aws.String("/"),
        RoleName:                 aws.String(name),
        AssumeRolePolicyDocument: aws.String(buf.String()),
        Description:              aws.String(time.Now().Format(time.RFC3339)),
    })
    if err != nil {
        panic(err)
    }
    role := createRoleOutput.Role

    // 2) Policyをつくる
    //    ... というのは割愛します。今回は既存のもの使おう。
    //        具体的には、 arn:aws:iam::aws:policy/AmazonS3FullAccess です。

    // 3) Role に Policy を attach する
    _, err = client.AttachRolePolicy(&iam.AttachRolePolicyInput{
        PolicyArn: aws.String(arnPolicyAmazonS3FullAccess),
        RoleName:  role.RoleName,
    })
    if err != nil {
        panic(err)
    }

    // 4) Instance Profile をつくる
    instanceprofileCreateOutput, err := client.CreateInstanceProfile(&iam.CreateInstanceProfileInput{
        InstanceProfileName: role.RoleName, // めんどくさいのでRole名と同じにします
    })
    if err != nil {
        panic(err)
    }
    instanceprofile := instanceprofileCreateOutput.InstanceProfile

    // 5) Instance Profile に Role を追加する
    _, err = client.AddRoleToInstanceProfile(&iam.AddRoleToInstanceProfileInput{
        InstanceProfileName: instanceprofile.InstanceProfileName,
        RoleName:            role.RoleName,
    })
    if err != nil {
        panic(err)
    }

    // 成果物
    fmt.Printf("%+v\n", instanceprofile)
}

実行

% go run main.go
{
  Arn: "arn:aws:iam::111222333444555666:instance-profile/testtest",
  CreateDate: 2018-06-05 08:18:09.494 +0000 UTC,
  InstanceProfileId: "AIPAJDNEGOMABCDEFGHIJK",
  InstanceProfileName: "testtest",
  Path: "/"
}

雑感

DRYな備忘録として

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)