ぽよメモ

レガシーシステム考古学専攻

リモート研修についての雑感

はじめに

 社名は明かしません。知っている人も、わざと明かすような言及はしないで貰えると助かります。なお色々ぼかしたり混ぜたりして書いています。
 

これは何

f:id:pudding_info:20200504235658p:plain
テレワークのイラスト

 入社から一度も出勤せず、全てリモートで研修を受けて一ヶ月経ったので、今時点での自分の感想を言語化して残しておきたいと考えました。もしかしたら今後意見が変わるかも知れないし、変わらないかも知れないヤツです。研修を受けた側の本音はまだ貴重な方だと思うので、リモート研修やってる各社の人事に届け。

 ちなみに、これはエンジニア向けの研修ではなく、それ以外も含めた共通の研修を1ヶ月程度受けたことについての感想です。相当に恵まれた環境であり、先輩社員の方々の努力を節々から感じています。他の会社のリモート研修は知りません。全てを一般化しないで下さい。

著者の状況

  • 2020年の新卒
  • (ソフトウェア)エンジニア職での採用
  • 通勤には電車を使って1時間程度かかる
  • 家に仕事をする部屋がある
  • 元から引きこもりオタク

正直な感想

 これを言うと不謹慎っぽいんですがフルリモートでの研修になって本当に良かったです。以下良かったところです。

  • 通勤電車に乗らなくて良い
    • 感染リスクが〜とかもありますが、純粋に移動時間が減って嬉しい。余裕をもって家事が出来る。朝急がなくて良い。
  • 昼休憩にちゃんと休憩できる
    • やたらコミュ力を発揮したりしなくて良いので楽
  • 別に困っていない
    • そもそもリモートでやるためのコンテンツが用意されているので当たり前だが、別にリモートで困ったと思ったことがない
    • この内容で十分だと思ったし、むしろこれ以上色々やっても意味あるか怪しい

「通勤したい」と思ったことは今のところ一度も無いです。別に顔はリモートでも見ることができ、会話もでき、ある程度仲良くなることも可能でした。業務が終わった後に軽く雑談したり、リモート飲み会をやったりもしています。それ以上の関係性を仕事には特に求めていません*1

 研修のコンテンツに不足感もそれほど感じていません*2。これ以上何かやる必要有る?という気持ちです。冗長なことを続けられても、どんどん失望するだけだと思います。

 一方で、通勤したいサイドの言い分も十分理解出来ました。例えば「家で仕事することを想定していなかったので、まともな椅子や机がなく身体がしんどい」とか、「家のWiFiが不安定/遅く、まともにWeb会議できない」などです。家の設備がそれなりに整っているオタク以外にリモートワークはなかなか厳しいというのは確かにと感じました。「(リアルで)顔が見たい」「(リアルで)会話したい」「(リアルで)一緒に遊びに行きたい」などはあまり賛同できませんでした。別にリモートでよくない?(真顔)

リモート研修で微妙だなと思ったこと

初日出社するかどうかを新卒に委ねる

 そもそも初めての事態だったので仕方ないのですが、「こーーれは微妙なライン」という状況で新卒に「初日来ますか?リモートにしますか?」って聞いたら99%の新卒は出社しますって言うと思います。そこで「や、感染怖いんでリモートにします」って言うヤツはたぶん人生2周目です。

 この引きこもりの僕ですら「一回くらいは出社しておきたいな」と思ったくらいなので、普通の人は出社すると思います。実質一択の質問で責任を新卒に持たせるのはどうかと思います*3

昼飯食べながらの雑談会

f:id:pudding_info:20200504235750p:plain
オンライン飲み会のイラスト

  • 昼飯を用意する時間が十分でない
  • そもそも食べながらとか喋りにくい

などの理由で微妙でした。リアルで会っていれば、食べに行くまでや食べ物を用意する時間などにも会話が発生するかも知れませんが、リモートでは全員手元に食事を用意している段階ではいスタート!なのでコミュニケーションがとりづらいです。昼飯じゃなくておやつの時間とかにしませんか?

成果の見えない(見えにくい)自学自習の時間

 単純にモチベ湧かないです。抽象的な目標と手段を与えられてこれやっといてねと言われても、成果を測定しづらく、またそれがどう役に立つのかイマイチわからないのでやる気になりませんでした。計算ドリルでもやってた方がマシです。

リモート研修で良かったこと

研修の内容自体については言及しませんが、まぁ研修ってこんなもんだよなという気持ちでした。まぁまぁ楽しかったので良かったのでは?それ以上特に言うことはないです。それ以外についてだけ述べます。

服装の自由

 僕はほぼずっと下半身はスウェットで過ごしていました。上半身も単なるパーカーとか、せいぜいシャツをちゃんと着る程度で、寝間着に見えないようにだけ気を遣っていました。その程度の配慮で十分じゃないですか?スーツ着てリモートやってるとこもあるらしく、ウケると言う他ないです*4

同期との雑談の時間

 ガス抜きという意味でも、交流を深めるという意味でも、こういう時間は貴重でした。やっぱりリアルでの細かいコミュニケーションの発生が無い分、こういう時間を無理にでも取って補うしか無いと思います。ちなみに同期の名前はあんまり覚えられませんでした。

社員との雑談の時間

 同期としか話していないと今後の不安が蓄積するばかりなので、先輩社員の方々と喋って解消するというのも大事だなと感じました。人事だけでなく、あらゆる部署の人と一回は話しておけると雰囲気を掴めて良いのではないでしょうか。ちなみに先輩社員の名前はあんまり覚えられませんでした。

来年以降に向けて

 もしかしたら来年以降、自分が研修する側に回る可能性もあるのでいくつか気付いたことを残しておきます。

出社可能になってもリモートの選択肢を残す

 受けていて思ったのは「わざわざ座学を受けるためだけに出社する必要ある??」です。ここで「いやでも同期とのコミュニケーションが〜」とか言うなら座学とは別にコミュニケーション取る日を用意して下さい。要するに、リモートで可能なもののために出社を強要して欲しくないということです。

 出社が難しくなる理由は何も感染症だけではありません。電車が止まるかも知れないし、体調があまり良くないかもしれないし、朝起きれないかも知れない。必要なときなら仕方ないですが、リモートで問題ないものならリモートでいいじゃんというのが僕の主張です。同時に、実施した内容を常に録画しておくことも重要だと思います。後から次の年の反省に活かすことも出来るし、病欠した人のフォローにも使えるからです。

座学におけるフィードバック

 リアルで喋っていれば、フィードバックは視線や身振りからでも得られますが、リモートにこれを期待するのは難しいです。実際、フィードバックが無くて「わかりましたか?…………あー……うーん……………先に進めます」みたいな状況が頻繁に発生しています。これには2つ原因があると考えています。

  1. そもそもフィードバックの方法が用意されていない(or 適切な手段でない)
  2. 喋っている側がフィードバックの確認方法を知らない

 予め研修中に使用するリアクションの手段を決めておくべきでしょう。更に言うとそれは身振り手振りなどではなく、Web上または使用しているツール上で行うことができ、感情を表現できる方法で行うべきだと考えています。前述したように回線の問題で自分のビデオをオンにしないほうが快適に動く人も居るため、身振り手振りは適した方法ではありません。また、👍のみのようなリアクションは、適切なフィードバックをするのに十分でないため、文章orもっと多様なリアクションが使えると良いと思います。

 フィードバックを確認する側も、予めここにこうリアクションしてくれと伝えておくことで、気まずい沈黙を避けることが出来ると思います。これを研修を実施する側の人全員で共有できているとなお良いと思います。

受講者が手を動かして何か出来るコンテンツの用意

 完全な座学なら難しいですが、少しでも受講者の能動的な行動を要求する内容があると自然と話を聞きます。内容的には何でもよく、特定のWebサイトを開く程度で十分かも知れません。その上で何か出来るともっと良いと思います。

 ただ、死ぬほど興味ない内容でひたすらインタラクションを要求されると、辞めたい度が急上昇するのでさじ加減は必要です。

研修の目的と妥当性の提示

 何のためにやるのかよく分からないものをリアルで延々受けさせられたら発狂して辞表たたきつけると思いますが、リモートだとただただ「無視」できます。それで良いなら構いませんが。研修の各内容について

  1. 何を目的として
  2. どのような方法で
  3. なぜその方法が妥当であると判断したか

の3点が分かっているだけで不満は相当減ると感じました。内容にそこまでのめり込めなくても、必要性を理解出来るからです。1、2は問題なくても3に問題がある場合もあります。目的に対して手法がマッチしていなければ(マッチしていないと研修を受ける側が感じれば)、やる意味が無くなってしまうからです。逆に言うと、これが説明できない研修なんて必要ないので辞めれば良いと思います*5

 今年はコンテンツをしっかり練る時間もなく急ごしらえかもしれませんが、来年以降リモートが必要になったときに同じようなことを続けるのは愚策かと思います。特に3について、実施する側はよく考えるべきだと思います*6

最後に

 研修という言葉に良いイメージがなく、ビビりながら受けましたが、それなりに楽しかったので良かったです*7。誰も直面したことが無かった事態においても柔軟に対応し、尽力頂いた社員の方々には大変感謝しています。一方、まだまだリモート研修の可能性はこれからだなと思っているので、もっとこの文化が成熟していけばいいなと感じています。

*1:職場恋愛を夢想する人には最悪な状況かも知れません

*2:人事がどう思ってるかは知らないです。あくまで僕自身の感想です。

*3:結局弊社では初日から全員リモートになりました

*4:顧客の前に出るとか、その様子が全国に公開されるとかなら会社のイメージのためにスーツを要求するのは理解出来ます。

*5:リモートだろうがそうでなかろうが関係無くです

*6:例えばAIを使った新規事業を考案!とかです。何の意味があんの?あんたらAI欠片も知らんのでしょ

*7:別にまだ研修は終わっていません。この一ヶ月やってみてという感想です。

大学院でやってよかったこと

これは何

 ついに大学院情報工学専攻(修士)を修了してしまうため,何かポエムが書きたくなりました.ネットには研究室への怨嗟が溢れていて*1,大学院が楽しいとか(当たり前の人にとっては当たり前過ぎて)あんまり書いてないので,じゃあ自分で書いてみようという感じです. 実験系(ウェット)な人たちには「は?」と言われることが多々ありそうです.気をつけてお読みください.

 また,僕自身は大学院から専攻を変えたため,あまり一般的な大学院生とは言いがたい可能性があります.専攻を変えた経緯は以下の過去記事を参照のこと.

poyo.hatenablog.jp

完走した感想

f:id:pudding_info:20200319151803p:plain
ゴールした人のイラスト

 大学院の2年間はあまりにも早く終わってしまい,あまり実感がありませんが,おおよそ楽しく充実した時間でした.「大学院進学やめとけばよかった」と考えたことは,おそらく一度も無いと思います.残念ながら(今のところ)目に見える実績が無く,研究活動として見たときには大失敗だった可能性もありますが,様々な面で成長を感じた2年間でした.特に修士論文は自分でテーマを決め執筆まで行ったことで,大きな自信となりました.就活も特に危なげなく終わり,4月からは東京で働きます.頑張っていくのでよろしくお願いします.

 特にWeb系の一部では「大学院に行くよりさっさと働いた方がいい」という風潮があるように感じますが,コンピュータサイエンス修士を修めることにはそれなりの意義があると思います.修士の価値は自分で決める,そういうことだと考えています.自分が修士に価値を感じることが出来たのは,ひとえに研究室のメンバー及び先生方のおかげです.ありがとうございました.研究室の今後のますますの発展を祈っています.

大学院の良かったところ

 結局,どういう研究室に入るかによってこの辺りは大きく変わってくると思います.そういう意味では,「大学院の」というよりも「研究室の」良かったところですね.

  • (卒業できれば)修士号が手に入る
  • 研究室という空間を2年間フルに使える
  • 研究について技術的なものからメンタル的なところまで相談できる相手が居る
  • レベルが近いまたは上の相手が多い
  • 純粋な興味ドリブンで好きなだけやっていい

興味があるからというだけの理由でこれだけ時間を好きに使って没頭できる機会はそう無いと思います.4回生ではあまりにも時間が短すぎ,できることが限られてしまう上,どうしても先生や先輩の言うことをはいはい聞くだけの存在になりがちです.自分主導で研究を進めることは,基本的には修士以降で初めて出来るような印象が強いです.とりあえずで進んできて良い場所では無いと思いますが,ちゃんと覚悟をしてきている人にとって少なくとも悪い場所にはなり得ないはずです.皆様,進学の方,いかがでしょうか.

やって良かったこと

 この2年間,授業・自身の研究を除いて,やってみて良かったことを6つ取り上げたいと思います.そんなに奇抜なことはしていません.また,就活についても特に言及していません.分野によってあまりにも大きな差があり,参考にならないと考えたためです.

1. とにかく物を捨てる

f:id:pudding_info:20200322174421p:plain
故人のコレクションの処分に困る人のイラスト

 この作業で僕の大学院生活はスタートしました.研究室というのは,よっぽど新興のところで無い限り,最低でも数年から数十年という年月が積もり積もった場所です.しかも大抵研究者は整理整頓が苦手です*2.そのため,学生の生活空間がどうでもいいもので溢れていることが多いです.先生の了解を得つつ,どんどん捨てていきました.

 2~3年しかいない環境を整備するモチベーションが湧かない人の気持ちも理解出来ますが,綺麗にすると単純に周りから感謝されて気分が良いのでお得です.

2. とにかく掃除する

f:id:pudding_info:20200322174752p:plain
清掃業者のイラスト

  • 明確に掃除する時間が無い
  • ゴミは限界まで溜める
  • 水回りを誰も掃除したことがなく,臭い
  • 掃除する気がない

など,特に男ばかりの研究室ではありがちな気がしています.率先してゴミを捨て,部屋を掃除しました. 他に,複雑なゴミの分別ルールについての周知や,なくなってきた消耗品の購入リクエストなども行っていました.これも単純に周りから感謝されて気分が良いのでお得です.

 特に部屋の匂いはため込んだゴミの他に水回りなどが原因のことがあり,キッチンハイターで三角コーナーと排水溝を漂白・殺菌するだけで多少マシになります.

3. 細かい不満を設備投資で潰す

f:id:pudding_info:20200319133826p:plain
貢ぐ人のイラスト

 買って良かったものリストです.研究室で使って良かった物は以下の通りです.

  • 短焦点プロジェクタ
    • 10万円くらいだった
    • 上から吊らなくても十分有用
    • 空間を広く使えるようになる他,常にスクリーンの目の前に置いておくことでカジュアルに使えるように
  • メタルラック
    • サーバにしているマシンの置き場
    • 高さを自由に変えられるので収納したいものを最適な形で仕舞える
  • 多少マシなモニタ
    • 43インチ4Kや,フルHDだがUSB-C1本で出力と給電ができるもの*3など
  • 椅子
    • 古い物を捨てて新しいものにリプレース
    • 座り心地が悪い/キャスターの滑りが悪いなどは地味にストレスなため
  • 荷物置き用バスケット*4
    • 明確に各自のカバンを置く場所が出来ると,なんとなく部屋が片付いて見える
  • スタイルハンガー*5
    • コートなどを椅子にかけている研究室におすすめ
    • いつの間にかずり落ちて床に…とかならなくて良い感じ
  • 大判のウェットティッシュ
    • 机を拭いたりするのに雑巾はどんどん汚れてあまり衛生的ではない
    • 使い捨てることが出来るウェットティッシュは掃除のハードルを下げる
  • キッチンペーパー
    • 食器用布巾は使い込まないと水を吸わない
    • 研究室では洗濯もしづらいので不衛生……
    • よく水を吸ってくれて使い捨てれるので便利

プロジェクタや4Kモニタ以外は比較的安価なものを並べたつもりです.ちなみに個人で買って良かったものは以下です.

  • iPad Pro + Apple Pencil
    • 圧倒的に捗る
    • これ一台で論文を読んで校正もできる
    • 論文を紙で読む時代は終わった
  • Air Pods
    • 研究室ではカジュアルに研究の話を振られたり,来客があったりするため,周囲の音が聞こえるイヤホンが便利だった
    • 最初はAmbie Wirelessを使っていたが少し耳が痛いのが気になり売却
  • USB-Cの給電アダプタ
    • 移動する場所全てに置いておいた
    • 充電器の持ち運びを減らせるのは楽
  • 大乱闘スマッシュブラザーズSPECIAL
    • ストレス解消や学生の交流に大変良い
    • ちなみに負けるとストレスが溜まるので勝つことがストレス解消の秘訣*6

金は正義です.

4. コミュニケーションのハードルを下げる

f:id:pudding_info:20200322172057p:plain
会話をするカラスのイラスト

 そもそも弊研究室ではSlackを導入しており,メールなどよりはハードルが低かったです.未だにメーリングリストというところも多いようですが,正直メールは今の学生に馴染まないと思います.特に全体連絡に対して返事するべきかどうかとか,後から会話に参加する人がこれまでのやりとりを見れないとか……返事せずともリアクションで態度を表明でき,話題ごとに話す場所を分割できるSlackやDiscord,Microsoft Teamsなどの導入がおすすめです.そういったツールが導入されていても,DMやプライベートチャンネルがメインとなってしまうと効果は半減です.僕は積極的に研究のネタになりそうな内容や,アドバイス・質問等をSlackの公開チャンネルに投げることで,情報をオープンにし共有する文化の醸成を目指しました.完全に上手くいったとは言いがたいですが,まぁやらないよりは良かったかなと思っています.

 オフラインでのコミュニケーションでも,後輩に積極的に話しかけたり,先生とカジュアルに話すところを周囲に見せたりなど,より話しかけやすい雰囲気を作ることを意識していました.積極的に各自が今の状況を(フォーマルな形ではなくカジュアルに)共有する雰囲気を作ることで,自分だけでなく周囲の人のガス抜きもできていたのではないかと考えています.楽しかったとは言っても研究がつらいことは多数あったため,気軽に愚痴を言えたり,どうするべきか相談できるというのは重要だったと感じました.

5. 研究相談に積極的に応じる

f:id:pudding_info:20200322174110p:plain
カウンセリングを受ける男性のイラスト

 まず前提として弊ラボは学生数に対して先生が少なく,かつ教授が様々な事情で多忙であり,何もかもを教授に見てもらうという体制を取ることが難しいという実情がありました.そのため,以前から論文は一旦同期や先輩の校正を通してから先生に見せるというスキームがありました*7.研究の方針についても全て教授にお伺いを立てるのではなく,先輩と相談するなど学生間で方針を決め,ある程度進めながら詰まったら教授と話し合うといった進め方をしていました.とはいえ,自分のものでない研究に付き合う義務は特にないため,相談に乗る行為や校正は完全にボランティアです.今年はM2 7人+B4 4人という大人数が修論/卒論を執筆する関係上,容易にパンクすることが予想されたため,さっさと論文を書いて校正に回ることを決めていました.

 結果として,研究方針の相談までは深く関われませんでしたが,考察に対する批評や,論文自体の書き方など多数の面で後輩/同期の執筆に関わりました.いくら専攻する分野(ソフトウェア工学)が同じとは言え各自の研究内容は大きく違うため,研究の内容理解からしっかりとする必要があり,様々な発見がありました.単純に複数本の論文を書いたようなものなので(?),お得です.一度で二度,三度美味しいみたいな感じです.ただし,余裕が無いと死んでしまうので計画的に早く終わらせましょう!!!

 加えてドクターの先輩の研究相談に関わったりしたこともありました*8.これもドクターまで行く人が

  • 日頃からどれくらい研究しているのか
  • どのように見通しを立てて研究をしているのか
  • うまく行っていないときにどうメンタルを保っているのか*9

など,身近で見て感じることが出来たのは大きかったです.自分にD進は向いていないなと分かったのも良かったですね.

6. 負債の返却

f:id:pudding_info:20200322173813p:plain
便利屋・なんでも屋のイラスト

 果たしてこれは返却できたのか新しい負債を増やしたのかまだ判断できませんが,とにかくこういうことをやっていました.

poyo.hatenablog.jp

中でも,Wikiesa.ioへ移行できたのが最も大きな進歩だったと思っています.それまでほとんど誰も書いてくれなかったWiki1年間で数百記事以上に成長し,大きく貢献できたと感じています.もちろん他のメンバーの執筆を促進するために自分もたくさん書いたという面もあり,そのモチベーションは以下の記事にまとめています.

poyo.hatenablog.jp

これから

f:id:pudding_info:20200322175625p:plain
運動会の徒競走でスターターピストルを鳴らす先生と、スタートラインに並ぶ生徒たちのイラスト

 さて,冒頭にも書いた通り,僕はこれから社会人として労働をやっていくことになります.修士卒という意味では,多くの人が自分と同じスタートラインに立っていると言えるかと思います.普通に研究したあの子も,死ぬほど研究して賞も取りまくった彼も,2年間遊んでいて卒論から進歩があんまり無かったあいつも,僕も,みんな同じ修士号です.単なる修士卒として埋没しないよう,自身の強みをさらに伸ばし,弱点を補っていきます.よろしくお願いします.


 

*1:主観です

*2:これも主観ですが今のところほとんどの人には当てはまっていると感じています

*3:DELL P2419HC.2万円前半で安いのでオススメ

*4:カフェとかの足下にあるようなやつ www.askul.co.jp

*5:こういうの www.askul.co.jp

*6:別に強くないので負けまくった

*7:周囲の話を聞いていると,意外と多くのラボではこれをやっていないっぽい?誤字脱字の指摘だけでもやれば良いのにと思います

*8:単に「いやそれは無理でしょ〜〜〜」ばっかり言ってた気はしますが……

*9:だいたいスマブラするかボドゲやるか酒を飲むかアニメ見るかでした

Moleculeを使う際にTestinfraからAnsible Factsを参照する

概要

 Ansible公式のテストフレームワークであるMoleculeは,Ansibleによる構築の後に,デフォルトではTestinfraによるテストを実行します. Testinfraにはhost.ansible.get_variables()というAPIがあり,これを介してAnsibleの変数を取得できるように見えます.が,実際にはinventoryやhost_vars,group_varsに記載されているもの以外の値を取ることができません.

 ここでは,Testinfraによるテストコードから,gather_factsによって収集される変数やRoleのdefaultsやvars内で定義されている変数を参照するハックを紹介します.ただし,これは完全にAnsibleの挙動と同じであるとは言えないかもしれないという点に注意してください.

環境

  • macOS 10.15.2 Catalina
  • Python 3.7.5
  • Ansible 2.9.2
  • Molecule 2.22
  • Testinfra 3.4.0

ここでは単体のRoleのテストのみを取り扱います.Roleのディレクトリの構造は以下の通りです.

$ tree -L 2 /path/to/role
/path/to/role
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── README.md
├── defaults
│   └── main.yml
├── meta
│   └── main.yml
├── molecule
│   └── default
├── tasks
│   └── main.yml
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

Testinfraにおける問題点

 TestinfraはAnsibleと完全に統合されているわけではないため,構築の実行中に使用される変数を取得することができません.これにより何が起こるかというと,複数のプラットフォームに跨ったテストを書くときにifを大量に並べることになります.

テストコード中では以下のようにOSの情報を取得できます*1

def test_hoge(host):
    dist = host.system_info.distribution
    if dist == 'debian':
        # some action
    elif dist == 'ubuntu':
        # some action
    elif dist == 'darwin':
        # some action
    elif dist == 'centos':
        # some action

正直めちゃくちゃ面倒臭い……インストールするパッケージのバージョンチェックなども,このままではバージョンをハードコードすることになり,Role内の値を変更するときにテストコード内も全て変更したりする必要が出てきます.

 さて,ここで救世主のようにみえるTestinfraのAPIHost.ansible.get_variables()の実際の実装をみてみましょう.

https://github.com/philpep/testinfra/blob/3.4.0/testinfra/utils/ansible_runner.py#L172-L189

ansible-inventoryコマンドを叩いてインベントリの情報を収集している以外は過去のバージョンとの互換性を保つためのコードのようです.つまり,get_variables()とは言いつつも,実際にはインベントリに記述されている情報しか取っていません

既存のアプローチ

いくつかのIssueで議論されています.

github.com

github.com

これらの中でも直接YAMLとして読み込んだり,include_varssetupを使用した方法が紹介されていますが,これらは誤った用法によりうまく変数を解釈できていません.

  • YAMLとして読み取る
    • これは論外
  • include_varsを使う
    • 一見うまく動作するように思えるが,これも実際には変数の解釈をしない
    • 例) hoge: "{{ ansible_python_interpreter }}"のようなYAMLをロードしても{"hoge": "{{ ansible_python_interpreter }}"}が返ってくるだけ
  • include_vars + setup + ansible.template.Templar

Testinfraから変数を参照する

 ようやく本題です.変数を取得する方法は雑にいうとAnsibleのinclude_varssetupモジュールを使い,自分でファイル読み込みの優先順位を定義して順に読み取っていきます.読み込んだ変数を優先度順に ansible.template.Templar で解決していきます.
 Testinfraが内部で採用しているテストフレームワークであるpytestの作法に則って,fixtureとして実装します.

setup

まず,setupモジュールを使用してAnsibleのFactsを収集します.

import pytest

@pytest.fixture(scope='module')
def ansible_facts(host):
    return host.ansible("setup", "gather_subset=min")["ansible_facts"]

これはそれなりに重いので,

  1. gather_subsetfilterなどの引数を使って必要な変数のみ取得*2
  2. fixtureのスコープをmoduleにすることで,複数回の取得を防ぐ

等で多少早くなります(たぶん).

 このansible_factsというfixtureは単にいつも使っているFacts*3がそのまま返ってきます.

include_vars

 include_varsを使って各変数定義ファイルを読んでいきます.

from ansible.template import Templar
from ansible.parsing.dataloader import DataLoader

@pytest.fixture(scope='module')
def ansible_vars(host, ansible_facts):
    # リストの後にいくほど優先度が高い
    # host.system_infoを利用すれば,OSごとに読み取るvarsを変更している場合にも対応可能
    var_files = [
        "../../defaults/main.yml",
        host.ansible.get_variables(),
        "../../vars/main.yml",
    ]
    templar = Templar(loader=DataLoader())
    # 優先度順に読んでいく
    all_vars = {}
    all_vars.update(ansible_facts)
    for f in var_files:
        if isinstance(f, str):
            var_from_f = host.ansible(
                "include_vars", f"file={f}")["ansible_facts"]
        else:
            var_from_f = f
        # 変数の出現順に埋め込みを解決
        for key, val in var_from_f.items():
            templar.available_variables = all_vars
            all_vars[key] = templar.template(val)
    return all_vars

ディクショナリの順序が保証されているPython 3.6以降でしかうまく動作しない気はしています.

 templar.template()は引数にディクショナリも取ることができるのですが,その際,解決すべき変数がそのディクショナリ内に含まれている場合にうまく動作しません. 例えば以下のようなファイルを読み込み,そのまま渡すとうまく解決することができずにエラーになります.

---
hoge: "hoge"
hogefuga: "{{ hoge }}fuga"

そのため,まずはhogeという変数を解決してTemplarの持つ変数のディクショナリを更新し,次にhogefugaを解決するようにしました.

 

テストで使う

 実際のテストコードへの実装は非常に容易です.例えばインストールされているべきパッケージの一覧をinstalled_packagesとして定義しているなら,以下のようにします.

def test_hoge(host, ansible_vars):
    expected_packages = ansible_vars.get("installed_packages")
    for expected_pkg in expected_packages:
        actual_pkg = host.package(expected_pkg)
        assert actual_pkg.is_installed

メリット

  • 煩わしいOSの判別を一部不要にできる可能性がある
  • Role側がデフォルト値を変えただけなどの場合に,テストを手動で修正する必要が無くなる

デメリット

  • そもそもRoleのデフォルト値が間違っていたりするとテストの意味がなくなる
  • setupが重いため,内容次第ではテストが遅くなる可能性がある
  • 完全にansible-playbookコマンドによる実行と同等とはいえず,また,内部のAPIを直接参照しているため,今後も互換性が担保されるかわからない

現時点での制限

  • Role中のタスクでset_factしたりregisterしている変数は参照できない
  • 変数の優先順位を人が解決する必要がある

などなど.現時点での実装があまり賢いとは思っていないので,もしより良い方法を知っている人がおられれば教えていただけると幸いです.