ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Alibaba CloudにISUCONの模擬試験環境を構築する(Terraform編)

はじめに

した。

github.com

さて、今年もISUCON出ます。去年何もできなかった自分に対して圧倒的な成長を実感できる予感がしています。

チーム内でいろいろ作戦会議をしてますが、最初の30分それぞれ何をするのか、そして実際にできるのかの模擬練習をしておいたほうがいい、という意見が出まして、ヨッシャ環境構築するぞとなりました。

Alibabaもalicloud providerもはじめてでしたが、なんやかんやでとりあえず1台インスタンスが立ってGlobal IPにsshできるところまできました。

事前準備としては - Terraform userの作成、Administrator権限の付与 - keypairの事前登録、keypair名をtfファイルに更新

ができれば動くはずです。 ちなみにちゃんとTerrafrm 0.12.6にしました。ちゃんとした。

Alibaba Cloud、普段クラウド触ってればだいたい雰囲気同じ感じでなんとなしできると思います。

ユーザに関しては Resource Access Management -> ユーザ -> 新規ユーザで。Administrator グループを作ってそこにterraformユーザをいれてあげる。そのグループに権限付与ポリシーでAdministratorをあてる、だったはず。 まぁAWSのユーザ、ロール、ポリシーと同じノリです。

新規ユーザ作成時にkeyとsecretが生まれるのでそれを.envrcにいれて環境変数で読めるようにしましょう。

$ cat .envrc.sample
export ALICLOUD_ACCESS_KEY="secret_secret"
export ALICLOUD_SECRET_KEY="secret_secret"
export ALICLOUD_REGION="ap-northeast-1"

keypairですが、新規に作るのも面倒なので、自分のGitHubに登録してある公開鍵を使って https://github.com/chaspy.keys 既存のkeyをimportする形にしました。 そのkeypairの名前だけterraformの keypair attachment resource にいれてあげる必要があります。

resource "alicloud_key_pair_attachment" "attachment" {
  key_name     = "key_pair_github" # Create key pair by hand
  instance_ids = ["${alicloud_instance.web.id}"]
}

Applyするとoutputにglobal ipがでるので、sshすればよいです。

余談だけど普段ラッパースクリプトとかCIとかでしかTerraform実行しないので terraform ってフルスペル入力するのしんどくてエイリアスした。。。

$ tf apply
(snip)
Apply complete! Resources: 11 added, 0 changed, 0 destroyed.

Outputs:

ip = 47.74.4.123

$ ssh root@47.74.4.123

Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-52-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


Welcome to Alibaba Cloud Elastic Compute Service !

root@isucon8:~#

おそうじも簡単でらく。

$ tf destroy
(snip)
Destroy complete! Resources: 11 destroyed.

このあと複数台構成にするとかいろいろやるかもしれない。

次はAnsibleでApplicationを構築するところをやります。いうて以下を流すだけになると思うが。

github.com

おまけ

alicloud-providerに軽微なPR2件出した。マージされろー。

github.com

github.com

delete branch botというGitHub Appをクローズした

はじめに

した。

github.com

ついにGitHubオフィシャルでPRをmergeしたあとbranchを削除する機能が出たからだ。

help.github.com

作ったときの記事

blog.chaspy.me

少し残念な気もするが、個人のリポジトリで1年弱、何の問題もなく安定稼働していたし、lambdaでまともになにか作ったのも、GitHub Appを作ったのもはじめてだったのでいい経験になった。

datadogでどれだけ呼ばれたかは監視をしていて、これを機に確認してみた。

f:id:take_she12:20190818131305p:plain

なにげに使用数は少しずつ最近は伸びていて、多いときに1日500回ほど呼ばれていたようだ。そういや会社の一部のリポジトリで「branchを消す文化」のないところがあったので入れたのもあったかもしれない。

このDashboardも削除した。

サービスだったりアプリケーションを「ちゃんと」クローズするのも大事だと思うので喜んでバイバイした。

またなにか誰かに使われるものを作れたらいいな。

Terraform meetup tokyo#1を開催しました

はじめに

しました。

terraform-jp.connpass.com

ありそうでなかったmeetupだったので、思った以上に注目度が高かったようでした。しかし注目度だけが先走ったせいもあり参加率は悪く、具体的には書きませんが"最悪"の数字を叩き出したので次回以降は対策を練っていきます。

モチベーションが高いひと、これたはずだけど諦めたひとがこれないようなコミュニティにしたくない。

会場の様子。オイシックスさんの会場スケーリングできるからすごいんですよね。。。

f:id:take_she12:20190804233744j:plain

LTの様子。運営メンバー4名が発表しました。

f:id:take_she12:20190804233800j:plain

Hashicorpさんの"ハシ"を入手した運営メンバー。

f:id:take_she12:20190804233927j:plain

いつ使おう。まだ使っていない。

f:id:take_she12:20190804235235j:plain

Terraform-jpでは「せっかく勉強会に来ているのに何も話さないで帰るなんてもったいない(ありえない!)」という考えを大事にしており、ワールドカフェ形式でグループごとに話す取り組みに挑戦しました。

僕自身もやったことがなかったのですが、アンケートやTwitterを見る限り知見を得られた、来てよかったという声がいくらかあり、価値はあったようです。

懇親会で話していても、「1人でTerraformをしていて話せるひとがいない」というひとは結構な数いて、そういうのを支えあえる勉強会、コミュニティ(Slackを含め)であればいいと思いました。

また、飲食スポンサーはなんとHashicorpさんにお願いしました。申し分ない量のお酒とお菓子とつまみを提供いただき、また参加者にとっても有益であるTerraformの情報を話していただき、非常に助かりました。

meetup自体は今後も続けますので、今後もスポンサーをお願いする機会があればぜひに、という感じです。

Terraform-jpの"オフ会"はニッチなSource Code Readingと、meetup(Lightning TalkとWorld cafe)を隔月でやっていく予定です。なお実施日程は毎月最初の平日です。理由は特にないです。

次回 9/2 Source Code Reading#2

connpass.com

その次 Terraform meetup tokyo#2 10/1(火)です。よろしくおねがいします。LT公募します。

実際にコミュニティ駆動でaws providerにPRを出せて晴れてcontributorになれて本当によかったです。今後も仕事でDeepに使っていくはずなので、Contribution & より深い理解 & Communityを盛り上げていきたいと思います。

Lightning Talk資料はこちら。まぁcode読むと怖くなくなるし最新verにするモチベあがるしいいことあるのでみんなでやろーぜ、ということを言いたかっただけの資料です。

言い損ねたけどこのコミュニティからContributor10人出したいなぁと思ってるのでやっていきましょう。

この業界に入って、Softwareの、Opensourceのコミュニティに、勉強会に助けられてきたので、それを提供する側にまわれて恩返しできたのが嬉しいです。

ぜひTerraformユーザの方は気軽に遊びにきてくださいね。それでは!

Terraform aws provider PR / lambdaのnode engine v6.10のEOL対応

はじめに

github.com

mergeされた!

これはなにかというと、Lambda側でnodeのengine v6.10がEOLのせいでapplyにこけたので、テストとドキュメントを修正した。

もともとは別の aws_lambda_permission resourceのimport supportをやろうとしていた。

github.com

このページの以下のサンプル。

resource "aws_lambda_permission" "allow_cloudwatch" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.test_lambda.function_name}"
  principal     = "events.amazonaws.com"
  source_arn    = "arn:aws:events:eu-west-1:111122223333:rule/RunDaily"
  qualifier     = "${aws_lambda_alias.test_alias.name}"
}

resource "aws_lambda_alias" "test_alias" {
  name             = "testalias"
  description      = "a sample description"
  function_name    = "${aws_lambda_function.test_lambda.function_name}"
  function_version = "$LATEST"
}

resource "aws_lambda_function" "test_lambda" {
  filename      = "lambdatest.zip"
  function_name = "lambda_function_name"
  role          = "${aws_iam_role.iam_for_lambda.arn}"
  handler       = "exports.handler"
  runtime       = "nodejs6.10"
}

resource "aws_iam_role" "iam_for_lambda" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

runtime = "nodejs6.10"

ここね。

EOLになってるので The runtime parameter of nodejs6.10 is no longer supported for creating or updating AWS Lambda functions. という怒られが発生する。

aws.amazon.com

代わりに10.xが使えるので、古い世代をやめて1世代分送った感じ。

今回は実装ではないにせよ、ドキュメントの修正も大事な貢献だと思う。ちなみにaws providerのdocumentは website 以下にあるので気づいたらどんどんPR投げたらいいと思う。

github.com

おわりに

方針がよくわかんなかったのでとりあえずreplaceして投げたら丁寧にコメントくれて、その指摘に対応したらマージされた。

昨日からこのリポジトリのissue/PRをwatchしてるけど、かなりのスピードでReview/Mergeされていて、Hashicorpのcore committerたちしっかり働いています。いずれも24時間以内に反応もらえる感じです。

次は元々やろうとしてた lambda_permission のimportをやろうと思う。

Terraform importの実装

はじめに

PRを出した。(mergeまではしばらく時間がかかりそうな雰囲気)

github.com

Autoscaling groupのlifecycle hookのimportをsupportするというニッチ(?)なissueを解決するためのもの。

そもそも先日行った Source Code Readingのオフ会をきっかけに、次のmeetup(8/1を予定)までに何か1つPRだすぞーといって出したもの。準備からコード読み含めて連休の結構な時間を使った。

terraform-jp.connpass.com

このissue自体もcontributorのkterada0509 さんが教えてくれて、参考の実装まで教えてくれて手取り足取りどころではない感じで圧倒的感謝です。

結果的にほぼ参考実装の丸コピにはなったものの、理解するために手を動かしていい経験になった。

Terraform import

そもそもimportとは何かというと、既存のリソースをTerraformの管理下におくこと(=stste fileにとりこむこと)である。

tffileは生成してくれないので、実際はimportしたあとplanの差分を埋めるべくtffileを書く必要がある。

コマンドはこんな感じになる。

$ terraform import <resource type>.<resource name> <resource id>
# terraform import aws_autoscaling_group.chaspy_test_asg test-asg

こんな感じになる。

で、インポートする時点では中身は空でいいのでtffileに以下のような定義をおいておく必要がある。

resource "aws_autoscaling_group" "chaspy_test_asg" {
}

test-asgというのが実際にAWS上にあるAutoscaling Groupの名前である。

コードを読む / ストレートにImportする

さて、ではこのAutoscaling Groupのリソースファイルを見てみよう。

https://github.com/terraform-providers/terraform-provider-aws/blob/v2.19.0/aws/resource_aws_autoscaling_group.go#L28:titie

ポイントしてるように、Importを可能にするにはこのようなImporterを実装する必要がある。

     Importer: &schema.ResourceImporter{
            State: schema.ImportStatePassthrough,
        },

ImportStatePassthrough が何を意味しているかというと、cliの第2引数で受け取ったidが、そのままresource idとして使える場合、そのまま実際のリソースの情報を resourceAwsAutoscalingGroupRead functionで読み取り、その内容をstateファイルにつっこむことになる。

もしこのようにストレートにインポートできる場合で、importがsupportされていなければ、この部分を追加するだけでimportできるようになる。

Importがストレートにいかない場合

では今回のPRのように、 ImportStatePassthrough ではうまくいかないパターンはどんなパターンか。

参考にした AutoscalingPolicyと同じく、そのリソースのidだけではresourceのgetができないような場合はimportを工夫する必要がある。

参考にした実装のAutoscalingPolicyのドキュメントを見てみよう。

www.terraform.io

$ terraform import aws_autoscaling_policy.test-policy asg-name/policy-name

なぜこうしているかというと、policy-nameだけではリソースが一意に定まらないからである。

cliを見てもわかるが、autoscaling policyはautoscaling groupが必須である。(そりゃそうだ)

docs.aws.amazon.com

で、import実行時にはasg nameとpolicy-nameを/区切りで入力させることにしている。

ではこの実装を見てみよう。

terraform-provider-aws/resource_aws_autoscaling_policy.go at v2.19.0 · terraform-providers/terraform-provider-aws · GitHub

passthroughするわけにはいかないので、オリジナルのimport用functionを実装している。

     Importer: &schema.ResourceImporter{
            State: resourceAwsAutoscalingPolicyImport,
        },

terraform-provider-aws/resource_aws_autoscaling_policy.go at v2.19.0 · terraform-providers/terraform-provider-aws · GitHub

期待している <asg-name>/<policy-name> がきた場合、スラッシュ区切りで分けて、そのリソースのpropertyにsetするとともに、SetIdでidを付与している。

逆に言えばpassthroughの場合、このd.idがそのままそのリソースにSetIdされることになるのだろう。

今回取り組んだ Autoscaling Lifecycle Hookも同じような構造であったため、ほぼそのままの実装でいけた。

おわりに

これまで使われている、使っているOSSへのContributionができていなかったので、今回挑戦できて本当によかった。

8/1のmeetupのLTで話す内容だが、このPRを送るための事前準備、debug方法、テスト方法などなどもまとめてブログに書く予定。

はやくマージされないかなー


追記:7/16 Mergeされました!

github.com

MongoDB In Action 2nd Edition Chapter 10 "Chapter 10. WiredTiger and pluggable storage" を読んだ

はじめに

読んだ。

MongoDB in Action: Covers MongoDB version 3.0

MongoDB in Action: Covers MongoDB version 3.0

  • 作者: Kyle Banker,Peter Bakkum,Shaun Verch,Doug Garrett,Tim Hawkins
  • 出版社/メーカー: Manning Publications
  • 発売日: 2016/04/15
  • メディア: ペーパーバック
  • この商品を含むブログを見る

2012年に出た1st Editionの日本語訳も中古で買って一通り読んだんだが

MongoDBイン・アクション

MongoDBイン・アクション

v3.0サポートの 2nd Editionが出ていて、

この版で新しくWired Tigerとプラガブルストレージの章が追加されていたので、ひとまずここだけ読む。

Manningのページから "pBook+eBook+liveBook includes previous edition" を買ったが(お得)

www.manning.com

liveBookが便利。オライリーSafariみたいな感じのだけど、ブラウザで見れるので、Mouse Directoryで単語の意味がシュっと出せる。

gigazine.net

f:id:take_she12:20190701031532p:plain


  • Storage Engineについて
    • Storage EngineはClusterの挙動やMongoDBへアクセスするDriver、mongo shellに影響を与えない
    • しかし実際のファイルに読み書きする際に影響する
  • なぜPlugubleにする必要があるのか / 異なるストレージエンジンを使う必要があるのか
    • 記事があり、大量に読まれるNewssiteとTwitterのようなSocial Mediaがあるとする
    • documentの数、サイズ、動的にコンテンツが提供されるか、という点で違いがある
  • Wired Tigerについて
    • Wired Tigerへの移行、設定は読み飛ばし
    • Option
      • dbPath: dataが保存されるpath
      • journal.enabled: ジャーナルが有効かどうか
      • engne: wiredTiger or nmapv1
      • engineConfig.cacheSize: キャッシュとして使うメモリサイズ
      • engineConfig.journalCompressor: ジャーナルで使用する圧縮タイプ。
      • collectionConfig.blockCompressor: コレクションの圧縮方式
      • indexConfig.prefixCompression: インデックスを圧縮するかどうか
  • MMAPv1との違い
    • nmapv1, wired tigerの各圧縮方式3つで性能比較した
      • 圧縮なし、snappy, zlib
      • それぞれの設定ファイルを示した
      • insertのscriptをかいた
    • insertのテストでは、起動時間にnmapv1と大きな差があった
      • まぁこれは一度限りなのであまり重要ではないが
      • データの圧縮率が非常に大きい点でWired tigerが優れている
    • readのテストでもWired Tigerが上回っている
    • ベンチマークの結論
      • 少なくとも、データ圧縮の点でWired Tigerが明らかにすぐれている
    • 他のストレージエンジンについては読み飛ばし
    • ストレージエンジンがMongoDBからどのように呼ばれてるか、も飛ばし

おわりに

NMAPv1との違いとそのベンチマークに焦点をあてており、Wired Tigerのパフォーマンスについてはは書かれていなかった。

つぎはMongoDB In Action 2nd Editionを動かしつつ2週目読むか。

オライリーのほうも気になっている、第3版がいまアーリーリリース。でもSafariやめちゃったんだよな。やむなし。

learning.oreilly.com

9月発売か。そしてこれはMongoDB v4.0対応。

かといって2版はMongoDB v2.4だし、うん、発売を待つかな。

はじめてのMongoDBを読んだ

はじめに

読んだ。

はじめてのMongoDB (I・O BOOKS)

はじめてのMongoDB (I・O BOOKS)

結構薄いんで先にばーっと読んだしまったあと、(MongoDB イン・アクションもこのあとばーって読んだ)検証環境でざーっと動かして2周した感じだ。

最初の一冊としてざっと全体感をつかむにはちょうどいい。ただどのみちがっつりやるならMongoDB イン・アクションのほうが量も多いしいろいろ深い。この本はアプリケーションエンジニア向けで、インアクションのほうはDBAまで対象にしてる感じ。

インストールまわりは終わらせていたので、内容としては

  • 基本的なMongo shellの操作
  • import / export
  • インデックス
  • Ruby(Sinatra)アプリからのアクセス

というところが触れられていてよい。

また、

  • バックアップ・リストア
  • Replicaset
  • シャーディング

は付録でちゃんと触れている。必要になれば調べられるように、ちゃんと紹介されていてよい。

Sinatraについては写経して動かした。

github.com

誤植がいくらかあったりしたが、なおしつつちゃんと最新のRuby, Sinatra, mongo drverで動いたのでよかった。

  • Ruby: 2.6.2
  • Sinatra: 2.0.5
  • Mongo Driver: 2.9.0
  • MongoDB: 3.2.22

ソースコードGitHub公開だったら誤植PR送るけど光学社ページからのDLなので挫折。

おわりに

こっちはlocalのruby / sinatraで動かして、MongoDBは chaspy/vagrant-mongodb を使えた。べんり。一応mongoのhostとportは環境変数から取るようにした。

github.com

やっぱSinatraはいいな。