masarasiの日記

私は Mackerel CRE テクニカルサポート担当です。

terraform provider mackerel をはじめて使った

terraform provider mackerel をはじめて使ってみました。

terraform は使ったことがなかったので難しそうなイメージだったのですが、導入から実行まで意外と簡単に使えました。

terraform provider mackerel は Terraform Registry で公開しています。

registry.terraform.io

インストール方法

インストールは公式ドキュメントの内容に沿って行う。

developer.hashicorp.com

Install Terraform の項目でインストールする環境のインストール方法を表示する。ここでは Linux を選択し、Amazon Linux に表示される yum コマンドを実行する。インストールはこれだけで完了。

任意で Quick start tutorial の内容を実行してちゃんと動くか確認する。

セットアップ

適当なディレクトリの中に main.tf を作成する。

下記は Mackerel の通知チャンネルを新規作成する場合の例。

terraform {
  required_version = ">= 1.3.0"
  required_providers {
    mackerel = {
      source  = "mackerelio-labs/mackerel"
      version = "~> 0.3.0"
    }
  }
}

resource "mackerel_channel" "email" {
  name = "terraform"

  email {
    emails = ["xxxxx@xxxxx.ne.jp"]
    events = ["alert", "alertGroup"]
  }
}

main.tf 解説

terraform のバージョン指定

terraform {
  required_version = ">= 1.3.0"

terraform のバージョンを指定する。演算子の意味は下記の通り。

  • = 指定したバージョンのみ許可
  • != 指定したバージョン以外を許可
  • >, >=, <, <= 左から、指定値より大きい、以上、未満、以下、のバージョンを許可
  • ~> 末尾の数字が指定値以上のバージョンを許可
    • たとえば ~> 1.0.0 の場合 1.0.11.0.2 は許可されるが 1.1.x は許可しない
    • ~> 1.x にした場合 1.11.2 が許可される

自分の環境では v1.3.7 だったので => 1.3.0 にしている。

terraform -v
Terraform v1.3.7

バージョン指定については公式ドキュメントを参照。

developer.hashicorp.com

terraform provider mackerel の読み込み

  required_providers {
    mackerel = {
      source  = "mackerelio-labs/mackerel"
      version = "~> 0.3.0"
    }
  }

version はその時リリースされているバージョンに合わせる。

Mackerel への設定内容

resource "mackerel_channel" "email" {
  name = "terraform"

  email {
    emails = ["xxxxx@xxxxx.ne.jp"]
    events = ["alert", "alertGroup"]
  }
}

terraform provider mackerel ドキュメント を参照して、Mackerel に実行したい設定を記述する。上記は terraform という名前の Email channel を新規作成する場合の内容。詳しくは Resource: mackerel_channel を参照。

初期化

初回のみ実行する。

terraform init

実行

terraform apply

main.tf を元に実行される内容が表示される。

Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # mackerel_channel.email will be created
  + resource "mackerel_channel" "email" {
      + id   = (known after apply)
      + name = "terraform"

      + email {
          + emails = [
              + "xxxxx@xxxxx.ne.jp",
            ]
          + events = [
              + "alert",
              + "alertGroup",
            ]
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:

Enter a value:yes を入力して Enter を押すと実行される。

確認

Mackerel に通知チャンネルが作成されました。超簡単。

Go言語でAPIを実行するプログラムを作る②

masarasi.hatenablog.com

続き

残作業(前回より)

  • 企業 ID やアクセストークンは変数で渡したい(そもそも出来るかはわからない)
  • POST メソッドで打刻するプログラムに変更する
  • UI を作る

AKASHI 公開 API について

前回、AKASHI の API について全く触れていなかったので、ここで整理。

AKASHI の 公開 API は以下。

AKASHI 公開API 仕様

現在、とりあえず API を実行する検証として、以下の打刻情報取得を行っているところ。

6.7 打刻情報取得API

打刻情報取得 API の実行には以下が必要。

  • ログイン企業ID
  • トークン(token) - 自分の ID に API の実行権限が必要(管理者に付与してもらう)。マイページから発行する。
  • 開始日時(start_date)
  • 終了日時(end_date)
  • 従業員ID

ログイン企業ID、トークン、従業員ID については毎回固定なのでコードに埋め込みでもよさそう。 開始日時と終了日時は実行の度に変えたいので、コマンドライン引数で渡せるようにしたい。

進捗②

調べると flag パッケージを使うとコマンドライン引数をうまく処理してくれそう。 というわけで開始日時と終了日時をコマンドライン引数で渡せるように改修した。 コードの内容は以下。主に前回からの変更部分のみ記載。

func main() {
    // オプションを定義
    var startDate string
    flag.StringVar(&startDate, "start_date", "", "Start Date")
    var endDate string
    flag.StringVar(&endDate, "end_date", "", "End Date")
    flag.Parse()

    // 空のurl.URL構造体のポインタ
    u := &url.URL{}

    〜〜〜〜〜

    // クエリマップに値をセット
    q.Set("end_date", endDate)
    q.Set("start_date", startDate)
    q.Set("token", "<アクセストークン>")

実行方法

go run ak4.go -start_date=20220301000000 -end_date=20220331000000

※取得範囲 2022/3/1 〜 2022/3/31

難しかったところ

ググるとたくさんやり方が出てくるのでどの方法でやればいいのか困った。とりあえずうまくいったけど、オプションが増えるとこのやり方ではしんどいと思うので、もっとスマートな方法はあると思う。flags パッケージとかは構造体を使っていい感じにやってくれそうだったけど、今の自分には扱えそうになかった。

残る作業

  • POST メソッドで打刻するプログラムに変更する
    • サブコマンドでこれまでの情報取得と打刻の両方が出来るようにしたいと思い始めた
  • UI を作る

Go言語でAPIを実行するプログラムを作る①

勉強のために Go 言語で API を実行するプログラムを作り始めている。

はてなでは勤怠管理に AKASHI というシステムを使っていて、出勤時と退勤時にボタンを押すというもの。そしてこれをよく忘れる。。。

画面を開く > ログインする > 打刻(出勤/退勤ボタンを押す)

たったこれだけの操作だけど忘れてしまうんだよな。なので、この操作をとことん簡略化することで押し忘れを防ごうという計画。

まぁ、その目的のためなら他に方法はたくさんありそうだけど(社内には StreamDeck でやっている人がいる)、主目的は Go の勉強なので一石二鳥を狙ったかたちだ。

ゴール

1 クリックで出勤/退勤が出来る UI を作る

進捗

いきなり POST するプログラムを作るのは怖いので、AKASHI から打刻情報を GET で取得するプログラムを作った。

作成にあたってはこちらを参考にさせてもらった。

golangstart.com

AKASHIから打刻情報を取得するプログラム

※不要なコードが含まれている可能性は多分にある

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "net/url"
)

func main() {
    // 空のurl.URL構造体のポインタ
    u := &url.URL{}

    // 構造体のフィールドに値をセット
    u.Scheme = "https"
    u.Host = "atnd.ak4.jp"
    u.Path = "/api/cooperation/<企業ID>/stamps"

    // Queryメソッドでクエリパラメータのマップを取得
    q := u.Query()

    // クエリマップに値をセット
    q.Set("end_date", "20220131000000")
    q.Set("start_date", "20220101000000")
    q.Set("token", "<アクセストークン>")

    // クエリパラメータをエンコード
    u.RawQuery = q.Encode()

    // String 型に変換
    uStr := u.String()

    // リクエストを作成
    req, _ := http.NewRequest("GET", uStr, nil)

    //requestにheaderをつける
    req.Header.Add("Cotent-Type", `application/json"`)

    //クライアントを作成
    var client *http.Client = &http.Client{}

    //結果を変数に代入
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }

    // deferでクローズ処理
    defer resp.Body.Close()

    //読み込み
    body, _ := io.ReadAll(resp.Body)

    //出力
    fmt.Println(string(body))
}

難しかったポイント

NewRequest の URL 指定

構文

func NewRequest(method, url string, body io.Reader) (*Request, error)

実際のコード

req, _ := http.NewRequest("GET", uStr, nil)

送信先の URL は u := &url.URL{} の通り u に格納されている。NewRequest の引数 url に初め u をそのまま書いてエラーになった。url は string 型でなければいけないが、url.URL{} は構造体のためそのままでは使えないので、uStr := u.String() で string 型に変換する必要があった。

残る作業

  • 企業 ID やアクセストークンは変数で渡したい(そもそも出来るかはわからない)
  • POST メソッドで打刻するプログラムに変更する
  • UI を作る

Goプログラミング実践入門をはじめた

業務で Go のソースコードを読むことはよくあって、入社してから半年間で少しはわかるようになったと思う。

ただ、なんとなくわかるというレベルで、複雑なコードになるとよくわからない。

自分でプログラムを作るなんて出来っこない。

それでも知識ゼロから少しはわかるようになったのはうれしくて、もっと詳しくなりたいと思っている。

そこでこの本を購入した。手を動かすのが一番よいはず。

Amazon.co.jp: Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ eBook : Sau Sheong Chang, 武舎 広幸, 阿部 和也, 上西 昌弘: 本


そしていきなりつまずいた。

まずはかんたんなプログラムを使って動かしてみよう!っていう、この手の本のお約束な感じで話は進むけど、

go install first_webapp

go install: version is required when current directory is not in a module
    Try 'go install first_webapp@latest' to install the latest version

エラー...

モジュールが見つからない??

ググったらドンピシャな記事があった。

zenn.dev

Go1.16 から Go Module がデフォルトで ON になったので、以下のようにする必要があるとのこと。自分の環境は Go1.17.3 だった。

go mod init first_webapp
go build
first_webapp

こちらのとおりにやったらうまくいった。ありがたい。

f:id:masarasi:20220208164836p:plain

電子書籍版なのでこのあたりは Go の最新バージョンに合わせてアップデートされるとうれしい。

ふるさと納税 購入編

おあつらえ向きに11/18から楽天ブラックフライデーセールが始まったので、ふるさと納税5自治体分を購入した。

違うショップで買えば買うほどポイント倍率が上がるというお買い回りシステム(10ショップまで、1ショップ¥1,000以上購入が条件)だったので、ふるさと納税とすこぶる相性がよい。加えて、11/18はダイヤモンド会員ポイント+3倍(上限1,000P)、11/20は0と5のつく日でポイント+2倍(上限3,000P)だったので、この日に買うとさらにお得という感じだった。

 

サトウのご飯(山形県

普段家で米を食べることはほぼないけど、それは炊飯するのがめんどくさいだけですぐに食べられる米があるならば食べる。炊きたてにこだわりはない。

 

うなぎ(鹿児島県)

今年も申し込んでしまったうなぎ。去年と自治体は違う。サトウのご飯も申し込んであるし、もう無敵である。ただ、発送がかなり早くて今週中にもう届いてしまうらしい。当然米はまだ届いていないのでスーパーでサトウのごはんを買って食べてしまいそうである。すぐにうなぎの返礼品がほしい人にはおすすめ。

 

ハンバーグ(佐賀県

ご飯だけたくさんあってもおかずに困るので申し込んだ。冷凍されていて賞味期限が365日なので食べきれないなんてことはまずない。米とハンバーグを一緒に食べる日が楽しみである。

 

すき焼き肉(宮崎県)

先日知り合いにすき焼きをごちそうになった。またやろうという話になり、自分がふるさと納税で肉を調達することになっていたので申し込んだ。到着は1月中になるようだ。楽しみである。

 

ROYCEスイーツ詰め合わせ(北海道)

甘いものは大好き。あんまり深く考えず選んだけどROYCEがうまいのは知っているし、間違いはないはず。

 

 

去年は中部・近畿への納税だったが、今年は東北・北海道・九州になった。県もかぶっていないし、いい感じにばらけている。47都道府県への納税を目指してみるのも良いかもしれない。それならばせっかくなので名産品とかにすればよかったなと今さら思った。

 

ふるさと納税 去年のふりかえり編

今年まだふるさと納税をやっていないことに気づいた。4月の時点で転職することが決まっていて、年収も変わるので転職後に落ち着いたらと思っていたけど、年内に届くようにするにはそろそろ頼まないといけない気がしている。ただ、どこに寄付をするか全然考えていない。一旦、昨年の返礼品を振り返ってみる。

ティッシュ山梨県富士宮市

確実に使うものなのでチョイス。60箱もあって昨年7月に申し込んでから1年と4ヶ月ぐらい経ったけどまだ半分ぐらい残っている。今のペースでいけば確実に来年の終盤まではティッシュを買わない生活が約束されている。唯一置き場所に困っていたけど突っ張り棒で浮かせることでスマート収納を実現している。

入浴剤(兵庫県赤穂市

桃、柚子、森という異なるタイプが60錠ずつで180錠入りだった。夏以外は毎日湯船に浸かりたい派なのでこれは結構順調に使い切った。リピートしても良い気はしているけど、桃の甘い香りがあまり得意な感じではなかったのでそこだけがネック。あとこいつも若干置き場に困る。

うなぎの蒲焼き(和歌山県有田市

うなぎは大好きなので120gぐらいの蒲焼き2本入りを2セット分申し込んだ。冷凍されていて湯煎で解凍するだけでもうまいし、解凍した上でトースターで表面を焼くと香ばしさが増してさらにうまくなる。一緒についてくるタレがちょっとイマイチな気がしたけど、お家でこれが食べられるのはかなりアリだった。これはまた頼んでもいいなと思う。平べったいので置き場所には困らないし、冷凍庫を開くたびにうなぎが目に入るのは結構うれしい気持ちになれる。

エビスビール(静岡県焼津市

350mlの1ケース。エビスが好きな父親へ献上。自分は飲んでないけど飲まなくてもわかる。うまい。自分用に申し込むなら香るエールが飲みたい。

コシヒカリ新潟県長岡市

5kg。実家へ献上。食べてないので味がどうなのかはわからないけど、魚沼産って有名なので多分うまい。ただ普段家では料理をしないしお米も炊かないので多分頼むことはない。パックご飯も返礼品としてあるみたいなので、そっちは割とアリな気がしている。

 

昨年は楽天のお買い物マラソンで購入してポイントうまうまだったので、またそのタイミングで頼みたいけど、ちょうど今開催中で11/11で終わるという事実を知った。今月末あたりにまた開催してくれるといいけど。

1ヶ月

毎週ブログを書こうと思っていたのに3週目にして早速サボってしまった。

 

はてなに入社して1ヶ月が経過した。8月25日にテクニカルサポートの実務に入り、OJTしてもらいながらではあるものの毎日サポート業務を行っている。現状、1日がほとんどサポートだけで終わってしまう。お客さんからの問い合わせ対応から学べることはとても多いけど、受け身なままではいたくないので、問い合わせの対応スピードを上げて、時間を生み出し、その時間で自ら学んでいけるようにならねばならない。

 

直近あったイベント

セールスチームのアクションプラン発表会を拝聴した

前職ではセールスチームがどんな目標でどんなアクションを取っていくのか共有されたことなんてなかったので新鮮だったし、チーム内でそれを共有して質問し合ったりするのは良い文化だと思った。セールスチームの目標達成において、CREが協力していける部分もあるんだと勉強になったし、自分も早くそれが出来る力をつけたい。

 

技術勉強会(通称:ギ勉)で自己紹介をした

はてなでは毎週木曜日にエンジニアが集まる勉強会を開催している。普段は聞くだけで、聞いてる内容もレベルが高くてあまり理解は出来ていないんだけど、2日前ぐらいに急遽自己紹介をすることが決まった。大勢の前で話すのは得意ではないし、やり終えるまでは胃が痛かったけど、前職で12年間やってきたことは何かに特化しているわけではないものの幅はかなり広かったと自分でも思うし、いざやると共感してもらえたり笑ってもらったり、多くの人が反応してくれたので嬉しかった。

 

はてなインターンの成果発表会を見た

はてなインターンはすごい。3週間の工程の中で実際にチームへ配属されて短期間で機能開発やリリースまで行う。当然その裏では社員の皆さんのバックアップがあるし、長い時間をかけてインターンの準備もしているが、参加するインターン生のレベルは高い。既存のコードを読んで理解し、自分の意見を言って、それを形にする。最後に開かれたインターン生自身による成果発表会においても説明はわかりやすいし、実際に新しい機能を使ったユーザーの嬉しい反応なども知れてとても良かった。自分は見ているだけだったが感動したし、間違いなく彼らにとって最高の夏だったと思う。