pokutuna.com

pokutuna

Web Developer / Software Engineer
Hyogo, Japan

Blog Entries

  • ぽ靴な缶

    Google Cloud 認定 Professional Data Engineer 取りました

    やったー Google Cloud の主催する Google Cloud Innovators Gym Japan (G.I.G) というプログラムに参加して取りました。 Google Cloud を利用する企業を対象とした招待制のプログラムで、参加すると関連する Coursera コースへのアクセス、試験を受けるためのサポート、Google Cloud エンジニアの方によるハンズオンや質問できる機会が提供されます。 バッジ 以下の資格が対象。今回のプログラムは4月中頃に始まり、7月中頃までに Coursera のコースを終え合格報告をするスケジュール。お話を頂いて良い機会なのでチームの若者を誘って参加しました。 Professional Cloud Architect Professional Cloud Developer Professional Data Engineer pokutuna は公式ドキュメント読んで筋の良い手段を取ればいい、正直俺ならいつでも資格は取れる... という傲慢さを持っているわけだけど、なら取れよと思うのも当然の話、無免許で Google Cloud を触っている事実は覆せない。なら GW 予定もなんもねえし最速で取ってやるわいと、GW 中に PDE コースの Coursera を終え、記憶が揮発しないよう頭皮をキュッと絞めながら5月末に試験を受けた。 普段やってる範囲については良い再確認の機会になった。各プロダクトそれぞれのドキュメントを読みつつ、過去の経験や一般的なソフトウェアに対する感覚で色々判断しているわけだけど、Coursera の授業を聞くとまあそうなるよね間違ってなかったわとなるし、微妙に知らないことや使ってない機能の知識も補えた。あと同僚に説明する時も言語化しやすくなったと思う。普段使っていない Dataflow や BigTable はフムフムと授業を聞けた一方、Dataproc はモチベーション上がらなかったな。今から Spark や Hadoop を選択しない...という気持ちがある。Data Engineer でも ML の話はあるものの概念や手法の一般的な話なのでまあいける。再現率と適合率、どっちがどっちか毎回忘れるので覚えたけど、テスト勉強自体 10 年ぶりなので懐かしい感じがした。 印象に残ったのはコンピューティングとストレージの分離の話。 アーキテクチャの話として出てくるけど、クラウドやサーバレスの切り口にもなる話だった。この 2 つを分離できるなら一気にスケールできて、ボトルネックがネットワークに移る。分離できないアーキテクチャだったら2つセットの仮想マシン的な単位で借りないといけない、1台のキャパシティに気を揉むことになる。サーバーレス以前のアプリケーションはそうなりがちだし、要求が高い OLTP な DB だったりしてもそうなる、みたいな理解ができる。 そう考えると Spanner はめちゃすごいし、その後に演習で BigTable インスタンス作るけど、操作可能になるまでの速さにびっくりするのでうまく出来ているんだなと思う。 もう1つは、秘訣(The secret sauce) - How Google does Machine Learning で出てくる "自分で見たことがないデータは準備不足" という話。気に入ったところを引用する。 十分なデータが集まってない またはアクセスできない時点で MLについて話しても無意味です 実はデータがあるかもしれませんね 何年も記録し 別の部署が管理しているシステムに あるかもしれません でも実際に見たことはありません 私は自信を持って言います 自分で見たことがないデータは準備不足です それだけでなく 定期的にそのデータを確認して レポート作成や新たな発見をする人が 組織にいないなら つまり そのデータがすでに 価値を生み出していないなら データの保守に努力が 払われていない可能性が高く データが次第に廃れていきます これまで対話したクライアントの中で クリーンデータを集める労力を 過小評価しない人には 会ったことがありません 「思ったより簡単だった」と言う人はいません 多くの苦労や障害に直面するでしょう おっしゃる通りです、感動で泣ける。 これは ML Engineer の授業なんだけど、規定の 3 コース以外の Coursera にもアクセスさせてもらえるので見れた。ありがたいですね。 試験について 公式の模擬試験は初見 88% 正答だったので、まあ見直せば合格やろと思いつつ念のため Kindle で売ってた模擬問題集をやったりした。要件に応じてどのプロダクトを選ぶかとか、コスト最適化とか定番問題は色々ある。読みながら雑にまとめたメモはこれ、メモなので整理されてはいないけど助けになる人も居るでしょう。Processional Data Engineer - pokutuna 模擬問題集には、かなりの悪文があったり、その選択肢じゃ一意に決まらなくない? と思う問題もあった。商品レビューで低評価されているものの、ある意味かなり役に立ちました。Coursera だけで試験突撃してたら落ちてた可能性ある。で、こういう問題集なんですが... 真面目に作ってる人も居そうですし、言いがかりになると悪いんだけど... これ英語の書籍や海外コミュニティの問題を機械翻訳したやつだったり、公式模擬試験を更新のたびに集めたやつだったりしない? 俺が見たヤツはそういう感じが漂っている... 役には立ったし恩は感じるけど、宣伝したくはないという複雑な気分。 試験は大阪の Kryterion と提携するテストセンターで受けた。リモートも選べたけど、専用ソフト入れたり部屋を片付けて試験官に見せたりしたくないなと。行って受付したら、即ロッカーに私物全部入れて待っててくださいという感じだったのは予想外だった。試験開始時間を待ちながら携帯で見直す想定だったんだけど...もっとギリギリに行ってもよかった。試験は席ごとに衝立が置かれた学校の PC 教室のようなところで受ける。同じ部屋の受験者同士で受けてる試験は違っていて、待っている間の周囲の会話の感じだと、TOEFL や Microsoft Office の資格試験なんかも同時にやっているようだった。 あとこれは規約で共有を禁じられた試験内容にあたらないと思って書くんですが、環境が中華フォントで問題文が読みづらかった...理解するのに支障はないけど、ボタンラベルが 見直す になってるのは日本語表示環境じゃないでしょう。 認定証の検証 試験に合格すると、Accredibleで認定証とバッジ画像が発行される。 そんで認定証の存在がブロックチェーンに記録されてるらしいじゃないですか、しかも BTC。BigQuery に精通する Professional Data Engineer として、証明書の存在を UDF で検証しつつ bigquery-public-data.crypto_bitcoin.blocks の行を SELECT する SQL を披露するのが合格エントリに相応しい。 そう思ってマークルツリーの仕組みとか読んでみたけど、肝心のリーフとなる自分の証明書の SHA256 を得る方法が分からない。このドキュメントの "similar to ~" で濁されているところが知りたいんだけど... 一応 blockchain-certificates/cert-schemaを読んで、Accredible の blockchain data API から得られる JSON 中の credential_json_data を URDNA2015 & nquads で正規化したりしてみたんだけど、API のレスポンスに含まれるハッシュにならなかった。証明書と btc_anchor_branch からこのクエリの merkle_root を計算して SELECT してドヤ、という予定だったんだけど、興味が続かなくて諦めた。 SELECT * FROM `bigquery-public-data.crypto_bitcoin.blocks` WHERE merkle_root = "de49e548fe4fb7b8b01f263b101c87f08a3c384c9d0e6d873daa179378ae5376" AND timestamp_month = "2023-05-01" Open Badge の仕様は読んでみて、バッジの png 画像から URL を取り出すのは書けた。記事冒頭のバッジ画像から取り出せるよ。 badge.go · GitHub

  • ぽ靴な缶

    Google Cloud 版 Dataform と周辺リソースの図

    GCP 版 Dataform がついに GA になりましたね。同時に定期実行の仕組みも出て、一通りの機能が揃った感がある。いまこそ買収以前の SaaS 版(Legacy 版)から GCP 版に移行する時!! しかし GitHub リポジトリと連携する場合、登場人物が多くて難しくなっていると思う。 特に GCP に馴染みがなかったりデータ分析がメインの人は困りそう。公式ドキュメントには step by step で書いてあるものの、なぜ必要なのか分からないまま設定することになる。 なので全体像を図にしたり補足するという趣旨のエントリです。 Dataform とは Dataform とは...という話はしません。公式ドキュメントや世間のブログ記事を読もう。 Dataform を使うと、テーブル同士の依存に基づいて順番に SQL を実行してデータパイプラインを作ったり、依存関係を可視化したり、データセット名に suffix を付与してステージング環境を作ったりできる。 現状の Dataform でカバーしきれない複雑な要件、具体的には更新や変換にリアルタイム性が要求されたり、外部の依存やトリガーに基づくパイプラインなどでは Cloud Dataflow や Clodu Composer が必要になるけど、データウェアハウス実装のかなりの範囲をカバーするサービスです。 cloud.google.com Google Cloud のリソースとの関係 このあたりのドキュメントで登場する登場人物をまとめた。 Quickstart: Create and execute a SQL workflow  |  Dataform  |  Google Cloud Create a Dataform repository  |  Google Cloud Connect to a third-party Git repository  |  Dataform  |  Google Cloud Dataform と周辺リソースの関係 ① まず Dataform API を有効にして、コンソールから Dataform リポジトリを作る。 すると ② Dataform サービスアカウントが Cloud IAM に生えてくる。 service-{PROJECT_NUMBER}@gcp-sa-dataform.iam.gserviceaccount.com の形式。 IAM 一覧では、ユーザが作ったもの以外はデフォルトでは非表示なので、"Google 提供のロール付与を含める" をチェックするとよい。 ふくめる 重要なのは、Dataform はこのサービスアカウントの権限で動作するということ。 ③ GitHub に行き、Dataform のコードを保存するリポジトリを作る。 ④このリポジトリを GCP 側から操作するため Personal access token (PAT) を払い出す 今 GitHub には 2 種類の PAT がある。 personal access tokens (classic) fine-grained personal access token classic は以前からあるが、リポジトリ単位でのアクセス制御ができない。新しい fine-grained を使い ③ で作ったリポジトリのみ許可するのが良い。classic では、scope に repo を、fine-grained では Repository permissions で Contents: read and write を与えればよい。 ⑤ 再び GCP 側に戻り、Secret Manager でシークレットを作成し、④ で作成した PAT をバージョンとして保存する。 ⑥ シークレットの "権限" タブで、② の Dataform サービスアカウントに roles/secretmanager.secretAccessor ロールを付与して Dataform がこのトークンを利用できるようにする。 補足すると、ここでは個別のシークレットへのアクセス権を付与している。IAM コンソールの目立つボタンからロールを付与すると、プロジェクトレベルのアクセス権となり、一通りのシークレットにアクセスできる権限を付与することになるので注意。 これで Dataform コンソールでコードを書いて GitHub へ push できるようになった。 ⑦ Dataform を使う目的は BigQuery のテーブルを作成したり更新したりすることなので、IAM で Dataform サービスアカウントに BigQuery を操作する以下の権限を付与する。 BigQuery ジョブユーザー (roles/bigquery.jobUser) BigQuery データ編集者 (roles/bigquery.dataEditor) その他、別のプロジェクトのデータを参照したい場合は、そちらでも BigQuery データ閲覧者(roles/bigquery.dataViewer) を付与する。更新したいならデータ編集者ね。Dataform 実行プロジェクトと BigQuery リソースのプロジェクトは異なっていても構わない。 Google Spreadsheet など Google ドライブのデータを外部テーブルとして扱いたい場合は、該当のファイルを Dataform サービスアカウントに共有すればよい。 Spreadsheet をサービスアカウントに共有する (オプション) CI やその他のワークフローから実行する可能性があるなら、それ用のサービスアカウントを作っておくとよい。 ② のサービスアカウントは、GCP が管理するもので Service Agentとも呼ばれる。追加のロールを付与することはできるけど、ユーザーが成り代わったり認証情報を入手したりはできないので、Dataform コンソールの外から利用できない。 IAM での権限は Google グループに対しても付与できるので、Dataform サービスエージェントと、CI 用のサービスアカウントを所属させておいて、そのグループに対して BigQuery の権限を与えるようにしておくと、2 つのサービスアカウントそれぞれ与えなくて済むし権限が食い違うこともなくなる。 サービスアカウントを Google グループに所属させる cloud.google.com GitHub リポジトリと連携しなくても使える ここまで GitHub リポジトリと連携するつもりで書いていたけど、連携しなくても Dataform を使うことはできる。 リポジトリとしての便利さはほぼ得られない。2023-05-14 現在、HEAD にコミットするか戻すかどうか、Workspace の変更を main に push する操作だけできる。 ちょっと触ってみたいだけなら、連携部分は気にしないでいいと思う。必要になったら GitHub リポジトリと接続すればいい。Legacy 版と違って既にファイルのある GitHub リポジトリと連携することもできるし。 CI GitHub 連携をしたら GitHub Actions で CI を整備したいですね。 push したら compile に成功するかチェック & dry-run する main にマージしたら Dataform を実行する などするようにしています。 cloud.google.com CI で色々やる際の注意点として、ルートの package.json の依存は @dataform/core のみか、最小限にする必要がある。Dataform コンソールで SQLX をコンパイルする際に、バックグラウンドで npm install が走っているようだけど、依存が増えるとタイムアウトしてまともに使えなくなる。@dataform/cli が増えただけでダメ。 CI の中でだけインストールしたり $ npx -p @dataform/cli@latest dataform compile などしています。 Can't install certain devDependencies [264598563] - Visible to Public - Issue Tracker おまけ Dataform 関連だけ抜き出した Terraform、google-beta が要ります。 resources.tf variable "project" { type = string } variable "region" { type = string default = "asia-northeast1" } variable "dataform_repository_url" { type = string } variable "dataform_default_branch" { type = string default = "main" } data "google_project" "this" { project_id = var.project } resource "google_secret_manager_secret" "dataform_repository_token" { secret_id = "dataform_thirdparty_repository_token" replication { automatic = true } } resource "google_secret_manager_secret_version" "dataform_repository_token" { secret = google_secret_manager_secret.dataform_repository_token.id secret_data = "******" } # secret が state に書かれてしまうので、普段は手でコンソールから secret と version を作って # secret は terraform import、 version は data リソースで参照、みたいにしている # # data "google_secret_manager_secret" "dataform_repository_token" { # secret = google_secret_manager_secret.dataform_repository_token.id # } resource "google_dataform_repository" "dataform" { provider = google-beta name = "my-dataform-repository" region = var.region git_remote_settings { url = var.dataform_repository_url default_branch = var.dataform_default_branch authentication_token_secret_version = google_secret_manager_secret_version.dataform_repository_token.id } } # Dataform Service Agent へのロール付与 locals { dataform_agent_member = "serviceAccount:service-${data.google_project.this.number}@gcp-sa-dataform.iam.gserviceaccount.com" } resource "google_project_iam_member" "dataform_agent_roles" { for_each = toset([ "roles/bigquery.dataEditor", "roles/bigquery.jobUser", "roles/dataform.editor", "roles/dataform.serviceAgent", ]) project = var.project role = each.value member = local.dataform_agent_member depends_on = [ # Dataform Service Agent は最初の repository が作成された後に作られる google_dataform_repository.dataform ] } resource "google_secret_manager_secret_iam_member" "dataform_repository_token" { secret_id = google_secret_manager_secret.dataform_repository_token.secret_id role = "roles/secretmanager.secretAccessor" member = local.dataform_agent_member depends_on = [ google_dataform_repository.dataform ] } # CI などから Dataform を実行するためのサービスアカウント resource "google_service_account" "dataform" { account_id = "dataform" display_name = "dataform" description = "Dataform 実行用サービスアカウント" } resource "google_project_iam_member" "dataform_sa_roles" { for_each = toset([ "roles/bigquery.dataEditor", "roles/bigquery.jobUser", "roles/dataform.editor", ]) project = var.project role = each.value member = google_service_account.dataform.member } おわりに Dataform が買収されて進化が止まっている間にライバルの dbt が普及してしまった感がありますが、巻き返してほしいですね。 Google Cloud 組み込みだし、BigQuery を DWH として使っていたらすぐ使い始められるし、無料だし dbt Cloud のようにユーザー数課金でもない、第一の選択肢になると思います。 気が向いたら、定期実行とその通知について書こうと思います。

  • ぽ靴な缶

    Slack チャンネルのロボット帝国化を防ぐ feed-pruning-proxy

    この記事は はてなエンジニア Advent Calendar 2022 2日目の記事です。 みなさんは Slack の RSS アプリ を使っていますか? /feed subscribe FEED_URL で RSS や Atom フィードをチャンネルに流すことができます。 Slack に RSS フィードを追加する | Slack これを使って各種リリースノートやニュースサイトの新着をいろんなチャンネルに流しています。Slack をお使いの皆様もきっとそうしているでしょう。 フィードによって技術の最前線をキャッチアップでき、供給された話題は参加者同士の活発な議論を産む。学習とコラボレーションが同時に促進される素晴らしい機能と言えますね。 . . . 本当か??? 例えば BigQuery のリリースノートを流すとこうなる!! 激流 これ 5 記事あるわけじゃないからな。 こんなフィードをチャンネルに流していると、いつ開いてもフィードしか見えない。 そうして人々は言葉を発しなくなる。 そうやって生まれた自動的な通知ばかりで人が話さなくなったチャンネルをロボット帝国と呼んでいます。人類は機械に支配されたのである。 展開オプション 当然知っているけど、Slack には展開オプションがあって、受け手側で展開を抑制することもできる。 でも全く展開してほしくないわけじゃないのよ、普段の会話では展開してくれるのは便利だし。 展開オプション ロボット帝国に対抗するために生まれた feed-pruning-proxy そんなチャンネルに人間性を取り戻すため pokutuna/feed-pruning-proxy を開発しました。 これはクエリパラメータに与えた URL のフィードの内容を加工して返すアプリケーションです。 いくつかの機能がある。 /p?feed={url} (デフォルト) フィード中の各エントリの本文部分を削除します。 RSS なら description, Atom なら summary と content 記事の URL やタイトルは流れるので、それだけ Slack が展開することに期待します フィードの本文と展開される URL の内容が重複するようなフィードに対して、2回も言わなくていいよという時に使う。 /p?feed={url}&diet (diet モード) フィード中の各エントリの本文部分のマークアップを削除します。 リンクの展開を抑制しつつ本文を出力したい時に使います。 Slack の展開結果が 何もない or 画像だけ のような、何か言ってよというページに対して使う。 こうして得た URL を /feed で購読することで、たかだか1つ展開されるちょうどよい出力がチャンネルに流れるようになります。 実際に記事を読んでるのか そういう気持ちになることもありませんか。それも解決します /p?feed={url}&org={str}&channel={str} とすると これで実際にフィードから記事を読みに行っているのか計測できるようになり、このフィード誰も見てないし remove しましょう、という話ができるようになる。 このログを BigQuery に流し込むと集計や可視化も簡単にできて、みんなが注目した記事とかが分かって楽しいですね。 ご利用頂けます これを GAE にデプロイしておきました。こちらからご利用いただけます。 https://feed-pruning-proxy.an.r.appspot.com/ 迷惑がかかるような使い方をされていたり、金がかかるな〜思ったら予告なく止めるかもしれません。 App Engine または Cloud Run へのデプロイ なのでぜひ自分の GCP プロジェクトにデプロイしてみてください。 App Engine へのデプロイは $ gcloud app deploy でできます。エッジキャッシュもあるし、こういうちょっとしたアプリケーションを公開するのに大変便利ですね。 blog.pokutuna.com また、Cloud Run にデプロイできるボタンを README に置いておきました。押すと Cloud Shell が開いて Cloud Run にデプロイできます。 これを使っています github.com さあロボット帝国に抗い、人間の輝きを取り戻しましょう。 はてなエンジニア Advent Calendar 2022 2日目の記事でした。 昨日は id:arthur-1 さんの Advent Calendar を Mackerel で監視する 〜新卒の暮らし方を添えて〜』 でした 明日は id:mizdra さんです。

  • ぽ靴な缶

    なぜ今も Google App Engine を選ぶのか

    Google Cloud で何かアプリケーションを動かしたい時、いつも App Engine (GAE) を第一の選択肢として挙げています。 なのにみ〜んな Cloud Run に行ってしまう。なぜなのか?? 確かに Cloud Run のほうが新しくて公式に露出が多いし、GAE はこういうランディングページからの言及も消えているので無理もない。Google Cloud 的にもあんまり使って欲しくない雰囲気が漂っている。 cloud.google.com App Engine は GCP 最初期からあるサービスで今年で 14 年目になるらしい。 Google App Engine 単体で出ていて、他のサービスが続いて Google Cloud Platform になったような気がする1。 そんな歴史あるサービスだとレガシー感が漂っていそうなものだけど、全くそんなことはない。 2019 年の 2nd gen 化から改めて使ってみたところ、圧倒的に良くなっているし、今も一線で使えるサーバレス実行環境である。 ポートフォリオサイトの https://pokutuna.com/ も GAE だし、仕事でも社内用の小さなアプリケーションから、多少トラフィックのある API サーバーまで GAE でリリースしてきた。 アプリケーション実行環境の選択肢は色々増えたものの、今でも GAE のほうが楽に安くアプリケーションを構築できる状況や要件はよくある。そんな GAE のいいところや GAE が便利な状況について書いておきたい。 静的ファイルを配れる & エッジキャッシュが使える GAE では、静的ファイルのパスを app.yaml で指定することで静的ファイルを Google のエッジサーバーでキャッシュさせつつ配れる。アプリケーションからのレスポンスでは Cache-Control: public, max-age=3600 などヘッダに含めることでキャッシュさせられる。 アプリケーションの手前にリバースプロキシを置いて静的ファイルを返す構成はよくあるが、GAE は単体でそれ相当のことができる。小規模なアプリケーションでとてもありがたい。手動のキャッシュの破棄はできないが、設定不要の CDN が付いているのに等しい。 GAE がこの機能を持つのは、静的ファイルを返すことは Web アプリケーションの通常のユースケースだからだろう。 どちらも HTTP エンドポイントを実行するサービスだけど、GAE がユーザ向けアプリケーションを公開することに重心を置いているのに対し、Cloud Run はもっと広く Pub/Sub を受けたりジョブを実行したり非同期システムのランタイムを志向しているので、Cloud Run がエッジキャッシュをサポートしていないのもまあ納得できる。 Cloud Run で静的ファイル返したい場合 手前に Cloud Load Balancing を置いて Cloud CDN を有効にする Firebase Hosting で静的ファイルを配りつつ特定のパスを Cloud Run に向ける 別に Cloud Storage に上げて公開して URL を返す 諦めて Cloud Run のアプリケーション内から返す などが考えられる。 1 つ目の、手前に Load Balancing を置いて Cloud CDN を使うのが素直な構成だと思うけど、Load Balancing を立てているだけで月数十ドルかかる。事業でサービスを公開するなら安いコストだけど、個人開発や社内向けの小さなアプリケーションだと地味に払いたくないコストである。 費用を意識するならコンポーネントは増えるがここだけ Firebase Hosting を使うのが良いと思う。 Identity-Aware Proxy (IAP) が Load Balancing 無しに使える IAP を使うと、アプリケーションに手を加えず簡単に Google Workspace ドメインや、特定の Google アカウントに対してのみアプリケーションを公開できる。管理画面や、社内用アプリケーションを作る際によく利用する。 Cloud Run や GKE で IAP を使うためには、Cloud Load Balancing が必要なのだけど、GAE だけは単体で IAP を挟むことができる。特に社内向けアプリケーションは、営業時間中にまばらにトラフィックがあるだけなのに LB 立て続けるのはもったいない。GAE すればコストがタダに近くなる。 cloud.google.com プロジェクトの初めのうちはプロトタイプを IAP かけた GAE で開発しつつ、一般公開前に Cloud Load Balancing を立ててバックエンドサービスに GAE を指定して将来の構成の変更に対応しやすくする、というのもいいでしょう(ちょうど最近やりました)。 今は App Engine にロックインされない かつては、ローカルの開発時に dev_appserver.py とかいうよくわからんスクリプトを使う必要があったり、外部に HTTP リクエストを送るのに専用の urlfetch ライブラリを使う必要があったり、ライブラリを自由に入れられないので自分でアップロードしてインポートパスを通したりする必要があった。ロックインされるし、開発体験が良くなかった。 2nd gen になってからこれらの制約は無くなった。ふつうに書いた Web アプリケーションがそのまま動く。 1st gen は独自のサンドボックスでユーザのアプリケーションを分離していたのと、ユーザ認証からデータストア、タスクキューまで付いたオールインワンのアプリケーション実行環境として提供されていたのもあって、専用ライブラリを使ってね、としていたのだと思う。 2nd gen では、それら GAE にバンドルされていたサービスは各 Google Cloud プロダクトを利用して実装する形になった2。App Engine 特有の実装も不要になり、脱出も容易、つまり、安心して使えます。 cloud.google.com ランタイム選択フローチャート かつてこういう図が公式ドキュメントにあった。 (引用) Which serverless compute platform is right for you? の図 Choosing a Serverless Option  |  Serverless Guide  |  Google Cloud (Internet Archive) これをたどると、大半のユースケースで App Engine に辿り着かない? 僕はまず GAE で動かせないか検討して、言語がサポートされていないとか、追加で何かインストールしないといけない要件(Image Magick 要るとか)がある場合に Cloud Run を検討する、という感じでやっている。 過去には、やや複雑化してきた Cloud Function を GAE に置き換えたりもした。GAE は 0 台までダウンスケールできるし起動も早いし、新しいバージョンをリリースする際に段階的にトラフィックを移したり、前のバージョンに戻したりも楽ちん。Cloud Run でもよいけど、Cloud Functions で出来ていた程度のもののイメージを管理したくないという判断もあった。Cloud Functions gen2 はガワだけで中身は Cloud Run なので、今なら Run にするかな。 繰り返しになるけど、LB もいらず IAP もかけられるので、GAE はプロトタイプの開発にも向いていると思う。 まとめ GAE の楽さや安上がりな点について紹介しました。 こんなアプリケーションに集中できるいいプロダクトなのに公式の案内から消えていきつつある!! みんなが GAE でケチりながら激安アプリケーションをホストすると Google が儲からないので隠されているのだと思う。 このエントリで GAE が選択肢に上がるとうれしいです。 App Engine の中心的な考え方であるサーバーレス、サーバー管理不要、イベントドリブン プログラミング、リソースの使用量に応じた料金などは 10 年前から一貫しており、現在も当時と同様に当を得ています。 誕生から 10 年、App Engine の歩みを振り返って | Google Cloud 公式ブログ これかっこいい、おっしゃる通りです 関連エントリ blog.pokutuna.com blog.pokutuna.com Wikipedia(en) の Google Cloud Platform ページの最初の履歴は 2014 年で、記述を見るたぶん合ってるのではないか https://en.wikipedia.org/w/index.php?title=Google_Cloud_Platform&oldid=602909799↩ Google Cloud が提供していないものもあるけど...↩

  • ぽ靴な缶

    2022-10 の Cloud Storage 料金改定に伴い GCR から Artifact Registry へ移行する

    Google Cloud で運用しているサービスの Cloud Storage 費用が10月の料金改定から爆増していた。 Cloud Storage 費用(オレンジ部分)が増加 料金改定のタイミングで Cloud Storage のマルチリージョンからマルチリージョン内のリージョンへの転送費用が無料じゃなくなっていた。 Docker イメージの転送費用によるものであれば、Container Registry から Artifact Registry へ移行することでこの費用は無にできる。 cloud.google.com 無料条件がなくなった Google Cloud 内の下り(外向き)ネットワーク費用を見る。 Internet Archive に残っている過去の料金表(2022-05-01)には以下の記述があった。 マルチリージョンにある Cloud Storage バケットからある 1 つのリージョンにある別の Google Cloud サービスへのデータの移動で、両方のロケーションが同じ大陸にある。 無料 現行は、この無料条件がなくなっているうえに、 $0.08/GB とまずまず高めの値段設定になった。 同じ大陸内の異なるロケーション間でデータを移動する場合、転送元バケットは ASIA マルチリージョンに配置され、上記の無料ケースのいずれも適用されない。 $0.08/GB cloud.google.com Container Registry (GCR) のコンテナイメージは Cloud Storage のマルチリージョンバケットに保存され、イメージを利用する実行環境は何らかのリージョンにあるので、この条件にあたってしまう。 今まではイメージと実行環境のロケーションを合わせていれば無料で使えたが1、一通りマルチリージョンバケットからの転送に費用がかかるようになってしまった現在はもう無料で使うことはできない!! asia ほどの費用にはならないが、gcr.io から us 内への転送も $0.02/GB と、無料ではなくなっている。 Artifact Registry を使う Container Registry (GCR) より後に公開された Artifact Registry。 Maven や npm モジュールなどもホストできる。 cloud.google.com 移行するモチベーションは特になかったけど、今回の費用改定で明らかにメリットが生まれてしまった。 Artifact Registry はアーティファクトを保存するリポジトリのロケーションを選ぶことができる。実行環境と同じロケーションにイメージを置くことで、Cloud Storage のネットワーク費用を無料にすることができる!! 移行する作業は特に難しくなく、ドキュメントで移行について案内されている。 cloud.google.com アクセス権限周りに大きな変更があったが、困るようなことはなかった。 GCR 時代のアクセスコントロールは Cloud Storage の IAM ロールでやる感じで、おおざっぱだし分かりづらかったけど、Artifact Registry ではそれ用のロールが設けられプロジェクト単位でも個別のリポジトリに対しても権限を設定できる。 実際の作業としては、API を有効にし、Artifact Registry にリポジトリを作って、GCR に置いてあるイメージを Artifact Registry Registry に上げなおして、k8s manifest やデプロイコマンドなど各所の image 指定を更新する程度でした。 これでグラフの右端のように、また Cloud Storage 費用を無にできたわけです。 今回の値上げといい、ドキュメントの記述といい、かなり Artifact Registry への移行を促してる感ありますね。 Container Registry の進化形である Artifact Registry は、 https://cloud.google.com/artifact-registry?hl=ja Container Registry は引き続き使用可能で、Google Enterprise API としてサポートされていますが、新機能は Artifact Registry でのみ利用可能です。Container Registry には、重要なセキュリティ修正のみ与えられます。 https://cloud.google.com/artifact-registry/docs/transition/transition-from-gcr Google Cloud のドキュメント中の "大陸" (continent に対する訳) って独特の概念だよね、ASIA マルチリージョンの各所は海で隔てられている(台湾, 香港, 東京, ムンバイ, ...)2ものの、同じ文脈で大陸として出てくる "US" や "EU" と同じ扱いであったりもするわけで。でもある日 ASIA は大陸じゃありませーんと言われてもしょうがない気もするし。 https://blog.pokutuna.com/entry/gke-autopilot-storage-egress↩ https://cloud.google.com/storage/docs/locations#available-locations↩

  • ぽ靴な缶

    gcloud の configurations を切り替える

    前回の記事では --project を毎回渡せという主張を展開していたけど切り替える話。 blog.pokutuna.com gcloud コマンドには構成を管理するサブコマンド gcloud config configurations がある。管理するプロジェクトが多くない場合は、カレントプロジェクトを設定しつつ切り替える運用でもよいのではないでしょうか。 また、複数の Google アカウントを切り替える場合も configuration を作って切り替えるのがいい。カレントプロジェクトは設定しない派だけど、個人の @gmail.com と勤務先の Google Workspace のログイン状態を切り替えるのに使ってる。 ちなみに configurations を切り替えても ADC はそのままで、最後に gcloud auth application-default login した時点の認証情報から変わらないのが注意ポイント。 gcloud config configurations Cloud SDK 構成の管理 | Cloud SDK のドキュメント | Google Cloud 触ってみないと微妙に分かりづらいけど、Google アカウントやカレントプロジェクトなど一連の設定を 1 つのエントリとしてまるっと切り替えることができる。 "プロジェクトを切り替えることができる" と説明されていたりするけど、Google アカウントを含む一連の構成を切り替えると思っておかないと、 gcloud config set project でプロジェクトを切り替えたり、ログインし直したりしているとよく分からなくなる。 プロジェクトを切り替えるには、同じ Google アカウントでログインした複数の構成を作って、別々のカレントプロジェクトを設定しておいて、それらを切り替えるという感じ。 # configuration の一覧 $ gcloud config configurations list # configuration を作る & 同時にその設定名がアクティブになる $ gcloud config configurations create NAME # configuration に設定する $ gcloud init # 最初から $ gcloud auth login --project=PROJECT_ID # ログインしてプロジェクト ID 設定する $ gcloud config set project PROJECT_ID # プロジェクト ID だけ設定する $ gcloud config set compute/region REGION # region $ gcloud config set comute/zone ZONE # zone # NAME の設定に切り替える $ gcloud config configurations activate NAME 例のように、region や zone も保存しておけるので、Compute Engine などこれらの引数を要求するコマンドをよく使うなら、設定してあるとちょっと楽になる。 gcloud config に設定できるもの 先に挙げたものが config に設定できるものとしてメジャーだけど、他にもいろんな設定を保存できるし、configuration で切り替えられる。 例えば以下のように設定しておくと、Cloud Functions に新しい関数をデプロイする際に region を省略しても asia-northeast1 になる。 $ gcloud config set functions/region asia-northeast1 設定可能な項目はドキュメントにちゃんとまとまってある。 gcloud config | Google Cloud CLI Documentation あるいは json や yaml で出力してみると雰囲気が分かっておもしろい。 $ gcloud config configurations list --format=json accessibility/screen_reader を true に設定すると gcloud の出力がスクリーンリーダーフレンドリーになったり、core/log_http すると gcloud の API リクエストとレスポンスが出力されたりして面白いですね。 fzf や peco で切り替える よくあるやつ。fzf でも peco でも動くので読み替える。 gcloud-switch() { local selected=$( gcloud config configurations list --format='table[no-heading](is_active.yesno(yes="[x]",no="[_]"), name, properties.core.account, properties.core.project.yesno(no="(unset)"))' \ | fzf --select-1 --query="$1" \ | awk '{print $2}' ) if [ -n "$selected" ]; then gcloud config configurations activate $selected fi } gcloud にはグローバルな `--format=NAME[ATTRIBUTES](PROJECTION) オプションがあって、単体で出力をかなり加工できる。他のツールと組み合わせるときに使うとかわいいですね。 gcloud topic formats | Google Cloud CLI Documentation gcloud topic projections | Google Cloud CLI Documentation あるいは direnv を使っている場合は CLOUDSDK_ACTIVE_CONFIG_NAME 環境変数で切り替えることもできる。チームで configuration 名をプロジェクト名にしてリポジトリに入れたりするのもよいかもしれません。 Cloud SDK 構成の管理 | Cloud SDK のドキュメント | Google Cloud

  • ぽ靴な缶

    gcloud にカレントプロジェクトを設定しない派

    gcloud CLI にカレントプロジェクトをなるべく持たせないようにして暮らしている。 gcloud はデフォルトでカレントプロジェクトのリソースを操作する。操作するプロジェクトが 1 つなら良いけど、仕事でも遊びでもいくつもの GCP プロジェクトを扱っているので、うっかり異なるプロジェクトのリソースを操作してしまったり、意図しないプロジェクトに費用が計上されてしまうのが嫌だから。 カレントプロジェクトは設定しないようにして、gcloud を使う時は都度 --project=PROJECT_ID で渡すようにしている。 # カレントプロジェクトを確認するには以下のコマンドなど $ gcloud config get-value project $ gcloud config list # カレントプロジェクトの設定を消す $ gcloud config unset project ローカルの ADC の quota project 忘れられがちだけど、ローカルの Application Default Credentials にもカレントプロジェクトに相当する "quota project" がある。 ADC についてはこちら blog.pokutuna.com ADC の quota project は、gcloud auth application-default login した時点のカレントプロジェクトが設定される。 ~/.config/gcloud/application_default_credentials.json を見ると分かるし、ログイン時のメッセージにも出てくる。 Credentials saved to file: [/Users/pokutuna/.config/gcloud/application_default_credentials.json] These credentials will be used by any library that requests Application Default Credentials (ADC). Quota project "pokutuna-playground" was added to ADC which can be used by Google client libraries for billing and quota. Note that some services may still bill the project owning the resource. 普段からカレントプロジェクトを設定しないようにしていると気にしなくて良いが、unset したり切り替えたりしていると gcloud のカレントプロジェクトと ADC の quota project が異なる状態になるのがややこしい。 なのでこれも設定しないようにしている。 カレントプロジェクトを ADC に伝播させたくない場合は ADC ログイン時に --disable-quota-project オプションを使う。 $ gcloud auth application-default login --disable-quota-project ADC に quota project を設定しない場合、以下のような警告を見ることになるけど、アプリケーションコードからプロジェクト ID を与えればよいので気にしない。 WARNING: Cannot find a quota project to add to ADC. You might receive a "quota exceeded" or "API not enabled" error. Run $ gcloud auth application-default set-quota-project to add a quota project. ADC にプロジェクト ID を持たせない暮らし ADC に quota project を設定しない場合、アプリケーションコード中にプロジェクトIDが登場することになるけど、意図しないプロジェクトを操作してしまう危険を避けることを優先している。 認証情報はメンドイので ADC に解決してほしいが、プロジェクト ID まで暗黙に解決したいことはほぼないし、複数のプロジェクトで同じコードを実行する場合でも、設定や環境変数などでアプリケーションに伝えればいいという考え。 GCP 上の実行環境でも、実行環境とプロジェクト ID が異なってないなら問題はない。 Node Google Cloud の各種プロダクトに用意されたクライアントライブラリはコンストラクタに渡せばいい。 // Imports the Google Cloud client library const {BigQuery} = require('@google-cloud/bigquery'); const client = new BigQuery({ projectId: "<PROJECT_ID>" }); Spreadsheet など、Google Cloud 感ないものは GoogleAuth に渡す。Spreadsheet や Calendar なども API を有効にしたり使用量を管理するために Google Cloud プロジェクトが必要。 googleapis/google-api-nodejs-client import { google } from "googleapis"; const auth = new google.auth.GoogleAuth({ projectId: "<PROJECT_ID>", scopes: [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spreadsheets.readonly", ], }); const sheets = google.sheets({ version: "v4", auth }); Node の場合、明に指定しない場合は google-auth-library がプロジェクト ID を解決しようとする。その過程で GCLOUD_PROJECT や GOOGLE_CLOUD_PROJECT 環境変数を参照したり、gcloud のカレントプロジェクトを参照したりする(歴史的経緯だろうけど、この挙動が嫌だなあ)。 Go Go でも Google Cloud 系のクライアントライブラリでは素直に渡せばいい。 googleapis/google-cloud-go import ( "context" "cloud.google.com/go/bigquery" ) func main() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "<PROJECT_ID>") ... } Google Cloud 感のないものは google.golang.org/api を使うことになるが、こちらは option.WithQuotaProject() を使う。google.golang.org/api 以下でほぼすべての Google の API を叩けるので、Cloud API もこちらの方法で叩ける。 googleapis/google-api-go-client import ( "context" "google.golang.org/api/option" "google.golang.org/api/sheets/v4" ) func main() { ctx := context.Background() client, err := sheets.NewService(ctx, option.WithQuotaProject("<PROJECT_ID>")) ... } まとめ いろんなプロジェクトを触る場合は gcloud にカレントプロジェクトを設定しないのをおすすめしている ローカルの ADC も quota project があり、ログイン時のカレントプロジェクトが引き継がれる、これも設定しないのがいい アプリケーションコードでプロジェクト ID を明に指定すればいい blog.pokutuna.com

  • ぽ靴な缶

    GCP IAM ロールの持つ権限を比較するテク

    メンバーやサービスアカウントの権限を考える際に、ロールの持つ権限を比較したいことがしばしばある。そういう時は gcloud と diff を使うことで比較できるという素朴なテク。 ロールと権限 ロール(role)は roles/{roleName}, roles/{service}.{roleName} などで表され、許可されている操作を表す権限(permission)の集合である。 例えば BigQuery データ閲覧者 (roles/bigquery.dataViewer) は、以下の permission を持つ。 bigquery.datasets.get bigquery.datasets.getIamPolicy bigquery.models.export bigquery.models.getData bigquery.models.getMetadata bigquery.models.list bigquery.routines.get bigquery.routines.list bigquery.tables.createSnapshot bigquery.tables.export bigquery.tables.get bigquery.tables.getData bigquery.tables.getIamPolicy bigquery.tables.list resourcemanager.projects.get resourcemanager.projects.list cloud.google.com ロールの比較 個別のロールと権限について確認したいときは以下のドキュメントを見る、GCP 屈指の縦に長いページ role から permission Understanding roles | IAM Documentation | Google Cloud permission からそれを持つ role IAM permissions reference | IAM Documentation | Google Cloud role をいじっていると以下のような疑問が湧いてくることがある。 roles/bigquery.dataViewer と roles/bigquery.metadataViewer ってテーブルのデータ読める以外に何が違うんだっけ? roles/browser と roles/resourcemanager.folderViewer ってどう違うんだっけ? roles/editor は強い権限だけど、意外と SecretManager で出来ない操作あった気がする 上のドキュメントを行ったり来たりしてもいいけど、* でサービス内の個別の permission が省略されていたりするのでいまいち分からないし大変。 diff で比較する そういう時は gcloud コマンドで role の permission を得つつ、diff で比較するとよい $ gcloud iam roles describe ROLE で権限のリストが得られるので、これを diff -y で左右に並べる。 roles/bigquery.dataViewer と roles/bigquery.metadataViewer の違いは、 $ diff -y -W80 <(gcloud iam roles describe roles/bigquery.dataViewer) <(gcloud iam roles describe roles/bigquery.metadataViewer) description: Access to view datasets | description: Access to view table and etag: AA== etag: AA== includedPermissions: includedPermissions: - bigquery.datasets.get - bigquery.datasets.get - bigquery.datasets.getIamPolicy - bigquery.datasets.getIamPolicy - bigquery.models.export < - bigquery.models.getData < - bigquery.models.getMetadata - bigquery.models.getMetadata - bigquery.models.list - bigquery.models.list - bigquery.routines.get - bigquery.routines.get - bigquery.routines.list - bigquery.routines.list - bigquery.tables.createSnapshot < - bigquery.tables.export < - bigquery.tables.get - bigquery.tables.get - bigquery.tables.getData < - bigquery.tables.getIamPolicy - bigquery.tables.getIamPolicy - bigquery.tables.list - bigquery.tables.list - resourcemanager.projects.get - resourcemanager.projects.get - resourcemanager.projects.list - resourcemanager.projects.list name: roles/bigquery.dataViewer | name: roles/bigquery.metadataViewer stage: GA stage: GA title: BigQuery Data Viewer | title: BigQuery Metadata Viewer ほうほう、roles/bigquery.dataViewer はテーブルやモデルのスナップショットやエクスポートも取れるんですね。 includedPermissions 以下だけ欲しいなら --format オプションで中身だけ取ることもできる。 --format='value[delimiter="\\n"](includedPermissions)' gcloud の format オプションについてはこちら。 roles/browser と roles/resourcemanager.folderViewer の違いは、 $ diff -y \ <(gcloud iam roles describe roles/browser --format='value[delimiter="\\n"](includedPermissions)') \ <(gcloud iam roles describe roles/resourcemanager.folderViewer --format='value[delimiter="\\n"](includedPermissions)') > orgpolicy.constraints.list > orgpolicy.policies.list > orgpolicy.policy.get resourcemanager.folders.get resourcemanager.folders.get resourcemanager.folders.list resourcemanager.folders.list resourcemanager.organizations.get < resourcemanager.projects.get resourcemanager.projects.get resourcemanager.projects.getIamPolicy < resourcemanager.projects.list resourcemanager.projects.list フムフム。 多くの permission を持つ権限なら比較したい部分で grep すればいいですね。 roles/editor のうち、SecretManager で、roles/secretmanager.admin より弱いのは、 $ diff -y <(gcloud iam roles describe roles/editor | grep secretmanager) <(gcloud iam roles describe roles/secretmanager.admin | grep secretmanager) - secretmanager.locations.get - secretmanager.locations.get - secretmanager.locations.list - secretmanager.locations.list - secretmanager.secrets.create - secretmanager.secrets.create - secretmanager.secrets.delete - secretmanager.secrets.delete - secretmanager.secrets.get - secretmanager.secrets.get - secretmanager.secrets.getIamPolicy - secretmanager.secrets.getIamPolicy - secretmanager.secrets.list - secretmanager.secrets.list > - secretmanager.secrets.setIamPolicy - secretmanager.secrets.update - secretmanager.secrets.update > - secretmanager.versions.access - secretmanager.versions.add - secretmanager.versions.add - secretmanager.versions.destroy - secretmanager.versions.destroy - secretmanager.versions.disable - secretmanager.versions.disable - secretmanager.versions.enable - secretmanager.versions.enable - secretmanager.versions.get - secretmanager.versions.get - secretmanager.versions.list - secretmanager.versions.list > name: roles/secretmanager.admin roles/editor でも、secret に IAM Policy を設定することと、実際の version の読み取りができないのだな〜ということが分かる。 gcloud と diff を使うとこういう感じで比較できます。 適切なロールを選ぶとともに、IAM の推奨事項を見て絞ったりできるとよりよいですね。 cloud.google.com

  • ぽ靴な缶

    3/17 Born Digital Summit 2022 で発表します

    来週 2022-03-17(木) の Google Cloud オンラインイベント 16:20- 『はてな広告配信システムのクラウドネイティブ化への道のり』で発表します。 データセンター環境で運用していた広告配信システムを GCP へ移転する話です。 派手なメッセージな感じではなく、約1年のプロジェクトの中での採用技術やテクについて紹介する風情の発表になります。EOL 過ぎたソフトウェアたちをまるごとマネージド化し、Elasticsearch を BigQuery に置き換える様子などをご覧にいただけます。 たぶん登録しておけば後日動画で見れると思います。 cloudonair.withgoogle.com 笑顔の写真は締め切り当日にがんばって撮りました。

  • ぽ靴な缶

    Google Colaboratory でデータフローのドキュメントを書く試み

    この記事ははてなエンジニアのカレンダー | Advent Calendar 2021 - Qiita 2日目の記事です。 最近、データパイプラインの整備や営業チームの人力混じりの運用フローを機械化するなどの業務改善に取り組んでいます。 その過程で、運用ドキュメントを読んだりヒアリングして図を描くことがよくあります。 描いた図をもとに「この流れであってますか?」と確認したり「ここ手間結構かかってそうですが困ってませんか?」とコミュニケーションをします。暗黙的な業務の流れが明確になるだけでなく、改善点の発見にも繋がります。 ひととおり改善タスクが終わった後にも図を最新にします。ドキュメントと併せて成果物とします。 どんなデータがあってどのようにビジネスに使われているか、データがどのように取得&保存されているかを残しておくのは今後のデータ活用や改善のためにも必要です。 俺はそんな個々の業務のデータフロー図を描いていって、やがてはおっきなエンタープライズデータモデルを絵にしたいんだ。 でも図やドキュメントを書いていく上で様々な悩みがある!! GUI 作図ツールを使う データフロー図を描くために、draw.io や Cacoo といった作図ツールを使ったり、Google スライド や miro といったスライドツールやホワイトボードツールを使う選択肢がある。 ツリーやダイアグラムを作るためのパーツが用意されていたり、リアルタイム同時編集できるものも多く複数人での認識合わせにも使えて大変便利だけど、いろいろ不満もある。 レイアウトにこだわりがち 自由な絵が描けるのはよいけど、レイアウトに結構な時間を使ってしまう。 ボックスの大きさは揃っているほうがよいしX軸Y軸のアラインを揃えたい、矢印は交差してほしくないし、矢印やボックスの形に一貫した意味が欲しい...とやっていると必要以上に時間を使っていることに気づく。 きれいな図は理解を助けるけど、一世一代のプレゼンテーションでもないのにこだわりすぎるのも無駄が多い。 とはいえある程度は整えないと読み解くのにストレスがあり、ちょうどよい塩梅が難しい。 一貫したルールがないと複数の図を並べた時にもごちゃごちゃした印象になってしまう。 その他いろいろ ドキュメントと別の所にあるので更新されなくなりがち えてして検索性が悪がち 画像として書き出したりスクリーンショットを撮ってドキュメントに移すのがダルいがち やる気のある1人だけがメンテナンスする羽目になりがち 差分管理できながち 図を作る部分の体験はよいけど、その図をどう運用していくか...というところで悩みが出てくる。 Graphviz や PlantUML を使う Graphviz、PlantUMLで図を書く手もある。 普段のテキストエディタで書けて一定のクオリティの図が作れるので重宝している。 レイアウトも多少意識する面はあるものの細かく手をいれられないので適度に妥協できるのも逆に良い点。 社内 Wiki にドキュメントを書く時に、ページ下の方にソースを貼り付けてドキュメントと図のソースの距離を近くすることもできる。 一方で満たされない思いもある。 記法の学習コストがあるがち リポジトリに入れると権限が必要だったりしがち 特に営業チームのメンバーが利用したい時に困りがち 巨大な図を作るとメチャクチャになりがち ドキュメント ここまで図の話をしてきたけど、実際にはドキュメントの一部として図を描きたい。 この業務の背景や目的、関連するドキュメントやダッシュボードへのリンク、新たにデータを利用する際の方法、実装を行っているリポジトリ、権限や窓口、データの更新頻度や扱う諸注意...などなど、図だけで説明しきるのは難しくて、ある程度文章で説明することになる。 ドキュメントを作ってメンテしていく上で、もっとドキュメントと図を近づけたい。 Google Colaboratory でドキュメントを書く Colaboratory は Google の提供する Jupyter Notebook & Python ランタイム。 これを使ってドキュメントを書くのはどうか、というのが今回の試みです。 データを扱うエンジニアには Jupyter はお馴染みだろうから親和性も高い。 Colaboratory へようこそ - Colaboratory やってみます データフローとドキュメント Google Colaboratory でデータフローのドキュメントを書く試み - Colaboratory いかがでしょうか。 果たしてまな板やすし桶はデータストアなのか、これはデータフローなのか、寿司酢を入れなくてよいのか、異論はあるだろうけどデータフロー図とドキュメントを書くことができた。 Colab を使うと 図のソース置き場と表示をどちらも満たせる Markdown を使ってドキュメントを書ける 環境構築にあまり煩わされない BigQuery など実際のデータにアクセスしてサンプルデータを表示したり可視化できる Google アカウントによる権限管理ができる Google Drive 検索にひっかかる 変更履歴が残り古い版に戻せる これらのいいことがある。 やっていること 依存のインストール ! に続けてコマンドを打つことでシェルで実行される。 !apt や !pip で依存を入れることができる。 これをコピペして使っている #@title !pip install graphviz plantuml fonts-noto-cjk #@title は後述 graphviz, plantuml をよく使う fonts-noto-cjk 日本語フォントに Noto Sans Japanese を入れる 入れないと図中に日本語が表示できないことがある 他のフォントウェイトは fonts-noto-cjk-extra にあるけど大きめなので使ってない fonts-ipafont とかでも良いと思います Graphviz や PlantUML のソースを置く %%writefile {filename} から始まるセルを評価すると、以降の内容が filename に保存される。 Python コードで open して文字列を書いている例がよくあるけど、特定のテキストをファイルに書きたいだけならマジックコマンドを使うのが簡単。 Built-in magic commands — IPython 7.30.0 documentation 画像の生成 & 表示 単に Graphviz や PlantUML で画像を作って表示する !dot -Tpng my-flow.dot > my-flow.png # graphviz !plantuml my-flow.puml # plantuml from IPython.display import Image Image('my-flow.png') 一旦完成したらコードを非表示にする ドキュメントとして見せるにはコードを非表示にしておくほうが見栄えがいい。 メニューの "表示" からコードを非表示にするとセルを折りたたむことができる。 非表示にするとセルの先頭に #@title が挿入されるのは、フォームから変数に値を入れる機能を転用して非表示を実装しているからのようだ。つまりメニューを経由しなくてもセルの先頭に #@title を書いて右側の空白をダブルクリックしてもよい。 Forms - Colaboratory 感想 どうでしょうか、Colab にドキュメントを書くのはまだお試し中ですが、悪くない気がします。 特に、ちょっとラベルを変えたり 1~2本フローを増やしたりなどの微修正は画像を生成して Wiki に貼り付けたり、リポジトリにコミットする必要もなくて気楽にできます。 コードセルを非表示にしていても余白ができるのでがちゃがちゃした見た目になりがちだったり、Colab に詳細めなドキュメントが描いてあるという期待がないので社内 Wiki からリンクしていても読まれにくい、という点は気になる。 データアーキテクチャを図にしたりドキュメントにする良いツールやプラクティスがあれば教えて下さい。 アドベントカレンダーについて はてなエンジニアのカレンダー | Advent Calendar 2021 - Qiita 前日は id:nanto_vi による HTMLのdialog要素とフォーム機能 - Hatena Developer Blog でした。 明日は id:gurrium さんの WoTのMODを作りたい - ぜのぜ です。 参考 データフロー図 - Wikipedia DFD(データフロー図)ってなに?DFDの概要と書き方をあわせて紹介 | Cacooブログ