ツナワタリマイライフ

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

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はいいな。

VagrantでMongoDB Replica Setを作る

はじめに

作った。

github.com

いろいろMongoDBをガチャガチャ動かしたくて、まぁDockerで動かすのも普通にできたが、どうせだしReplicaSetも作ろうと思ったので組んだ。

存在は知っていたものの、今回はじめてVagrantのGuest/Hostのhostsを自動設定してくれるやつを使った。

github.com

guestのhostsはこんな感じになる。

vagrant@mongo0:~$ cat /etc/hosts
127.0.0.1   localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost   ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
127.0.1.1   mongo0  mongo0

## vagrant-hostmanager-start
192.168.33.202  mongo2

192.168.33.201  mongo1

192.168.33.200  mongo0

## vagrant-hostmanager-end

Vagrantfileにはこのへんの設定が必要。

  config.hostmanager.enabled = true
  config.hostmanager.manage_host = true
  config.hostmanager.ignore_private_ip = false
  config.hostmanager.include_offline = false

mongodbのreplicasetのinitiate処理だけは全部終わってから、特定の1台であてなきゃならんので別の処理とした。mongo shellのコマンドをどうやってbash scriptから渡したもんかなと思ったが、普通に標準入力で渡してやればいい。

vagrant@mongo0:~$ cat /vagrant/repl.js | mongo
$ cat repl.js
rs.initiate()
rs.add('mongo1:27017')
rs.add('mongo2:27017')
rs.status()
cfg = rs.conf()
cfg.members[2].hidden = true
cfg.members[2].priority = 0
rs.reconfig(cfg)

mongo shellにわたすものなので # でコメントが書けない。 jsなんで // で書けばいいんだろうけど。

おわりに

おもちゃができたのでガンガン遊んでいく。

MongoDB In Actionの2nd Editionが出ていて買ったので、Wired Tigerの章読んで何か書くかも。

www.manning.com

しかしいつになってもVagrantは好きだ。。。こわして作る、再現性があるのがいい。

入社してから1年

たった。シュッと書く。

前回

blog.chaspy.me

まだ1年しか経っていないのか、と思うぐらい成長したと思うし、もう1年も経ってしまったのかと思うほど足りてない部分も山ほどある。

必死になってた最初の3ヶ月過ぎて、半年ぐらいのときが一番しんどかった。すごく時間がかかってしまった。願うならもう二度と同じ体験をしたくない。もしまた転職することがあればこうならないようにしたいけど、まだ答えは見つかっていない。

半年を過ぎて、年明けぐらいからいろいろ新しいことをはじめたりして、ようやくバリューが出せはじめた気がする。

残念ながら英語力は対してあがっていない。先日の海外カンファレンス参加で、やっぱり英語でその場で理解したり、英語でネットワーキングしたり、質疑をしたりする英語力がないとダメだ、と強く思い、具体的な目標もできたのでようやく重い腰をあげてちゃんと努力しようと思う。具体的には でspeakingをVersantで継続的に計測しつつ、カンファレンスの動画を聴いて技術と英語同時にやるしかないなといった感じ。技術も英語も同時に伸ばすの、個別にやってたんじゃ無理だ。

技術力はどうなんだろうな。パフォーマンスについての考え方、AWSの理解、nginx、terraform、kubernetesに関しては仕事で使ってるので嫌でも詳しくなった。ただどうしてもコードを書く量が絶対的に足りてないのを趣味コードでちょいちょいやりつつどうしたもんかなと言った感じ。

多分このあたりはOSSのcontributionで実利をかねてやるのがいい気がしていて、自分で使うツールだけじゃなくて、普段から業務で使ってるOSSへのcontributionもちゃんとやっていかないと、とn年前から言っているが未だにできていない。とりあえずTerraformからやってみようと思っている。

terraform-jp.connpass.com

英語だろうが技術だろうがとにかく思うことは、時間は有限で学ぶべきことは無限にある。このあたりの取捨選択を今まで以上にちゃんと考えないといけないと思う。で結局英語力の問題に帰ってくるのだけれど、書籍はもう日本語ではなく英語書籍から学ぶ、あるいは書籍が出る前に公式ドキュメントを見て動かす、ぐらいが当たり前にならないとダメだ。優秀なエンジニアはこれを当たり前にできている。

環境といえば、やっぱり「環境がひとを変える」とか「一番のへたくそであれ」とか、言葉ではわかっていたことを実際に体験したことが大きい。優秀なエンジニアが多いので、自分の価値観も引っ張られるし、扱う技術に関しても自然とインプットが増える。SREは幸運にも全サービスに横断的に関わるので、目にする技術も多い。(だからこそどこまで学ぶかを迷うのではあるが)

この1年を見返すと、「まぁまぁたいていの仕事は1人でできるようになった」「改善や新しい仕組みの導入もできた」「オンボーディングやExperience mapなどチーム視点での取組もできた」でまぁ60点といったところだ。

次の1年の課題としては、まだまだ不足してる英語力。多めの英文を読むのは今でも時間がかかるし、書くのもまだまだツールに頼っている。リスニングは基本的に一発で聞き取れない。せっかく非日本語ネイティブのロビーが同じオフィスに来たので、さっき言った海外カンファレンスでの収穫を得るためにも、仕事をもっと高いアウトプットを出すためにも、当たり前に必須なので計画立てて継続的にやっていく。

コーディングスキル。これはちょっとどうしたらいいのか、なにが足りてないのかまだうまく分析できていない。一般的な考え方なのか、あるいは言語の学び方なのか、そして何を目標とするかもまだ漠然としているので別でしっかり考えたい。。。

もう1つはチーム視点で、SREもこれからまた少しサイズが増えていくのでチームのことをあれこれするのも少しずつやっていきたい。採用活動も含めて。

あと、ソーシャルやコミュニティ活動を通して、この1年で知り合いがめちゃくちゃ増えた気がする。元々お祭りごとは好きなので、勉強会のたぐいは好きだ。ただ、参加するだけでは得られるものも少ないので、基本的に何かしらの発表をするか、「ちょうどこれを知りたいと思っていた」みたいな技術情報を得られるものでない限りはあまり行かないようにしていた。結局、自分の技術力は仕事を通して得るべきで、ただ話聞いて懇親会で話すだけでは技術力は一切伸びないから仕事をしていたほうがマシだ。

僕はソフトウェアの世界のコミュニティが大好きだ。学生時代から個人が書いたブログにすごいお世話になってきたからアウトプットをしようと思ったし、前職時代に勉強会に参加して、いまSREをやれてるから、自分も運営をしようと思った。この世界に少しでも恩返しがしたい。

SRE Loungeで大き目なイベントをやれたらいいなと思っているので、そっちも楽しみにしつつ、自分もしっかり仕事をして、その仕事の成果を登壇してアウトプットしていこうと思う。

まわりのひとが変わると、自分の「当たり前」が変わる。変わったよ。総じて、転職してよかったと思う。

次は「入社して1年半」でまた書こう。2年にしようかと思ったけど、半年ぐらいでまた振り返っておきたいから。

海外カンファレンスで話すということ

まだ何も終わっていないしなんなら準備もまだなんだけども。恐怖とか不安とかを逃避しようとしているのがよくわかるね。 たくさんフィードバックをもらって、スライド構成を見直して、不要なところをカットしたり新しい具体的な例を追加したりした。

20分。何か1つ、誰かたった1人に伝わればそれでいいと思うし、それが別に海外だろうがなかろうが、勉強会のLTだろうが同じ。 経験したことを共有する、ただそれだけなんだよなぁと言い聞かせるも、緊張するものはする。

昨日はSpeaker Receptionで、日本から参加される藤田さんと合流して参加した。 そのとき思ったことを書き留めておく。

最初は席がなくて藤田さんと2人席で話していたところに、ChairのFrancesが来てくれて、挨拶をしてあっちのテーブルに行きなよと促してくれた。 会場はびっくりするほどノイジーで、静かな場所ですら英語を聞き取れないのに、いわんや、といった状況だった。

それでも、みんな本当にいいやつらで、この記事であと何度言うんだろうって感じだが、それは国内でも海外でも規模関係なく同じだ。 何を話すんだい、あなたは?どこからきたの?はじめて?そういった、絶対に誰にでもするであろう会話だけでも、 自分がここにいることを認められた気がしてホッとした。

見に行きたいな、って思いでメモしておく。話したひとたち。

A Tale of Two Postmortems: A Human Factors View Wednesday, 9:10 am–9:55 am Tanner Lund, Microsoft

Availability—Thinking beyond 9s | USENIX

Jason Wik, Jayan Kuttagupthan, and Shubham Patil, VMware

The MTTR Chronicles: Evolution of SRE Self Service Operations Platform | USENIX

VMwareの彼らとはセッション同じ時間じゃんw という話をした。聴けないのが残念だ。

How to Ruin an SRE-Dev Relationship in 3 Simple Steps Raushaniya Maksudova, Google

Our Practices of Delegating Ownership in Microservices World Daisuke Fujita, Mercari, Inc.

Error Budgets in Banks—Challenges & Way Forward Chaitanya Gorrepati and Alex Titlynanov

Lightning Talks | USENIX

Googleの彼女は、私たちが大きなカンファレンスで、あるいは英語(海外)での発表がはじめてだという話をすると、「Sugoidesu」と言ってのけて、Sugoidesuはあなただよなぁという話をした。東京には何度か来ているようだ。

ちなみに Lightning Talks は事前にスライド提出が義務付けられており、1枚15秒 * 20枚スライドで、自動再生されるらしい。ペースが調整できないのはそれはまた別のテクニックが要求されて厳しい。時間を厳密に守るためとはいえ。

強く思ったことは、強くなってまたここに(厳密に同じSRECon Asiaという意味ではなく、海外カンファレンスという意味で)帰ってきたいということだ。

英語はやっぱり全然聞き取れないし、会話をちゃんとできたとは全然言えないが、それでも自分が話したことを汲み取ってくれて、同じ空間を同じ立場で共有できたことを、嬉しく思った。 怠惰な自分の大きなスタート地点だな、と思った。参加して本当に良かった。

英語できるようになりたいなあなんてことを言ってる場合じゃないや。

とまだはじまってすらないが、1日目の朝食をホテルで取りながらこの文章を書いている。 終わったあとはまた別の感想を持つのだろうか。それはまたあとで書こう。

Speaker Reception のあとはメルカリのみなさんにご一緒させていただきお世話になりました。 これもまたいい経験だった。

さぁ、あとちょっと頑張ろう。

etcd clusterをVagrantで立ち上げる

はじめに

立ち上げた。

github.com

vagrant upしてサービス起動すればいいようにはなっている。

coreosにしたかったがboxが見つからなかったのでubuntuにした。

雑記

  • systemdの設定ファイル内で環境変数を使うために EnvironmentFile でファイル指定した。IPが違うのでそれはinit処理でいれておくことで対処した。
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target

[Service]
User=etcd
Type=notify
Environment=ETCD_DATA_DIR=/var/lib/etcd
Environment=ETCD_NAME=%m
EnvironmentFile=/etc/default/etcd
ExecStart=/usr/local/bin/etcd --name ${ETCD_NAME} --data-dir /var/lib/etcd --initial-advertise-peer-urls http://${ETCD_HOST_IP}:2380 --listen-peer-urls http://${ETCD_HOST_IP}:2380 --listen-client-urls http://${ETCD_HOST_IP}:2379,http://127.0.0.1:2379 --advertise-client-urls http://${ETCD_HOST_IP}:2379 --initial-cluster-token etcd-cluster-1 --initial-cluster etcd0=http://192.168.33.200:2380,etcd1=http://192.168.33.201:2380,etcd2=http://192.168.33.202:2380 --initial-cluster-state new
Restart=always
RestartSec=10s
LimitNOFILE=40000

[Install]
WantedBy=multi-user.target
  • systemdのファイル内で改行ってどうするの?ExecStartを改行したい。。。
  • 最初の1台目をスタートするとき、他のホストが立ち上がっていない場合起動に失敗するため、init処理ではサービス起動を行わず、3台立ち上がったあとにコマンドでスタートするようにしたが、なんとかならないのか。
  • ubuntu、ドキュメントにそって手動でインストールしたけどaptで入ることにあとで気づいた、がまぁsystemdファイルいじりたかったしいいか。。。
  • ちゃんと1台でvalue setしたりremoveしたら他でも反映された。すごい。

今後

  • Raftの概要と動きを学んで動かす。このへんか。

raft.github.io

  • なんらかの言語のクライアントライブラリがあればそれ使って動かしてみる。実際に使いたくなるときに使えるように。

  • 2台が落ちたときの復旧方法・動作を確認しておく。1台になるとunhealthyで書き込めなくなるはず。

  • 3台落ちたときの復旧方法・動作を確認しておく。1台だけあげようとすると他がいないのであがらないような気も?(timeout時間内に他もあがろうとすると仲間をみつけてあがるような挙動にみえる。これもraftの仕様を学べばわかるか)
  • データのバックアップ、リストア方法について。データディレクトリをコピってそのままそこにおけばそれだけで復元するのか、どうなのか。
  • etcdctlでできること見ておく