生涯未熟

生涯未熟

プログラミングをちょこちょこと。

ソフトウェアエンジニアと品質保証 SRE、QAの枠にとらわれない新しい視点 参加レポ

参加した時にメモっていた内容になります。自分向けに投稿。

URL:https://offers.connpass.com/event/290685/

みーんなSREとかQAをチームにしとる チームにしていないのお前だけ - toriさん

開発チームがシステムを運用するオーナーシップ 
→ SRE, QAを安易にチーム化しない
→ なぜ?

チーム化の理想は?
専門領域の深掘りを集中的にできる
→ 果ては他チーム・組織全体にまで波及させる
→ 希少な人的ソースを基盤化

但し問題がある
・責務分割からの責任の放棄(あっちのチームがいい感じにやってくれるでしょ
・権限問題(あっちの領分だし
→ 外部からの口出しがしにくくなる
→ (外部から見て)よくわからんがこうなってる

!!学びの機会の損失!!

組織の形によっては「こっちで良しなにやりました、あとはよろしく!」となるのが良いのか悪いのかという論争はある

カミナシでは開発チームではなくサービスチームという立て付けでやっている
→ サービスを提供して初めてユーザーに価値が届く
→ 開発を求めているのではなく、サービス提供を求めているというお気持ち

チーム化による必要なケイパビリティを備える機会を奪うことを避けたい

セキュリティチームはさすがに人いなさすぎてチーム化
→ サービスチームにenablingしていくこと、文化を作っていくことを目標としている

オーナーシップをどこに集結させるのか?というお話だった。

QA;CSとかはチーム化した方がいい?
サービスチームにどこまでオーナーシップを持つのか?による。ビジネス含めて丸っと全部持てたら最強だが、現実的にはそうなっていない。

パネルディスカッション

t-wadaさん -> W
toriさん -> T

テーマ:チームでQAを捉える場合、具体的にどう進めていく?

W;チームにどれくらいQAを理解している人がいるか?にもよる。別チームにQAがいる場合には、時間借りのような形で関わってもらう。
自分ごととしてどこまでチームが範囲を広げられるか?経験者がいない場合には読書会や外部経験者からの助言でまかなっていく。学ぶ姿勢が大事。
機能開発にリソースを全振りするのはダメ。時間があったらやりますは結局やらない。

T:QAうまくいってるかというとそうではない。トライしている最中。QAは外部ベンダーから派遣されていたが、手動テストを減らすなどでエンジニアリングの力で減らしていき、QAは上流工程からどうしていくのか?を助言する立場。
スクラムでやっていると全リソースを機能開発に注ぎがち。そうなると自然に得意分野のタスクしか取らなくなる。業務外で学べ、は違うよね。
チーム全体のスループットが下がっても業務内で学んでいく。

QA:チームを分けない場合での理想状態は、各サービスチームが自律的にやるのか、それともある程度ナレッジシェアリングなどを行いつつ進めたいと考えるとチーム横断のワーキンググループみたいな形でやるのが良いのか、どうお考えでしょうか?

W:横串の知見共有グループを作るのがよい。知識をサイロ化させない、ナレッジシェアリングの場を作ろう。横串チームではなく、横串コミュニティを作る。
T:カミナシは小さい会社なのでまだサイロ化は起こっていない。AWSは↑のコミュニティがあった。横串コミュニティがなぜやっているのか疑問化されないためのカルチャーづくりも大事。

QA:SRE/QAを内包することで、何かチームライフサイクルが変わることがある?

T:例として開発段階でそれぞれのレビュー目線で指摘することができる人が増えること。

テーマ:SREやQAがチームをあえて別チームにすることが効果的な場合はある?

T:評価が難しくなってきたとき。専門領域が多岐に渡ると評価者が判断しかねることがある。サービスチームにはいるが、評価者としては横串チームでやってもらう、みたいな感じも一つ。

QA:SRE/QA/セキュリティなどの専門知識をenablingしていくメンバをチームに配置するとチームの規模が大きくなり過ぎて困ることはないですか。もしくはenablingするメンバを1人配置するほどの規模ではない場合にはどうしていますか。

T:チームサイズの理想は1桁人。2pizzaチームと言いながら前職で30人いるとかはあった。前職ではチーム規模を保つために、オーナーシップを上手く切っていくことをやっていた。
W:逆コンウェイのようなことですよね。つらいところはどこでした?
T:AWSの規模だと急なトラフィック増があるが、スケールするようなチームの切り方をしていた。ボトルネックがチーム間で共有されるような場合には2チームが結局依存する形になったりしていて、そこの解決が難しかった。

QA:QAチームを分けることで一定の品質を担保できるメリットがあると思っています. 開発チーム内で品質を管理しようとすると, どうしても開発優先となり品質の優先度が低くなってしまいがちになってしまうと思いますが, それを防止する方法等がありますでしょうか?

W:品質を下げて開発スピードが上がるという考え方が間違い。品質を担保できていないのは開発が終わっていないと同義。手順を分けると「あとはお願いします脳」になっちゃうので、そうなっている。チームを分ける怖さはここにある。完了の定義を見直そう。
T:スタートアップなどだとスプリント回したあとに、次のスプリントは負債を回収するために動くといった動きもあるっちゃある。

テーマ:ソフトウェアエンジニア一人一人がQAにどう関わっていくことが求められているのか?

T:使いたいものを作ろう!という意識が大事なんじゃないか。降ってきた要件をこなすだけはやめよう。価値提供することをもっとエンジニアの意識の中心に置こう。
W:同意見。自分事として関わることが大事。あとはユーザーとの距離が遠すぎると意識が希薄になっていくので、近づけることも大事。アクセスログを体感するとか、ユーザーの意見を受け取るなど。

QA:品質保証への意識を高める、学ぶためにどのように学んでもらうのが良いでしょうか? また、それは目標設計に含まれる場合、どういう目標設計にするのが良いのでしょうか。

T:仕事の中で学ぶのがオススメ。カミナシではジョブレベル・等級要件の定義に品質についての文言を含んでいたりする。
W:目標設計は事業貢献一辺倒・技術貢献一辺倒でもダメ。どちらの側面からも評価してあげるように設計するのが良い。

質疑応答

QA:QAってすごく多彩な領域があると思います(組織の品質ポリシー、チームのポリシー、チームが目指す(外部)品質モデル、テストのレベル、サイズの定義、テスト分析、設計、自動化、CI、メトリクス、内部品質の選択と担保etcetc... )チームにQAをEnableしていく、ときにどこからはじめると進みやすい、入りやすい、など感触ありますでしょうか?

T:テスト設計を一緒にやっていくことで、こういった観点があるのか!など感動があった。そういったスキルを持った人による新しい観点の導入が感触としてはよかった。
W:仕事を減らす入り方が良い。過剰なテストを減らすようなところから入ってもらうといい。エンジニアはとにかくありったけのテストを詰め込むので、そこを調整してもらうのが最初にやってくれると刺さる。
T:専門知識を持っている人は最高の状態を目指そうとする、ただヨチヨチ歩きの状態からは圧が強すぎるのでここまでにここに行きたいというロードマップを引いてもらえるとよさそう。

QA:定期アップデートの話?(質問見つけれなかった)

T:定期アップデートは当たり前にやることとして、価値観に入れている。(とはいえカミナシのAuroraアップデートはまだやれてない・・・

締めの一言

T:カミナシは仮説を元に実験的に色々やっている。今日話したことが実際に成功したかは今後のカミナシを見ていってくれ!
W:良い会でした

【PostCSS】ts⇔css間で値を共有する

プロジェクトの依存ライブラリをアップデートする苦行をやっているのですが、その最中で遭遇し解決した事象の話をば。
PostCSSを使っているのですが、その中で postcss-custom-media をv8からv10に上げた時にそれは起きました。

まず、以下のようなPostCSS設定ファイルがあり、

これがv8 -> v9でのbreaking changesにて importFrom が削除されたので、修正する必要がありました。
これについては、以下の内容を参考に postcss-global-data を使う形で解決しました。

github.com

各ComponentにCSSファイルが配置されていて、そこで @custom-media を利用しているのですが、 postcss-global-data を使って別途作成した media-queries.css を読み込ませて解決。
しかしここでふと気付いたわけです。「tsと共有している 100px をどうしよう・・・」と。

tsからはこのような形で呼び出していたのです。困った・・・

この問題を解決するためにいろいろ試しました。
最初に postcss-css-variables を使って media-queries.css に設定している @custom-media で指定しているピクセル数をcss variablesに置き換えていけるかな?と思ったらmedia queryでcss variablesが使えないことでダメでした。(知らなかった・・・)

次に、 postcss-extractatrule として custom-media を抜き出してexportしたものをts側で利用しようとしたけどなんかダメだった。
どういう風にダメだったかというと atrule[name="custom-media"] といった形式で抜き出そうとしたものの、取得結果を見ると空となってしまいどうしてもここを解決することができませんでした🤔

で、最後に試したのが postcss-design-tokens で、これが見事に刺さりました。これを使ってCSS内でデザイントークンを利用すればcss variablesではないのでいけないか?と思い、使ってみた経緯です。
利用例としては以下のような感じ。

これで具合が良かったのはts側からは design-tokens.json を読み込むだけでOKなのでめっちゃ楽ってとこでしたね。で、 @custom-media@media で使う際にcss variablesで怒れることがなく、万事解決しました!

まとめ

蓋を開けてみればPlugin知ってるか知らないかの話だったんですが、PostCSSのPlugin多すぎ問題があるのでなかなか難しいところではあります。
あとはmedia queryでcss variables使えないのは純粋に知らなかったので、これは大反省です・・・

chaika.hatenablog.com

この記事見かけてなかったら一生彷徨ってたかもしれないので感謝🙏

GKEアップグレードの時にいつもやっていること

GKE使っていると定期的にアップグレードの圧がやってきますね。
エイヤッと不用意にクラスタのアップグレードを行うと、deprecatedとなるapiVersionを使ってしまい最悪サービスが不通になる可能性もあります。

本記事ではアップグレード時にいつもやっていることをまとめていますが、暫定のものになるので変遷とともに各々改善していってください。

やっていること

まずは上げたいバージョンにアップグレードしても大丈夫かを調査するところから開始します。 確認することは以下の2つ。

  • 上げるバージョンに対して非推奨APIを使っていないかを確認
  • k8s Change Logを確認

上げるバージョンに対して非推奨APIを使っていないかを確認

Cloud Loggingを使うことで対象バージョンでの非推奨APIを使っていないかどうかをチェックすることができます。 以下のクエリを実行して非推奨APIを使っていないかを確認してみましょう。

resource.type="k8s_cluster"
labels."k8s.io/removed-release"="[上げるバージョンを指定]"
protoPayload.authenticationInfo.principalEmail:("system:serviceaccount" OR "@")
protoPayload.authenticationInfo.principalEmail!~("system:serviceaccount:kube-system:")

[上げるバージョンを指定] は対象が仮に1.26であれば1.26とそのまま入れてください。

もし非推奨APIが存在する場合はGKEのドキュメント内にアップグレードガイドがあると思うので、そちらを参考に対応を進めるのが良いです。

cloud.google.com

k8s Change Logを確認

基本的には非推奨APIの指定だけで問題ないと思いますが、念の為k8sのChange Logにも目を通し、 Upgrade Notes などアップグレードに関する情報を読むことをオススメします。

k8s Change Log:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/README.md

以上が、私がGKEのアップグレード時にやっていることになります。最近ではコンソール上でも非推奨APIを使っていないか?などを出してくれるのですが、上記のようなやり方もありますよというご紹介でした。

メモリ使用率によってk8sのPodをevictさせる君を作った

サービスを運用している中で緩やかにメモリ使用率が上がっていく問題があり、それが解決されるまで一時的になんとかするために掲題のを作りました。

github.com

中身自体はZapierが作っていたpreoomkiller-controllerが元になっております。

github.com

このコントローラーを導入すれば済む話じゃない?ってなりそうですが、こちらは「メモリ使用量」を閾値としており、更に更新も止まっていたのでせっかくなら勉強がてら作り直すかーとなった結果こうなりました。

この手のk8sに関するツールを今まで全く作ったことがなかったので、勉強に以下の本を読ませていただきました。

preoomkiller-controllerでclient-goを使っていたこともあり、かなり勉強になりました!

で、この本とpreoomkiller-controllerを読んでちょろちょろ書き直した結果、以下のように修正しました。

  • メモリ使用量からメモリ使用率の閾値に変更
  • Go1.13からGo1.20に対応
  • helm installでインストール出来るようにした
  • その他、動かなくなっていたところをチマチマ修正

他にも色々直したいところはあるんですが、そこは追々手を入れていこうかなと思ってます。

もし、要望やアイデアがあれば大歓迎なので是非issueにおねがいします🙏

Cloud ArmorのOWASPルールセットによるGraphQLリクエストでの誤検出

たまたま遭遇したけど誤検出のあるあるっぽいなと思ったので調べてメモしとく。

前提としてCloud Armorの事前構成 WAF ルールであるOWASP TOP 10のルールを有効化して運用しておりました。

cloud.google.com

運用自体は特に問題なかったのですが、ある日GraphQLの機能実装をしていたメンバーから特定のリクエストが403で弾かれますと報告を受け調べることに。

Cloud Armorのログを確認する

Cloud Loggingで jsonPayload.enforcedSecurityPolicy.outcome="DENY" なログを調べたところ、特定のルールが原因で弾かれていました。

それが、 lfi-v33-stableowasp-crs-v030301-id930120-lfi で弾かれていて、どうやら .profile がヒットしている様子。
たしかに、特定のリクエストにはfragmentとして profile といった文字列を含んでいて、それがルールに抵触して弾かれているようなのですが正直何で?といったお気持ちになったので少し調べてみることに。

ルールを確認してみよう

Cloud ArmorのOWASP TOP 10のルールはこのリポジトリで管理されているコアルールセットを元に構成されています。

github.com

で、今回引っかかっていたのはこの OS File Access に関するルールでした。

github.com

#
# -=[ OS File Access ]=-
#
# Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile lfi-os-files.data" \
    "id:930120,\
    phase:2,\
    block,\
    capture,\
    t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\
    msg:'OS File Access Attempt',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-multi',\
    tag:'platform-multi',\
    tag:'attack-lfi',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/255/153/126',\
    tag:'PCI/6.5.4',\
    ver:'OWASP_CRS/3.3.1',\
    severity:'CRITICAL',\
    setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

たしかに、 owasp-crs-v030301-id930120-lfi で検索をかけるとOSファイルアクセス試行とあったので間違ってなさそうですね。
ここで参照している lfi-os-files.data を見てみると・・・ .profile がありました!間違いなくここですね。

github.com

こりゃめちゃくちゃ引っ掛かりそうだなーと思いながら調べていると、別のリポジトリでこの .profile を含めていることに憤っている方もいました。

github.com

対応として合致パターンを ^.profile とかにすればいいと思うとのこと。しかし、Cloud Armorで用意されているルールに手を加えることも出来んし困るなー・・・

困ってる人多そうとか思ったが、調べた限りあまりいなかったのでモヤモヤしつつも OS File Access のルールをオプトアウトルールにする対応を取りましたというお話でした。