ワクチンの副反応でダウン

3時に寝て6時に起きた。1時までインフラ作業して帰ってきて、ワクチン接種のせいか、あまりうまく眠れなかった。朝に熱を測ったら37.2℃だったのでぎりぎり平熱だった。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日の議題は次の通り。徐々に熱が出てきてしんどかったせいか、情報共有の報告程度で終えた。

  • 今期の予算策定
  • 次のお仕事を探す段取りの見通し
    • 現プロジェクトの区切りが5月末にあることから次の契約更新のタイミング (7月末) で契約終了する可能性がある
  • 延期したワーケーション の再計画
    • 6月か7月ぐらいがよさそう

ワクチンの副反応

朝オフィスで測ったときは37.2℃でこのぐらいなら普通にお仕事できるかなと始めたんだけど、段々体温が上がってきて10時ぐらいには37.9℃になって、しんどいから一旦家に帰って横になって、デイリースクラムだけ家から参加した。その後もずっと寝込んでた。何回か起きて熱を測ったら最高38.5℃まで上がった。厚労省のサイトによると、3回目の副反応は2回目と同等とある。私は2回目の副反応はここまでひどくなかったのでこの差はファイザーとモデルナの違いなのかもしれない。熱が出て寝込むとか、数年に1回ぐらいの頻度でしか起きない。病気になったらこのぐらいしんどいんだなという、しんどさを思い出すのにちょうどよかったのかもしれない。

コロナワクチン3回目

22時に寝て3時に起きた6時に起きた。季節の変わり目のせいか、いつも眠い。

ワクチン3回目接種

2回目は昨年の9月27日 に接種した。6ヶ月以上経たないといけないので3月27日以降に接種資格を得て、実際に接種券が届いたのが4月7日だった。神戸市は初回のときにまごまごしたので他の自治体よりも遅れている。これまでファイザーを2回接種したので今回はモデルナを受けてみることにした。モデルナを扱っていてネット予約できるもっとも近くの診療所を予約した。オフィスから自転車で15分ぐらいのところ。16:30の予約なのに16時過ぎぐらいに行ったら普通に受け付けしてくれてすぐに接種もできた。16:05に接種終えて16:20まで待機してオフィスに戻ってきて普通にお仕事してた。その1時間半後に熱を測ったら37.0℃だった。その後もやや熱っぽいけど、平気とは言えば平気。

インフラ移行作業

昨日の続き。フロントエンドのテスト環境が壊れる可能性があるため、他メンバーが使っていない夜に移行作業を行う。POの人たちがQA検証を19-21時ぐらいにやっていることが多いので21時以降に作業すると連絡しておいた。なかなか大変だった。最悪の場合、数時間テスト環境を使えませんと伝えていたものの、その通りで4時間ぐらい検証作業をしていた。cloudfront の distribution 設定を CloudFrontWebDistribution から Distribution へ移行して、新しいやり方であるマネージドポリシーを使うようにした。この設定が意図した振る舞いにならなくて検証作業に時間を割いた。

cloudfront 経由で web api を呼び出すルートがあってキャッシュを無効にしたいのだが、無効にしたキャッシュポリシー (ttl をゼロにする) を作るとヘッダーの設定ができない。次のようなエラーになる。

The parameter HeaderBehavior is invalid for policy with caching disabled.

(cloudfront): Cache Policy cannot forward Authorization header. #13441 によると、maxTTL を1秒にして Authorization ヘッダーをオリジンに転送するようには設定できる。キャッシュメソッドは GET と HEAD なので実運用上は問題ないとは思うが、この回避策がないかどうかを調べて検証していた。結果としてはなかった。Configuring CloudFront to forward the Authorization header には Authorization ヘッダーを転送する方法は次の2通りとある。

  1. cache key に含める
  2. Managed-AllViewer という origin request policy をすべての viewer requests に含める

最終的には1番目のやり方で対応はしたが、2番目のオリジンリクエストポリシーを設定する方法も検証してみた。オリジンリクエストポリシーを単体で設定することはできなくて、キャッシュポリシーも一緒に設定しないといけないことからキャッシュポリシーの設定の影響を受けて意図したように Authorization ヘッダーの転送はできなかった。

  • cache policy: Managed-CachingDisabled
  • origin request policy: Managed-AllViewer

cdk の cloudfront の distribution 設定の移行

0時に寝て5時過ぎに起きた。

フロントエンドのインフラ作業の続き

昨日、cloudfront の distribution 設定のビヘイビアのキャッシュ設定が誤っていることに気付いたので cdk のコードを修正していく。Amazon CloudFront キャッシュポリシーとオリジンリクエストポリシーを発表 によると、2020年ぐらいに distribution ごとに個別設定していたのをマネージドポリシーというリソースを参照することで一元管理できるようになったらしい。cdk のコードで言えば、次の issue で対応されているが、これらの機能は aws_cloudfront.Distribution のみに追加されている。従来の CloudFrontWebDistribution では使えないので distribution 設定そのものを新しいやり方に移行する必要がある。

基本的には同じ設定を行うので新しいクラスのメンバーや構造にあわせて移行するだけなので難しくはないけれど、1つずつ設定内容の移行方法を確認していかないといけないから手間暇はかかる。cdk のドキュメントをみると、型に対してどういった設定をすればよいかが書いてあって、あとはメソッドの定義などもみながら自分たちの設定に近いものを選択していくといった作業になる。難しくはないけど時間はかかる。半日ほどやって移行のための pr を作成した。

cloudfront のキャッシュ設定

1時に寝て5時に起きた。

フロントエンドのインフラ作業

これまでバックエンドのインフラ作業をしてきたが、そちらの移行作業は完了した。フロントエンドのインフラも積み残しが多々あるのでこの機にリファクタリングする。差分が出ないことを確認して cf のテンプレートのドリフト結果を解消したものをデプロイしたらフロントエンドが壊れた。具体的には xhr の web api 呼び出しに対して認可エラーが返るようになった。数時間ほどの調査の結果、cloudfront の distribution 設定のビヘイビアのキャッシュ設定で web api 呼び出しのときに authorization ヘッダーを転送するための設定が漏れていることがわかった。cdk のコードにはそんな設定がどこにもなく差分も表示されないことから、フロントエンドの cdk コードも全く保守されていないことがわかった。デプロイするときに前回のデプロイが半年前だったのでなんか悪い予感はしたんよね。インフラ担当者の怠慢が度を越し過ぎてもう何が起きても私は驚かないけど。設定に漏れがある前提でフロントエンドのインフラをリファクタリングしていかないといけない。

cdk/cf の Stack とライフサイクル

0時に寝て5時に起きた。

インフラ変更の本番作業

先週やっていた様々なインフラ構築の改善を本番環境に適用する。cf の changeset は23とかになっていた気がする。大きな括りで次の3つの移行作業をした。

  • rds をスタックから切り離す
  • cdk の v1 から v2 へのアップグレード
  • ポリシーとセキュリティグループのドリフト解消

私は本番環境へのアクセス権限をもっていないので社員さんの作業内容を伝えてやってもらう。cf のテンプレートの更新やドリフトの解消など、テスト環境で10時間以上は費やした検証結果が功を奏して、本番作業は想定外の事象も発生せず1.5時間で完了した。cdk のコードも意図した設定になるように修正済みだし、なにも問題は発生しない。cdk のコードを書くときは cf のイベントログやドリフト結果と実際のインフラの振る舞いを確認するといった検証には時間がかかるが、それができてしまえば本番環境の構築はうまくできる。それがわかっているインフラ担当者がいなくなると、また1から担当者が検証する必要があって保守は大変かもしれないけど。

同じ Stack でどういったリソースを管理するかというライフサイクルは難しい問題かもしれない。今回 rds を削除したのは、なんらかの理由で手動運用で rds を変更することがあって、アプリケーション Stack から外してしまった方が保守しやすいのではないかという意見が出たため。それが正しいかどうかはわからないが、一度作ったリソースを削除しないもの (vpc や s3 bucket など) をアプリケーション Stack で管理すると、再作成できなくて面倒くさいことがある。というのは、再作成は新規に作成 → 古いリソースを削除の順番で処理されるため、一意な名前をもつリソースは基本的に再作成できない。

お花見リハーサル

0時に寝て6時に起きた。たぶん休暇をとったのはお正月以来かな。今日はオフィス行かなかった。

お花見 at 生田川公園

三ノ宮.devとbizpyの合同イベントとしてお花見を開催した。とはいっても、イベントページも作らず内輪で募集したので参加者は4人と小さく開いた。私もお花見やってもいいかと思いつつ、準備に着手するのが遅れた ので今回はリハーサルと称して来年の本番のための布石と位置付けた。たぶんもう1-2週間早く準備に着手していればもっとできたこともあったとは思うけど、まぁ最初はこんなもんか。

準備したこと

私が事前に準備したのはこのぐらい。労力にして数時間といったところか。

  • 事前に桜の開花状況を確認して日程調整
  • ほとんどの必需品はダイソーで購入
  • 参加者と連絡をとるためのプライベートチャンネル開設

実際にやってみてわかったこと

ダイソーで売っているこのサイズのレジャーシートが食べものを並べて4人で囲むのにちょうどよいサイズだった。

レジャーシート約4.5畳サイズ (ブルー、約270×270cm):300円

https://www.daiso-sangyo.co.jp/item/12550

各自一品は食べものか飲みものを持ち込みと呼びかけていたら次のものが集まった。事前に何をもってくるか示し合わせたわけでもないのに、みんなバラバラになってちょうどよかった。次回は示し合わせをしようとは思うが、意外とかぶらないものだなと感心した。

  • 手羽元
  • 唐揚げ
  • カルボナーラ
  • ピザ
  • 551のシュウマイ
  • ミートボール
  • いなり寿司
  • ビール
  • 日本酒
  • ワイン

天気もよくて11-16時という昼間の開催で直射日光を浴び過ぎたせいか、帰ってから熱気があってバテてた。4月になって日差しも強くなっているので直射日光を遮るなにかを用意してもよかった。大きな桜の木があればそれでもよかったんだけど、そうでもなく、地球が自転するので最初は陰になっていた場所も移動してしまった。わりと4人でわいわい話せたので小さい勉強会やイベントの方が距離感の近いイベントになってよかったりもする。たぶん10人とかいたらまた違う距離感のイベントになっていたんじゃないかと推測する。

ふりかえり

生田川公園 は住んでいるところから15分ぐらい歩けば行ける場所で花見イベントができることがわかって収穫だった。桜の木がたくさんあるというわけでもないので近所の人が集まるぐらいで、わざわざ外部の地域からくるほどのスポットではない。そのため、混雑していないというのが大きな訴求点と言える。バーベキューは禁止と書いてあったけど、他にも野外イベントに使えるかもしれない。河川沿いにある公園だし、夏に花火大会とか、秋にお月見とかやれそうな気はした。

開発が遅れる空気

昨日は0時過ぎまでオンライン飲み会で雑談していて、それから1時に寝て6時過ぎに起きた。

ストレッチ

今日の開脚幅は開始前161cmで、ストレッチ後162cmだった。今週はインフラエンジニアを始め、深夜と早朝に作業するため、生活が不規則になってしまった。そのせいか、腰と右股関節の張りが強いように感じた。1日は散歩に行ったり、深夜に一駅離れたスーパーに買いものに行ったり、すこし運動っぽいことも生活に取り入れるようにはしている。今週疲弊した身体をストレッチでほぐせたのでまた一週間がんばろうという気持ちになった。

インフラ作業

昨日からの仕掛り中の作業をテスト環境に反映させた。昼間は環境を壊してしまうとテストや検証作業を止めてしまうリスクがあるため、開発者や業務の人たちが使っていない時間を見計らって環境変更の反映や cdk の検証などをやりたい。必然的に土日も都合がよくて気付いたら2時間半ほど作業してた。

開発が遅れる空気

私は勘と経験で納期の1-2ヶ月前に開発が完了しないとわかるときがある。これまでなぜわかるのか自分でもよくわかっていなかった。便宜上「遅れる空気を読む」とでも言おう。私だけわかっても他者に伝えられない、もしくは伝えても無視されることが多かったので必要以上に指摘しないようにはしている。伝えて意図がわからない人たちにそれ以上言っても無駄だから。なにかしら条件があるのではないかと思い当たるところを書き出してみる。

  • チームメンバー (開発者) にタスクが遅れているという認識がない
    • 経験が浅いと見積もりの精度が低いため、全体像に対する進捗を正確に把握できない
    • シニア開発者がアドバイスしてもその内容を理解できなくて役に立たないこともある
  • 遅れている開発者が遅れを取り戻すための施策 (たとえば残業) をしない
    • 認識していないために残業しないから当然に遅れる
    • 認識していても残業を嫌う開発者は一切残業しない
  • 未知の問題や状況に対して「わからない」「困っている」といった報告をあげられない
    • 心理的安全性が低いと、無能だと思われたくなくて開発者が助けを求められない
  • マネージャーやリーダーといったスケジュール管理に影響力のある担当者が上位の意思決定者に事実ではなく自身の解釈を述べる
    • 例「このタスクは8割程度完了していて、あともう少しで終わりそうです」
      • 遅れているタスクはこういう報告が何度もあがる
      • 「いつ完了しますか?」と尋ねると予定日時を回答できない
  • マネージャーやリーダーが技術に疎く、実務担当者の言うことをそのまま受け入れる
    • 経験が浅い開発者の見積もり精度は低いため、大きく計画が狂うことがある
    • 私はソースコードを読んだ上でこの実装では品質基準を満たさないと判断したりしている
  • 上位の意思決定者と現場のリーダーとの人間関係が希薄だと建前の報告になる
    • 心理的安全性が低いと、現場の機微やもやっとしたことが共有されない

こういう空気を私は読んでいて、あるとき「この開発はもう間に合わないですね。」といきなり上長に言い始める。周りはまだ日程に余裕があるのになぜ?とびっくりする。開発って日々の積み重ねなので、日々の活動が正しい努力になっていないと1-2ヶ月後に成果が出ないというのは私からみたら自明だという話し。

壊れた cf スタックのリストアと cdk の再同期

2時に寝て6時半に起きた。インフラエンジニアになったのでみんなが作業していない時間にインフラの保守作業をするようにしている。昼はアプリケーションエンジニア、夜はインフラエンジニアみたいな生活になっていてしんどい。

壊れた cf スタックの更新

テスト環境の cf スタックを手動で更新して壊れているのを cdk で管理できるように直した。壊れていたのは次の3つ。

  • rds をスナップショットからリストアしたので cf が管理している rds リソースが存在しない
  • iam の acl 設定が異なる
  • セキュリティグループのインバウンドルールが異なる

aws 的にもそういった状況は認識していて cdk で同期できなくなった cf スタックを更新する手順を提供している。

ざっくり手順をまとめると次になる。

  1. 対象のリソースに DeletetionPolicy=Retain にセットする
  2. テンプレートからリソースを削除して、スタックの更新を実行する
  3. テンプレート内のリソースの実際の状態を describe して、スタック内に既存のリソースをインポートする

リソースの設定ぐらいなら既存のリソースからインポートしなくても cf のテンプレートを直接書き換えたものをアップロードしてスタックを更新するのでも大丈夫だったりする。しかし、cdk もそのテンプレートにあうように修正しないといけないため、cdk のコードとテンプレートのコードの両方をチェックしながら検証する必要がある。cdk でリソース管理ができるようになったからといって、それが変更前の既存のリソースの設定と同じかどうかは人間が目でみて検証しないといけない。これがあちこちで参照されているリソースだと追跡するのが面倒くさいといった手間暇がかかる。

cdk がよいものかどうか、私はまだ判断がつかないけど、cf を抽象化して便利になっているところは認めるものの、cf のスタックが壊れたときのトラブルシューティングが必要以上に複雑で厄介というのも事実ではある。一方で壊れた cf スタックを5時間ぐらいかけて直したのではまりポイントはいくつかも学ぶことができた。しんどかったけど。例えば、あるセキュリティグループのインバウンドルールに別のセキュリティグループを関連付けるとき、1つの設定ではうまくいかなくて次の2つの設定を追加した。これが適切かどうかわからないが、この設定で cdk でデプロイしたスタックの環境と既存リソースとの環境が整合した状態 (ドリフトが解消される) になった。こういうのが cdk の抽象化による訳のわからないところの1つ。

otherSecurityGroup.addIngressRule(
  ec2.SecurityGroup.fromSecurityGroupId(this, 'my security group', mySgId),
  ec2.Port.tcp(80),
  "my inboud rule",
)
otherSecurityGroup.addIngressRule(
  ec2.Peer.securityGroupId(mySgId),
  ec2.Port.tcp(80),
  "my inboud rule",
)

cdk のメジャーバージョンのマイグレーション

0時に寝て5時に起きた。開発者にインフラ変更の影響を出さないように6時半からインフラのお仕事してた。

cdk v1 と v2 の違い

AWS CDK Versions には v1 と v2 の2つがある。新規で作るものは v2 を選択すればよいけど、既存のスタックが v1 だとマイグレーションが必要になる。cdk は bootstrap したときに CDKToolkit というスタックを生成する。cdk をアップグレードするというのはこのスタックの設定も更新する必要がある。デフォルト設定をそのまま使っていればマイグレーションはそんなに難しくはないはずだけど、設定をカスタマイズしていたりするといくつかパラメーターを調整したりしなかったりしてややこしいかもしれない。

また v2 は v1 の experimental な機能は移行されていないため、v1 のライブラリを直接使うか、自前でその機能を実装するといったことも必要になる可能性がある。

例えば、v1 の apigwv2.VpcLink というメソッドは experimental で v2 に移行されていないため、v2 に移行されている stable な CfnVpcLink という機能を使って次のように実装した。これは v1 の cdk の実装をみて同じように実装しただけ。

-    const apiGwVpcLink = new apigwv2.VpcLink(this, 'ApiGwVpcLink', {
-      vpc: vpc,
-      vpcLinkName: 'my-vpc-link',
-      securityGroups: [mySecurityGroup]
+    const apiGwVpcLink = new  apigwv2.CfnVpcLink(this, 'ApiGwVpcLink', {
+     name: 'my-vpc-link',
+     subnetIds: vpc.privateSubnets.map(sb => sb.subnetId),
+     securityGroupIds: [mySecurityGroup.securityGroupId]

ecs の draining とタスクの停止時間

0時に寝て4時に起きた。なんか起きてから sns のタイムラインを眺めてた。6時半にはオフィスについて cdk のコードを読み始めた。

ecs の draining に時間がかかる?

cdk でインフラのデプロイをしていて、ecs のタスクの置き換えにやたら時間がかかっているのに気付いた。調べてみると、aws のドキュメントがすぐにヒットした。デフォルトでは停止するまでに5分ぐらいかかってしまうようだけど、それを調整したかったらいくつかパラメーターがある。

ecs サービスの deployment configuration

  • minimumHealthyPercent: 同時に停止できるタスクの割合設定
  • maximumPercent: draining されるタスクが停止するまで置き換えるタスクを開始するかどうかの設定?

ロードバランサーの deregistration delay

  • deregistrationDelay: elb(nlb) が登録解除処理が完了するまでに待つ時間。タスクが draining の状態になってこの時間が過ぎた後に登録解除して target が未使用になる

ecs タスク定義の stop timeout

  • stopTimeout: コンテナーが正常終了しないときに ecs が強制的にプロセスを kill するまでの待ち時間

それぞれのインフラの状況にあわせて適切なパラメーターを変更すればよい。私が管理しているのは次の2つを変更した。

  • maximumPercent: 100 -> 200 (%)
  • deregistrationDelay: 300 -> 30 (秒)

これで18分ほどかかっていたデプロイ時間を8分ぐらいまで短縮できた。テスト環境の設定なので多少のエラーが発生したとしても速い方がよい。

再びのインフラエンジニア

0時に寝て7時に起きた。

インフラタスクに専念

本当はインフラ担当者が別途いるのだけど、多忙過ぎて、インフラタスクが1ヶ月近く遅延していて、プロジェクト内で合意を得て私がすべて巻き取ることにした。内容の如何に依らず、その一切合切をすべて巻き取ると宣言した。過去に働いた会社でも他の担当者ができなかった業務を後からリカバリするのはよくやってたのでそれ自体は構わない。ただ他人のタスクを肩代わりしても評価されないことも多くて、もともと私のタスクではないから誰がやったかなんか忘れてしまうんよね。私もとくにアピールしないからそう認識されても構わないのだけど、そういう業務が増えてくるとその職場を辞めるきっかけにもなってた。

インフラ担当者や他の社員さんにヒアリングしながら現時点でも十数個のタスクがある。過去のインフラの負債も含めて2-3週間ぐらい、私が集中的にやればすべて片がつくのではないかと考えている。今日たまたまスクラムのリファインメントやってて、業務の人から他の機能開発が遅れているのに2-3週間もインフラ作業に専念するってどういうこと?インフラタスクってインフラ担当者にやってもらえないんですか?と質問を受けて、できるんならその方が望ましいけど、過去の実績からまったく進捗しないのでこちらでやるざるを得ない状況というのを説明した。業務の人からみたらインフラなんか何をやっているかわからないからそんなもんよね。これから2-3週間経って蓄積したインフラタスクをすべて解決した後で少し時間が経つとインフラ担当者が全部やったように外部からはみえてしまうというのを、過去に何度も経験した。