ようへいの日々精進XP

よかろうもん

2017 年 07 月 09 日(日)

ジョギング

  • 香椎浜 x 2.5 周
  • 朝早い時間は雨が降っていたりで、結局は 12 時過ぎから走りはじめて暑さに敗北
  • 右太ももが辛い

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

奥さん

  • 体調イマイチ
  • きっとストレスなんだろうなあ

夕飯

  • 楽しくご飯食べたいのでたこ焼きパーリー
  • 今回は上手く焼けたんではないかな

俺のチュートリアル 2017 夏 〜 go-datadog-api をちょっと使ってみた 〜

go-datadog-api

Golang で実装された Datadog API のラッパーです。

github.com

使ってみた

準備

$GOPATH 等は設定済みの状態です。

go get gopkg.in/zorkian/go-datadog-api.v2

monitors を取得するやつ

GetMonitors() 関数を利用すれば良いようです。

package main

import (
    "log"
    "gopkg.in/zorkian/go-datadog-api.v2"
)

func main() {
    client := datadog.NewClient("api key", "application key")

    mons, err := client.GetMonitors()
    if err != nil {
        log.Fatalf("fatal: %s\n", err)
    }

    for _, mon := range mons {
        log.Printf("Monitor %d: %s\n", mon.GetId(), mon.GetName())
    }
}

monitor の各要素は GetId()GetName() 等のメソッドを利用すれば取得出来るようです。

ところが

以下のようなエラーが出ちゃいます。

$ go run dd-monitors.go
2017/07/09 17:22:03 fatal: json: cannot unmarshal string into Go struct field Options.evaluation_delay of type int
exit status 1

取得した monitor の evaluation_delay というキーの値について、意図した値(型は int)が入っていない為、JSON の解析に失敗しているようです。この事象については、以下の issue でやりとりされていました。

github.com

evaluation_delay に値が入っていない場合の処理については、こちらのプルリクエストで Merge はされているので、近日中には Merge された内容でリリースされるんぢゃないかなーと期待しております。

ということで

monitor の取得については

もう少々待ちたいと思います。当然、evaluation_delay に値が設定されている場合や evaluation_delay がそもそも設定されていない monitor の場合には、以下のように monitor の各要素を取得することは出来ています。

$ cat dd-monitors.go
package main

import (
    "log"
    "gopkg.in/zorkian/go-datadog-api.v2"
)

func main() {
    client := datadog.NewClient("api key", "application key")

    mon, err := client.GetMonitor(12345678)
    if err != nil {
        log.Fatalf("fatal: %s\n", err)
    }
    log.Printf("Monitor %d: %s\n", mon.GetId(), mon.GetName())
}

$ go run dd-monitors.go
2017/07/09 17:51:12 Monitor 12345678: Apache Log Monitor 40x Error Test

そもそも evaluation_delay とは

Datadog API ドキュメントには以下のように書かれています。

evaluation_delay Time (in seconds) to delay evaluation, as a non-negative integer. For example, if the value is set to 300 (5min), the timeframe is set to last_5m and the time is 7:00, the monitor will evaluate data from 6:50 to 6:55. This is useful for AWS CloudWatch and other backfilled metrics to ensure the monitor will always have data during evaluation.

ざっくりと意訳すると…

  • メトリクスを遅延評価するオプション
  • 秒で設定する
  • CloudWatch 等のメトリクスで評価するモニタにおいてデータを常に確保したい場合に設定すると良い

CloudWatch のメトリクスを取得する際に NO DATA になってしまうことを防げるのかもしれないですが、使ったことが無いのでなんとも言えません。すいません。

GolangJSON パースのちょっと入門

encoding/json を使ったチュートリアル

GolangJSON パースについてはちゃんと書こうとすると 1 つの記事になってしまうんだろうけど、ひとまず encoding/json パッケージを使ったチュートリアルをしてみます。

参考

シンプルに纏まっていて解りやすかったです。有難うございましたmm

基本

  • JSON のデータ構造に合わせて構造体を定義する
  • Unmarshal 関数を使用してパースする
  • JSON を生成する場合には marshal 関数を利用する

そもそも構造体って?

1つもしくは複数の値をまとめて格納できる型。それぞれのメンバ(フィールド)は型が異なっていてもよい点が配列と異なる。

なるほど。(今更感)

以下のサンプルで言うと、

type SelfIntroduction struct {
    Name string              `json:"name"`
    Options []Options        `json:"options"`
}

これが構造体。

サンプル

参考サイトのサンプルスクリプトを拝借させて頂いて自己紹介スクリプトを self-introduction.go として保存しておきます。

package main

import (
    "encoding/json"
    "fmt"
)

type SelfIntroduction struct {
    Name string              `json:"name"`
    Options []Options        `json:"options"`
}

type Options struct {
    Name string              `json:"name"`
    Value json.Number        `json:"value"`
}

func main() {
    json := `
{
  "name": "ハゲ",
  "options": [
    {
      "name": "髪",
      "value": "つるっぱげ"
    },
    {
      "name": "age",
      "value": 40
    }
  ]
}
`
    jsonBytes := ([]byte)(json)
    data := new(SelfIntroduction)

    if err := json.Unmarshal(jsonBytes, data); err != nil {
        fmt.Println("JSON Unmarshal error:", err)
        return
    }

    fmt.Println("Name: " + data.Name)
    for _, option := range data.Options {
        fmt.Printf("%s: %s\n", option.Name, option.Value)
    }
}

実行してみます。

$ go run self-introduction.go
Name: ハゲ
髪: つるっぱげ
age: 40

おお、ちゃんと解析出来ています。

まだまだ GolangJSON を扱う上で色々と学ぶ必要が有りそうなので、追々チュートリアルしていきます。

ということで

go-datadog-api から始まって、evaluation_delay を経由して GolangJSON パースまで薄く触れてみました。引き続き、チュートリアルな夏は続きます。

2017 年 07 月 08 日(土)

ジョギング

  • 香椎浜 x 2.5 周
  • 11 時過ぎからスタートしたのが間違っていた(暑さでフラフラ

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

仕事でやらかした

  • 当たり前にやっておくべきことが漏れててやらかしてしまった
  • 当たり前のことが出来ていなかったのがとても悔しい

俺のチュートリアル 2017 夏 〜 チュートリアルで学ぶ IAM Role によるクロスアカウントアクセス 〜

はじめに

以下のチュートリアルを参考にしつつ、シンプルな構成を使って AWS のクロスアカウントアクセスを試してみたメモ。

docs.aws.amazon.com

構成

下図のような構成を想定。

f:id:inokara:20170708105112p:plain

やりたいことをスーパーシンプル三行で説明すると…

  • Account xxxx-xxxx-0001 の適切に管理されている S3 バケットに
  • Account xxxx-xxxx-0002 の適切な IAM Role が付与されている EC2 から
  • 出来るだけ安全にアクセスしたい(とりあえず閲覧出来れば OK)

チュートリアル

Account xxxx-xxxx-0001 の設定

IAM Role

以下の Trust relationships を適用して IAM Role の role-01 を作成する。

$ cat role-01.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::xxxxxxxx0002:role/role-02"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

$ aws \
  --profile ${Account xxxx-xxxx-0001 の PROFILE} \
    iam create-role \
      --role-name role-01 \
      --assume-role-policy-document file://role-01.json \
      --query Role.Arn \
      --output text

IAM Role に付与するポリシー

role-01 に付与するポリシーは、以下のように S3 バケットのオブジェクトを取得できるだけのポリシー AmazonS3ReadOnlyAccess を付与する。

$ cat policy-01.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Resource": "*"
    }
  ]
}

$ aws \
  --profile ${Account xxxx-xxxx-0001 の PROFILE} \
    iam put-role-policy \
      --role-name role-01 \
      --policy-name policy-01 \
      --policy-document file://policy-01.json

ここはアクセスさせたい対象に応じて設定すれば良いと思う。

Account xxxx-xxxx-0002 の設定

IAM Role

以下の Trust relationships を適用して IAM Role の role-02 を作成する。

$ cat role-02.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

$ aws \
  --profile ${Account xxxx-xxxx-0002 の PROFILE} \
    iam create-role \
      --role-name role-02 \
      --assume-role-policy-document file://role-02.json \
      --query Role.Arn \
      --output text

IAM Role に付与するポリシー

arn:aws:iam::xxxxxxxx0001:role/role-01 に対して AssumeRole 出来るポリシーを付与する。

$ cat policy-02.json
{
    "Version": "2012-10-17",
    "Statement": [
       {
           "Effect": "Allow",
           "Action": "sts:AssumeRole",
           "Resource": "arn:aws:iam::xxxxxxxx0001:role/role-01"
       }
    ]
}

$ aws \
  --profile ${Account xxxx-xxxx-0002 の PROFILE} \
    iam put-role-policy \
      --role-name role-02 \
      --policy-name policy-02 \
      --policy-document file://policy-02.json

Instance Profile

$ aws \
  --profile cloudpack-kappa \
      iam create-instance-profile \
        --instance-profile-name role-02

$ aws \
  --profile cloudpack-kappa \
      iam add-role-to-instance-profile \
        --instance-profile-name role-02 \
        --role-name role-02

最終的にこんな感じ?

こんな感じで図に書くとわかり易い。個人的に。

f:id:inokara:20170708102819p:plain

動作確認

STS に AssumeRole して一時的に認証情報を取得するスクリプト

Account xxxx-xxxx-0002 の EC2 から Account xxxx-xxxx-0001 の S3 バケットにアクセスする為には STSAWS Security Token Service) に AssumeRole して一時的に認証情報を取得する必要があるので、以下のような AWS SDK for Go を利用したツールを使って認証情報を取得するツールを噛まして S3 バケットにアクセスしてみる。

gist.github.com

Account xxxx-xxxx-0002 の EC2 で以下のように実行する。

./oreno-assume -role_arn arn:aws:iam::xxxxxxxx0001:role/role-01 -command "aws s3 ls s3://foobar/"

Access Denied

oreno-assume を利用していない場合には、以下のように Access Denied となる。

$ aws s3 ls s3://foobar/

An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied

アクセス OK

Assume Role してからアクセスすると…以下のようにアクセス出来る。

./oreno-assume -role_arn arn:aws:iam::xxxxxxxx0001:role/role-01 -command "aws s3 ls s3://foobar/"
                           PRE logs/
2014-07-01 01:29:52          0 404.html
2014-12-05 01:14:23         37 Hello.txt
2014-12-04 23:52:22         87 hello.html
2014-07-01 01:29:52          0 index.html

終わり

クロスアカウントアクセスのポイント

  • 信頼する AWS アカウント又は IAM Role 及び IAM User をプリンシパルした IAM Role を作る(チュートリアル中の role-01 を指す)
  • ↑で作成した IAM Role にアクセスさせたいリソースへのポリシーを付与する(チュートリアル中の policy-01 を指す)
  • 信頼されている AWS アカウント又は IAM Role(チュートリアル中の role-02 のこと)には role-01 に対する Assume Role 権限が付与されたポリシーをアタッチする(チュートリアル中の policy-02 を指す)

ちゃんと用語を理解しきれていないので誤りがあるかもしれないが…思ったりよりも簡単だった。

参考

docs.aws.amazon.com

blog.serverworks.co.jp

そして、俺の夏が

はじまる。

2017 年 07 月 07 日(金)

七夕

なのに今日も引き続き大雨。

ジョギング

  • 香椎浜 x 2 周
  • 晴れ間にスタートしたけど、帰りはシトシト雨に降られた

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

終日

ベランダの風の抜け方が気持ち良かったので終日ベランダで作業。

ベランダがオフィス。

この写真を遺影にしたいと思う。

2017 年 07 月 06 日(木)

大雨

  • すごいことになっている
  • 亡くなった方もいらっしゃるようで、被災された方々には心からお見舞い申し上げます

ジョギング

  • 雨の為無し

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

奥さん

最後の有給を使って体を休ませることに。義父が亡くなってからずっと気持ちが張り詰めていたし、最近の暑さなどが追い打ちになってしまったのだろう。

とりあえず、今日はゆっくり休んでもらって、明日は元気に仕事に行けるといいな。

2017 年 07 月 05 日(水)

ジョギング

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

奥さん

仕事から帰ってくるなり体がだるいと言って寝込む。暑さの影響かな…心配。

ひとまず、特製ビビンバ丼(肉なし)を作って少しだけ食べさせる。

2017 年 07 月 04 日(火)

タイフーン

朝からタイフーンの影響による雨だったのでジョギングはお休み。足も痛いし。

日課

  • (腕立て x 30 + 腹筋 x 30) x 3

夕飯

パスタを作る。パスタの茹で加減が絶妙だったと思う(過去に作ったパスタ比)