/// BANGBOO BLOG ///

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

May 20, 2021

GCP
■GCP(Google Cloud Platform)
https://console.developers.google.com/
GCPを活用するスキルを問われる「Associate Cloud Engineer」
インフラストラクチャの知識を問われる「Professional Cloud Architect」
データと機械学習の知識を問われる「Professional Data Engineer」
 マシーンラーニング:教師ありをベースにパターンを線形として認識し相似のパターンを見つける
 ディープラーニング:人間が把握できる次元のデータ構造ではない多次元でパターンを見つける
  線形検索みたいなもんか

■GCP
https://techblog.gmo-ap.jp/category/gcp/
https://tech.zeals.co.jp/entry/2019/01/08/094054
https://techblog.gmo-ap.jp/category/tensorflow/

情報源
Solution Design Pattern (gc-solution-design-pattern.jp)
google-cloud-jp – Medium
サポートを付けるとGoogleに聞き放題になったりする
 サポートのケースは組織レベルでみると全プロジェクトのケースが見れる

3か月間300 ドル分だけ無料
https://console.cloud.google.com
無料枠
GCE:プリエンプティブル以外の1つの以下のe2-micro VMインスタンスと30GB/月の標準永続ディスク
 オレゴン: us-west1
 アイオワ: us-central1
 サウスカロライナ: us-east1
GCS: 5GB/月のRegional Storage(米国リージョンのみ)

無料だとBigQueryのDML(insert)ができないらしい
予算とアラートを1円で設定(通知チャネルにSMSとメール設定)
 月額のプロダクトを日割レポートで見ると2月の日割りは高く見え、3月は安く見える
 為替の影響は月初から適応されるので円安だと高いよ

辞めるときはプロジェクトをシャットダウン&請求先アカウントの閉鎖
1)プロジェクトの閉鎖
Google Cloud Console > IAMと管理 > 設定 > シャットダウン
2)請求先アカウントの閉鎖(原因不明だが下記画面が出るときと出ないときがった)
Google Cloud Console > お支払い > (左ナビ)アカウント管理 > 請求先アカウントの閉鎖
※お支払い>マイプロジェクト>アクション>無効や請求先変更ができる

セキュリティは使用GoogleアカウントのSMSによる2段階認証、信用するデバイスの設定があるようだ

 GKE, Cloud SQL, Dataflow等
【GCP入門編・第3回】難しくない! Google Compute Engine (GCE) でのインスタンス起動方法! | 株式会社トップゲート (topgate.co.jp)
【GCP入門編・第12回】 BigQuery を使って気軽にビッグデータの解析を行ってみよう! | 株式会社トップゲート (topgate.co.jp)
【GCP入門編・第25回】 Cloud SQL for MySQL で Master-Slave 構成を組もう! | 株式会社トップゲート (topgate.co.jp)
【GCP入門編・第29回】Cloud Load Balancing で Web アプリケーションにロードバランサーを設定する | 株式会社トップゲート (topgate.co.jp)
【初心者】GCP Identity-Aware Proxy (IAP), Access Context Managerを使ってみる (WEBサーバへのアクセス制限) - Qiita

■IAM(Identity and Access Management) 
https://cloud.google.com/iam/docs/overview?hl=ja
https://cloud.google.com/iam?hl=ja
IAMベストプラクティス https://cloud.google.com/iam/docs/using-iam-securely
操作方法 https://cloud.google.com/iam/docs/how-to?hl=ja
ロール https://cloud.google.com/iam/docs/understanding-roles?hl=ja
https://www.isoroot.jp/blog/1244/
https://medium.com/google-cloud-jp/gcp-iam-beginner-b2e1ef7ad9c2

//IAMの機能(RBAC認可:role based access control)
機械学習を使ったスマート アクセス制御の最適化
デバイスのセキュリティ、IP アドレス、リソースタイプ、日時などの属性に基づいて、リソースに対するきめ細かいアクセス制御ポリシー
権限の認可、解除、委任に関するすべての監査証跡の履歴
ユーザーとグループのプロビジョニングや管理、シングル サインオンの設定、2 要素認証プロセス(2FA)

//IAMポリシー
IDをGroup(●●部)にアサイン
 Members(Group等)にRoles(●●役)をアサイン
  MembersとはグループやドメインやID(Googleユーザアカウント、サービスアカウント)
 Roles(●●役)にPermissions(権限)を付与

ロールは作成ができ●●世話役みたいな感じか
permissionsは権限で「resourcemanager.projects.get」等でロールに紐づける
 個人や無料アカだと組織がない?→フォルダが作成できない?
 組織がないとグループが作成できない→グループがないとIDにRoleを付与するしか
フォルダは組織ツリー状でリソース管理、組織改編が多いならプロジェクトフォルダでも
 各フォルダに対してそれぞれメールグループを定型(folder-admin/dev/lead/member/parttime/etc)で持たせ
 メールグループへのユーザ出し入れで権限の管理をするのが良さそう
IAMやServceAccountの一覧には出てこないが存在するIDがある、実際に権限を付与できるかで存在確認する(TFで作成の場合?)
ポリシーはMSのGPOみたいものも組み込みで存在する
サービスアカウントはAPI用、人が使うことは基本想定されていない(impersonate等できるが
ユーザが削除になっても権限やリソースは残る?30日位はdeleted:になって消えるのでは
プリンシパルには@gmail.comのGoogleアカウントやWorkspace契約のある組織ドメインのGWSアカウント等があり、独自ドメインでもGWS契約がない場合は@gmailのように登録しGoogleアカウントにして使用する
GCPはGWS gmailメールの変名に追従して権限も付与状態も変化がなく問題がない
 しかしterraformは追従しないためtfファイルでメールを使っている場合は変更する
外部ドメインのユーザの場合はメールグループ単位でのロール付与が効かず個別アカウントで付与する必要がある?あるいは組織ポリシーを開けっ放し?
APIを有効化せんと何もできないが、するロール roles/serviceusage.serviceUsageAdmin

メールグループの権限関係の確認方法
 仕組み:祖->親->子、上の権限は下も持つ
 権限から確認する、所属から確認するの両面で確認
 1)権限を持っている全ての子をリストアップ
 2)所属しているメールグループの全ての親をリストアップ

//画面上部のプルダウンからプロジェクトを選択できない場合
(BQのデータセットにのみ権限がある等)
1)BQの左ペーンでデータセット名を検索し(すべてのプロジェクトを検索するため2回必要)スターを付けて代替とする
2)データセットレベル権限でもURLパラメータ付きだと選択ができる
http://console.cloud.googl.com/bigquery?project=bangboo-kuso-project
3)IAMの画面で何かしらresourcemanager.projects.listを含むロール、つまりBQ data viewerでOKだがプロジェクトレベルの権限を付与しておく(権限付与後にログインしなおしが必要)
※jobuserがないとBQコンソールでプルダウンできない訳ではない(jobuserなしでOK)
※グループメールの深い階層で付与されていても影響はしない

//リソース
階層:Organization > Folders > Project > Resource(Google Cloud services)
割り当て:日や分に対してのデータ量の上限等を設定

必要以上に権限を付与しない
組み込みロールが多い、改変してロールを作るか
権限はサービス名.リソース.動詞という命名規則
プロジェクト名はGCPグローバルで名前空間を共有しており、企業名等でprefixするのがいい
プロジェクト毎にメールグループを設け、権限はメールグループの参加で管理したい

//リージョンとゾーン
リージョン:データセンターの存在場所、ゾーンをいくつか持つ
ゾーン:障害ドメイン区画(単一障害点を避ける形で環境設計したい)
Google Cloud SDKをインストールすればコマンドラインが使える
 BQは同一リージョンでないとJoinができない、ゾーンはマルチで良い
APAC: asia-east(台湾、香港)、asia-northeast(日本、韓国)、asia-south(インド)、asia-southeast(シンガポール、インドネシア)、australia-shoutheast(オーストラリア)
NA: northamerica-northeast(モントリオール、トロント)、us-central(アイオワ等)、us-east(バージニア等)、us-west(ネバダ等)
リージョンとゾーン  |  Compute Engine ドキュメント  |  Google Cloud

//サブネット、Shared VPC
Shared VPCホストプロジェクトに対しサービスプロジェクトを設定しプロジェクト間を共有
サブネットは通常リージョン内?レガシーだと完全に仮想で自由なサブネット?

//Cloud Shell
Google Cloud Shell の 10 の知っておくと便利な Tips | Google Cloud Blog
ファイルのアップロードやダウンロードが可、コードエディタもありブラウザで完結
Webアプリのプレビューも可
 f1-microのGCE一時インスタンスがプロジェクトをまたいだ永続ディスク5GBで起動されている
 gcludやdocker,bash,sh,vim,nano,pip,git,mysql等がプリインスコされている
  5GBあるのでインスコもできる sudo apt-get install gawk
 Cloud Shell VM の Zoneを知る:curl metadata/computeMetadata/v1/instance/zone
 Ctrl + b キーを押してから % キーを押すとtmux により ウィンドウが左と右のペインに分割
Cloud shellのグローバルIPを取得できる
 curl http://ifconfig.me/

リスト一覧を出すgcloud cmd
gcloud projects list --filter='bangboo-' --format=json | grep -oP '(?<="name": ")[^"]*'

どのgcloud cmdにも使えるワイルドフラグ
--access-token-file, --account, --billing-project, --configuration, --flags-file, --flatten, --format, --help, --impersonate-service-account(人がcmdを打つ場合でも成りすませる、その人にprjレベルの権限が必要), --log-http(cmdでエラーがでるならコレを、詳細が出る), --project, --quiet, --trace-token, --user-output-enabled, --verbosity

各言語でのSDKを使ったプログラムを実行する際の認証を得るために使います
gcloud auth application-default login
ローカルで以下のようなGCP系CLIを実行する際の認証を得るために使います
gcloud config configurations list
gcloud config configurations create unko-profile
gcloud config set account unko@dot.com
gcloud config set project onara-project
gcloud config configurations activate unko-profile
gcloud auth login

■GCE
 Marketplaceを使えばアプリを数クリックでデプロイできる
 永続ディスク…NWストレージ、SSD永続ディスクも選択できる
 ローカルSSD…高性能、永続ではなく一時的
 非マネージドインスタンスグループ インスタンスをIGに紐づけるだけ
 ステートレスMIG 自動スケーリング(Webフロントエンド等)
  スケジュールでもスケーリングできる(cronや予測も)
 ステートフルMIG 設定を保持可(DBやデータ保持必要なstatefulなアプリ等)
  インスタンス名やIPやディスクやメタを維持する、部分的に外部化ステートレスにして自動化等も
 ゾーンMIG=シングルゾーン、リージョンMIG=マルチゾーン(最大3ゾーン)
 プリエンプティブは24時間までだが20%課金だけで安い

インスタンスにサービスアカウントを改めて設定するとGoogleAPIはこれで実行される
 改めて設定しないとデフォルトSA
 操作自体はSSHで入るユーザで操作をする
  設定はsudoして行うことが多く例えばcronはroot実行になっている
  SSHで入ったユーザで設定するなら所有者/グループ/他のパーミッションを設定した上で

■マネージドクラウドDB各種
ホワイトペーパーPDF

■Bigquery
/// BANGBOO BLOG /// - BigQuery
/// BANGBOO BLOG /// - GCP ログ調査 Logging/Bigquery information schema

■GCS
 http(s)で公開可(そもそも公開しているがAllUsersやAllAuthenticatedUsersや各ユーザに権限がついていないだけ)
 Nearline…3カ月でアクセス等(全ファイルを1度閲覧)
 Coldline…1.5年でアクセス等長期アーカイブ
 (standard以外は最低保存期間の縛りがあり早期削除でもお金が掛かる)
 Multi-regional 99.95%、Regional 99.9%の可用性
  BigqueryからGCSにエクスポートできるが1GBまで
料金  |  Cloud Storage  |  Google Cloud
  5GBまで無料、リージョンで値段が違う、保存/NW/取得/操作で課金
  nearlineの保存は半額で取得と併せstandardと同じ金額になるが操作費高い
  coldline/archive storageでも長期保存はせずできれば削除する、できないならポリシーでcold/archiveへ移動
    最低保存期間の縛り(90/365)があり早期削除でも請求、その期間は置いておく
  autoclassだとニア→コールド→アーカイブといい感じにしてくれるが1000ファイルにつき0.0025追加料金
   ※128kb以下は適応されずstdで追加料金もかからない
Autoclassが安全便利でファーストチョイス?単価から370kb程度以下で損する
 バケット作成時に設計をしておく(バケット編集でAutoClassが変更できるようになった)
  ライフサイクルを決めて削除条件も決めておく
  バケットを細かく分けた方がよいかも(バケット内でフォルダを作るとコマンドが遅く管理が面倒)
   ファイルサイズが大きいもの=AutoClassが良いかも
   ファイルサイズが小さいもの=OLMでライフサイクル設定(クラスと削除)
 ログ保存用途ならColdline/Archive設定+OLMでの削除設定
gsutil ls -lR gs://aaaa バケット内の各ファイルのサイズと、最終行でオブジェクト数と合計サイズが分かる(オブジェクト数はフォルダも一つとカウントされる、フォルダはサイズが0)
※GCSの注意点
早期削除料金の発生がリスク
ストレージクラスはファイルごとに設定がある、バケットはデフォルト設定だけ、AutoClassはバケット
オブジェクトライフサイクルマネージメントOLMでストレージクラスの変更すること
早期削除料金は削除、置換、移動、クラス移動でかかるが、OLMのクラス移動ではかからない
OLMの変更はファイル単位で変わりバケット設定をみてもクラスが分からない
手動(gsutilやAPIという意味)で変更するとStd以外は早期削除料金で高額化の恐れ
 ただしOLMは若返りの方向へのストレージクラス変更はできない
 gsutilやAPIでなら若返りストレージの変更ができる
Std以外は保存と閲覧の使用としたい、なぜなら、置換はファイル編集が該当するためファイルサーバとできないから
費用は保存費、オペレーション費、NW費、Std以外は取得費等からなり、費用は利用サイズの影響が大きく、通常は保存より利用の費用が高くなる
早期削除料金はStd以外で削除されたり更新がかかればファイル単位でかかる
早期削除料金は最低保存期間分がかかるがファイル作成日を元に計算されどのストレージであっても日数としてカウントされる
LoggingをBQに吐き出しておけば、利用者やバケット作成者が分かる protopayload_auditlog.methodName = 'storage.bucket.create' とかの条件

/// GCSの論理削除によるデータ保護
削除や上書き等でも元に戻せる。ソフトデリート適応期間分の費用/オペA費用が掛かるが
リストアには大量データの場合は数日かかる場合があり保持期間の延長の考慮が必要 (デフォ7daysでは不足するかも)
パケットの削除のやり直しはGoogleに問い合わせが必要
早期削除は物理削除日を元に計算するので論理削除の期間後の日時が使用されるので、7days早めに削除してもいいかも

■GCP Cloud asset inventory
 5週間分の履歴が保管される
 CAI exportにより任意のタイムスタンプでBQあるいはGCSに履歴情報を吐き出す
  コマンドやライブラリでダンプが可能
 gcloud CLIのgcould asset search-all-resourseコマンドにより設定
  BQに吐き出し各種状況のチェックやポリシーのチェックに活用

権限の確認もコマンドでできる
 gcloud asset analyze-iam-policy --organization=123456 --identity="user:fack@unko.com"

■Cloud logging
 毎月取込50GBまで無料、取込0.5$/GB+保存0.01$/GB、2種類ありAuditLogで有効無効化
  管理アクティビティログ 13ヵ月400日デフォ有効(_requiredログバケットは取込もデフォ期間保存も完全無料)
  データアクセスログ デフォ無効(有効にしてもデフォ保存期間30日は無料、50GBを超える取込が有料)
   ※つまり50GBを超えた取込、あるいは保存期間を伸ばした分が有料
 BQ streaming insert0.05$/GB+BQ保存(10G無料)0.02/GB=0.07$/GBでBQ化し保存が得
  長期保存が必要なものだけエクスポート
  集約エクスポート
  ログ取集前にログシンク(取込費がかからない)
   サンプル1%等で絞る等
400日の_requiredに入らないものが30日の_defaultに入る
Logルータのシンクでフィルタ、サンプリングしLogバケット/GCS/BQ/Pubsubに転送
 requiredでなくdefaultに入る時にLogルータを設定しフィルタを掛ければ減る
 自動でSAが作られるので作成や権限付与は不要
  包含フィルタが空なら全ログ
  クエリsample(insertId, 0.10)で10%のサンプル
Logバケットのdefault30日は変更できる
全ログをBigqueryに入れるには組織プロジェクトで転送を設定すればいい
 クエリ:Loggingをクエリで見る、Logルータのシンクをフィルタ(サンプル)する

■Monitoring
ダッシュボードはサンプルから作ると楽
MQLで改変、クエリを実行するとエラーメッセが出るんで
fetch gae_instance::appengine.googleapis.com/flex/cpu/utilization | { top1, max(val()); bottom 1, min(val()) } | UNION
 MQLは使えなくなりPromQLに変わった

■APIキー
APIキーを発行することで、外部アプリから利用できるようになる。各種使えるが強力なためAPIを絞る等制限を入れた方がよい、アクセス元のIPアドレスやリファラーで縛る等も
API キーを使用して認証する  |  Google Cloud
【要確認】Google Maps Platform APIキーの取得方法と注意点 | ワードプレステーマTCD (tcd-theme.com)

■サービスアカウント
デフォルトでは上限100個
svacキーはPWと同じ、できるだけ発行せず慎重に管理、gitにUP厳禁
svac名や役割を広くしない、強すぎる権限は付与せず最小限の権限で
GCEデフォのsvacは使用しない(Editorを持つから)
 サービスアカウントはサービスを有効化したときに動作用に自動作成されたり、別途手動でも作れる
所属のプロジェクトが削除されると:
 サービスアカウントは削除できなくなり、権限が残るため権限は個別削除が必要になる
 サービスアカウントの権限が残るが、他のプロジェクトで使用できる
 一定期間が経つとサービスアカウントの権限も自動削除される
 >プロジェクト削除前にサービスアカウントの無効にするのが望ましい
IAMでsvacにロールを付与、IAM>svacでユーザにsvacに対する管理ロールを付与できる
組織ポリシーでsvacキーの使用を特定のプロジェクトに制限した方が良い
できればキーを作成せず他の方法を
 workload identity(gke)、workload identity federation(serverless)
  SAMLみたいなものでGKE、OpenID、AWS、Azure、ActiveDirectory、GoogleCloudAPIは対応している
 一発使用ならimpersonateで成り済ませば一連のgcloud cmdは実行できる(下記参照)
SAキーの管理方法
 キーの削除、あるいはIAMコンディションにより権限側の変更、あるいはVPCサービスコントロールで制限位しかない
 有効期限の設定は無い、キーローテート機能もなくコマンドで自作するしか(削除と作成をするだけ)
 キーローテートを要求するため、キーは各々で発行してもらう
  手前でキーを発行した方が、キー削除や追跡ができるがローテートの手間がある、手前だと権限付与も少なくできるが、、


svacキーはRSA鍵ペア、秘密鍵でJWT署名なしトークンを作成(JWT=json web token)
 GCP内ではキーが自動rotateされている
 外部の場合は手動や仕組みでローテーションしたい
 開発環境ではクライアントライブラリとgoogle application credentials環境変数を使い隠匿する
サービス アカウント キーを管理するためのベスト プラクティス  |  IAM のドキュメント  |  Google Cloud
Google Cloud SDKのインストールと認証の設定について - TASK NOTES (task-notes.com)
概要 / アジェンダ - Infra OnAir (cloudonair.withgoogle.com)
秘密鍵さえあれば成り済ませ追跡が困難で誰が利用したか等が分からないのでsvacキーは使いたくない
svacキーは10個作成できる

/// svacキー使用方法
サービスアカウントのキーを作成しローカルに保存
SSHでGCEのVMに内容をコピペしてキーファイルを作成
下記でSAとしてログイン
gcloud auth activate-service-account ketsu@un.com --key-file /home/ketsu/sakey.json
cloud shell terminalでもファイルをアップロードできるのでup後下記でOK
gcloud auth activate-service-account ketsu@un.com --key-file sakey.json
ログオン切替
終わるとき rm sakey.json

shellセッションごとに環境変数でkeyを設定する方法も
認証のスタートガイド  |  Google Cloud

/// サービスアカウントキーを発行せずにサービスアカウント権限を使う
サービスアカウントに直接成り代わって gcloud コマンドを実行する - Qiita
サービス アカウントの権限借用の管理  |  IAM のドキュメント  |  Google Cloud
gceにデフォルトsvacが設定されていれば誰で入ってもauthはsvac?パスはユーザだが
任意のコマンドに--impersonate-service-account=ワイルドフラグを付けるだけ
IAM and Resource Manager API を有効化
サービスアカウントに使いたいロールを付与(roles/accesscontextmanager.policyAdminとか)
自身にroles/iam.serviceAccountTokenCreatorを付与
叩くgcloud info --impersonate-service-account=chinko-compute@developer.gserviceaccount.com
 ※tfだとproviderにimpersonate_service_accountを追加する形
設定するにはこれらしい
 gcloud config set auth/impersonate_service_account chinko-compute@developer.gserviceaccount.com
svacを指定するならこれでもいいがKeyがいる
 gcloud auth activate-service-account chinko-compute@developer.gserviceaccount.com --key-file=/himitsu/dame_key.json --project=bangboo-kuso
ログインユーザ確認で要確認
 gcloud auth list
gcloudコマンドのリファレンス

■セック
Google workspace googleアカウント(特定の経路:IP以外は無効)
組織ポリシー(GCP) Google Cloud 組織ポリシー - Qiita
 serviceuser.services deny compute.googleapis.com デフォルトcomputeなし
 compute.skipDefaultNetworkCreation enforced=true デフォルトcompute nwなし
 compute.vmExternalIpAccess inherit_from_parent=true
 iam.allowedPolicyMemberDomains inherit_from_parent=true 対象組織 外部ユーザ禁止
  →allusers/allauthuserも影響する(このためGCSもallusersが設定できず公開にはならない)
 iam.allowedPolicyMemberDomains inherit_from_parent=false 対象prj 外部ユーザ許可
 storage.uniformBucketLevelAccess enforced=true GCSアクセス制御を均一
 storage.publicAccessPrevention=true 公開しない(allusersも消える、逆にoffってもallusersも要る)
 sql.restrictAutherizedNetwork enforced=true CloudSQLのネットワーク制限
 compute.restrictLoadBalancerCreationForTypes allow=in:INTERNAL LBは内部だけ許可
 compute.restrictLoadBalancerCreationForTypes allow=all=true 対象prj LB許可
 compute.disableSerialortAccess enforced=true シリアルポートアクセスの制限
 compute.disableSerialortAccess enforced=false 対象prj シリアルポートアクセスの許可
BeyondCorp Enterprise(VPNレス、なお下の各要素はこの為だけということではない)
┣ IAP
┣ IAM
┣ Access Context Manager(VPC Service Controls:IPとかメールドメインとか) 
┗ Endpoint Verification(Chrome機能拡張)
Cloud armor(WAF)、FW
危険な設定はアラートを出したい:security command center、cloud asset inventoryをBQに出し定期スキャン
BigQueryの高額クエリはアラートを出したい

セキュアなBigQueryの運用方法 - Speaker Deck
 IAM condition: 20時以降はアクセスできない等時間やリソースで権限制御
 VPC-ServiceControls: VPC+FWで制限を掛けられなかったIPやIDで制限を掛ける(クレデンシャル漏洩防御)
  LBのバックエンドをGCSにするとIAPが使えない時も
  TF)perimeterで境界を設定してaccess leveで超えれるものを定義
   危険で user explicit dry run spec = trueでテストしながら falseで本番化
   statusが本番用、specがドライラン用で一旦statusを消してテスト
    restricted_services = storage.googleapis.com ならGCS
    resource
    access_level
google_access_context_manager_service_perimeter | Resources | hashicorp/google | Terraform | Terraform Registry

VPCサービスコントロール+Access context manager
VPC SCで組織で有効にするプロジェクトを指定し、上り(内向き)のソース、ID、プロジェクト、サービスを指定、ACMで許可するアクセス元地域やデバイスを指定(beyond corpかも)
VPC Service Controls の概要  |  Google Cloud
VPC Service Controlsを分かりやすく解説 - G-gen Tech Blog
サービス境界とアクセスレベルで、特定のユーザーやサービスアカウントからしか BigQuery にアクセスできないようにしてみた | DevelopersIO (classmethod.jp)

GCPでセキュリティガードレールを作るための方法と推しテク - Speaker Deck
 サブネット作成の際はセキュリティの観点からフローログを15分で取る
 監査ログを有効に
 ContainerResistryの脆弱性スキャンを有効に
 ログ:データアクセス/ポリシー拒否は30日、管理アクティビティは400日
  BQにバックアップしたい
 SecurityCommandCenterで脆弱性を検知
Cloud Audit Logging 活用のベスト プラクティス | Google Cloud Blog
 集約エクスポート シンクにより監査ログをBQに貯めたい

■タグとラベル
組織ポリシーはタグでconditionを指定した上で設定できる
タグは権限管理のための機能
タグは事前に組織レベルでタグを作成する、その後にリソースに対しタグ付け
FWで使うのはネットワークタグで種類が違うと思われる
ラベルはリソース整理や課金整理のための機能

■ネットワーク
外部IP
 External IP addressで取得、300円/月位、通常一つは自動で割り当てられる
PoP(Point of presence)
 世界70か所でGCPとエッジ(ネット)接続
NWトポロジーで通信が可視化でき通信コストが分かる
 詳細開くのは片側だけにすると使用帯域が表示される

■課金
BillingのBilling ExportからBigQueryにダンプができる

■サービスイン、導入、廃止
どういうステップかよくわからんが
GA(Generally available)
サービスに関する重要なお知らせ:MSA(Mandatory service announcement)
Deprecated
Decommission

■他
///gcloudをプロキシで使う環境設定とか
https://qiita.com/tora470/items/bc00bef8cba9f9acecc7

///Loadbalancer
 IAPはhttp LB/GCE/AppEngineに
 Internal LBにExternal IPは無理

ついでにIAP tunnel userの権限で踏み台が作れる+OS Loginで認証強化
 OS LoginはIAPの認証機能でSSH上でGCEインスタンスにログインできる代物
 GCPがSSH keyとIAMをGCEに準備してくれる

ついでにリバースプロキシ(nginxとかで作る)
LBみたいなもんだがプロキシでキャッシュを返す
代理代表サーバとなりWEBサーバ界のFWみたいな役割もできる

///NoSQL
=not only sql、分散kvsだったりの非構造化データ、下記2つのみ提供
 キーを指定してCRUD(追加、取得、更新、削除)
 キーの範囲かキーの前方一致でのスキャン

///bigtable
高スループット低レイテンシー読み書き速く膨大なユーザや数千万件テラ以上で
gmail、GA、マップ等々で使われている

///cloud functions
サーバレスでRESTみたいな形でURLでサーバアプリを実行、Node.js/PHP/Python等のコードが直接コンソールに掛ける
 ブラウザでcloud functionsにアクセスしたら下記が出た
Error: Forbidden Your client does not have permission to get URL/kuso-ketsu from this server
呼び出しの認証  |  Google Cloud Functions に関するドキュメント
curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME  -H "Authorization: bearer $(gcloud auth print-identity-token)"
↑curlでいいなら、コンソールで[未認証の呼び出しを許可する] 設定 + allusersでも可

///Pub/Sub
パプリッシャーからサブスクライバーにメッセージ転送、順序設定可、大量データを1件ずつとか
publisher -> topic : メッセージ -> push型 subscriber
publisher -> topic : メッセージ -> pull型 subscriber
-> cloud functions/runに連携したり、cloud schedulerから連携をしたり

BQ テーブルにデータをエクスポートする Dataflow ジョブ
GCS でデータをテキスト ファイルまたは Avro ファイルにエクスポートするための Dataflow ジョブ

///シリアルコンソール接続
SSH接続できない!そんな時のシリアルコンソール | apps-gcp.com
突然起動しなくなったWordPressサーバーをなんとか復旧した話 | (tipstock.net)

///gcloud cmd
gcloud organization list GCP IDやGoogleWorkspace IDが分かる

///Recommender
API の使用 - 推奨事項  |  Recommender のドキュメント  |  Google Cloud

///Googleスプレッドシート+GAS+BigQuery
GAS:マクロで記録してそれを使いまわす
 GASでBQの制御は難しいかも、更新してもBQのデータが古いままだったりする(appscript.jsonに権限を追記しても)
  シート経由せずにGASから直にファイルに書き出すとましかも(下記コード参照)
 データを一時でも書込ならスプレッドシートの共有の編集権限とシート保護しない設定が必要と思われ(セキュリティがザルに)
呼び名
 connected sheetでBQのデータをスプシに抽出する
 federated queryはBQに外部ソース(スプシ等)をインポートする

スプシの保護(シートはコピーできザルなのでセキュリティ対策でなくデータ保護)
シートを保護する、非表示にする、編集する - パソコン - ドキュメント エディタ ヘルプ (google.com)
スプシの閲覧共有だけでBQコネクテッドシートのプレビュー/抽出は可能だが、それをvlookup系で他のセルに移せない
組織でコネクテッド シートを使用する - Google Workspace 管理者 ヘルプ
他のブックにすればいいかも
編集共有した別ブックに入力データ(日付やメール)を持たせBQフェデレテッドクエリでBQに準備
閲覧共有した別ブックは参照用にBQコネクテッドシートがある形

■シートを経由しないBQを操作するGAS
const request = {
query: "select * from asoko",
useLegacySql: false
};
let rows = [['c1','c2']]
const result = BigQuery.jobs.query(request, 'kuso-prj');
for(let i=0; i < result.rows.length; i++){
let resultRow = result.rows[1];
let c1 = resultRow.f[0].v;
let c2 = resultRow.f[1].v;
let row = [];
row.push(c1, c2);
rows.push(row);
}
const spreadsheet = SpreadsheetApp.create("file", rows.length, 2);
const range = spreadsheet.getRange("A:B");
range.setValues(rows);
Browser.msgBox("A file is created"+spreadsheet.getUrl(), Browser.Buttons.OK);

GASのGCPプロジェクトは通常はデフォルトがベスト
 GASはOauthのためだけにGCPのプロジェクトを使う
デフォルトプロジェクトから切り替えると戻せない、利点も少しだけ(サイト参照)
appscript.jsonにoauthのスコープを追加しないと十分に機能しない
 GAS で OAuth のスコープが足りなくてやったこと (zenn.dev)
 GoogleAPIのOAuth2.0スコープ  |  Google Identity Platform  |  Google Developers
※エラーの場合
 BQの場合はBQコンソールでクエリ単体で実行しテスト
 loggingを見るともう少し情報がある
 コネクテッドシートならスプシの共有設定とBQの閲覧ロール等が要る、ビューならその先の小孫~最後までのロールまで要る
  委任を有効にするとスプシ共有だけでBQロールが不要になるが、、
  コネクテッド シートでアクセス権の委任を使用する - Google ドキュメント エディタ ヘルプ
 oauth自体でこけるとクッキー消去すれば待たずに再確認ができる?
Google Apps Script試行錯誤 Blog: デフォルトのGCPプロジェクトを標準のGCPプロジェクトに切り替えたい (pre-practice.net)
Google Apps ScriptのログをGoogle Cloud Platformで確認する方法 – hidetoshl.com

GASでAdminDirectoryを使う
 gas > サービス > AdminDirectory APIをOn
 gcp該当prj > APIダッシュボード > ライブラリ > Admin SDKを有効
 等でg workspaceのユーザ情報が取れるらしい
  Google Apps Script試行錯誤 Blog: AdminDirectoryでUsers.listを取得したい (pre-practice.net)
  GASでAdmin SDKを利用する(Directory編)その1 - Qiita

メールグループは任意にg workspace管理画面で削除が可能
GCP上はDeleted groupとなり1か月程度で削除される(IAMの状態は見れるが使えない)

■アプリ
公開資料 - App Modernization OnAir 〜 モダンなアプリケーション開発とは 〜 (cloudonair.withgoogle.com)
cloud runの設定だけでCDCIできる(第10回

End

Posted by funa : 09:00 PM | Web | Comment (0) | Trackback (0)


May 2, 2021

Terrafirma
公式
https://www.terraform.io/docs/index.html
導入
https://www.terraform.io/guides/core-workflow.html
推奨方法
https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part1.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part2.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.1.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.2.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.3.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.4.html
チュートリアル
https://learn.hashicorp.com/collections/terraform/gcp-get-started
HCL
https://www.terraform.io/docs/language/index.html
CLI aka cmd(アルファベットリストから使う)
https://www.terraform.io/docs/cli/auth/index.html
GCP用リファレンス
https://registry.terraform.io/providers/hashicorp/google/latest/docs

お便強
https://qiita.com/minamijoyo/items/1f57c62bed781ab8f4d7
https://qiita.com/donko_/items/6289bb31fecfce2cda79
https://www.apps-gcp.com/infra-automation-01/
https://colsis.jp/blog/gcpterraform/

Infra as codeとしてインフラの構築や設定をコード化できる
特にクラウドだと構築の自動化や構成管理等でのレバレッジが強力

■段階
Terraformとは?基本知識とTerraformのメリット4つを紹介 | テックマガジン from FEnetインフラ
必要なリソースをTerraform化>workspaceの活用>main.tfの共通部分をmodule化

moduleは構成に合わないようなリファクタリングが必要になった時にterraform state mv が必要になってとたんにつらい、moduleを細分化しすぎるとvariable と output が大量に必要になって書きづらい、moduleは再利用できる複数のリソースの単位(プログラミング言語でいうところの関数みたいなもの)で作るのがしっくり

リソースの差分を無視するlifecycleブロックを使う
resource "aws_autoscaling_group" "app_1" {
  name = "app-asg-1"
  lifecycle {
    ignore_changes = ["load_balancers"]
    create_before_destroy = true//新しいのを作ってから古いのを削除
  }
}
外部ファイルを文字列として読み込む
resource "aws_iam_role" "ec2_role" {
  name = "ec2-role"
  assume_role_policy = "${file("./ec2_assume_role_policy.json")}"
}
1つのディレクトリで複数のStateを扱うWorkspaceという機能もあるのですが、
個人的には普通にディレクトリを分けて管理する方が楽
production/stagingが完全に同じリソース構成で、設定のパラメータの差分がちょっとだけあるという理想的な世界ではWorkspaceでも運用できるかもしれませんが、現実的にはstagingだけリリース前の検証用の一時的なリソースが立ってたりとか、完全に同じ構成にならないことも多いので、モジュールの読み込みの有無や一部の環境だけ存在するリソースなどの差分を吸収できる場所があったほうが都合がよい

Terraform職人再入門2020 - Qiita
モジュールが公式から提供されている
Browse Modules | Terraform Registry

Terraform の terraform.tfvars とは | 30歳未経験からのITエンジニア (se-from30.com)
環境情報は外部ファイルが基本
prd/stg/dev環境はprd.tfvars, stg.tfvars, dev.tfvarsを用意
.tfvars 各環境の設定
aws_access_key    = "XXXXXXXXXXXXXXXXXXXX"
aws_secret_key    = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
aws_region        = "eu-west-1"
main.tf
terraform {
  required_version = "= 0.12.26"
}
provider "aws" {
  version    = "2.66.0"
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.aws_region
}
var.tf 空の受け皿
variable aws_access_key {}
variable aws_secret_key {}
variable aws_region {}

Terraform で変数を使う - Qiita
実行時に-var-fileで値ファイルを指定して環境などを切り替えると良いかもしれない
terrafrom plan -var-file=dev.tfvars
terrafrom plan -var-file=prod.tfvars
変数ファイル指定がないときは変数でdefaultに入れておく、descriptionで変数の説明もかける
variable "foo" {
  type = "string"
  default = "default-var"
  description = "Sample Variable"
}
変数ファイルを異なるバックエンド(フォルダ構成)で共有したいときはシンボリックリンクを貼る
 ln -s ../common/shared_var.tf shared_var.tf

credentials等の秘匿したい変数を外部のファイルやコマンドライン引数から読み込む
variable "credentials_file" {} @var.tf 変数を定義し空にしておく
credentials = file(var.credentials_file) @main.tf ファイルを読むがファイル名は変数
terraform plan -var 'project=' -var 'credentials_file=.json' @cmd プロジェクトとクレデンをコマンド時に指定
他にもvars.tfvars設定ファイル(行頭variableが不要)、TF_VAR_環境変数による指定

-var-fileで変数ファイルを明示してcmd、ファイル名は.tfvars/.tfvars.json
-varで変数を明示してcmd
順序があり後の読込でオーバーライド


HCLの変数は基本2種類のlocalとvariable
variableはグローバル変数、ファイル外やコマンドラインから使える
その他の変数参照方法としては(上から優先に適応)
 コマンド引数 一時的に使用
 変数ファイル terraform.tfvars git管理等で外部ファイルで?
 環境変数 TF_VAR_ 実行ログに残らない鍵情報等
workspaceは使わない、moduleを限定的に使う
設定をコード化>Gitレポジトリに置く>設定内容、作業履歴の明確化、チームでの運用性向上

■特性
TFの影響を反映するのはterraform applyの時だけ、tfファイルとtfstateの差分を実際にリソース作成する
 tfファイルで変更した場合、TFはリソースの再作成を行うので一度消えることになる(大体は単位が権限だったりで影響がないだけでplanで要注意)
terraform planはtfとtfstateと実体の差なので、実体があってもtfstateになければwill be createdでplan時は表示される
terraform importはtfファイルからtfstateへ記載だけを行う(実体からも情報を取得しtfstateに入れる)
 カレントdirの全.tfファイルor.tf.jsonを評価するのでtfファイルの名は何でもいい
各リソースに対してTF化するかは選択ができるが、TFする場合はそのリソースに必要な全記載をTFファイルに行う
terraform import tfResourceID.yourResourceName gcpIdentifier のコマンド
 terrafrom import google_bigquery_dataset.tf-1 bangboo-prj/test-dataset
 tfResourceID(リソースIDというようタイプ:リソース種別)はTF指定のもの、yourResourceName (リソース名)は任意のもの
 構成ファイル.tfはローカルのものが使われる、importするとtfstateに反映
 GCP identifierはTF公式サイトの各サービスの一番下import項目を見ると指定内容が分かるのでGCPを見て拾ってくる
 terraform state list TF化されているリソースを見る
 terrarorm apply時にもtfstateは更新される(オプション-refresh=falseで無効可)
  またapply時に-target=xxxでデプロイするリソースを特定できる(TFファイルだけでなくTFステートもターゲットになる)

Syntax - Configuration Language - Terraform by HashiCorp コメントは#が基本、//や/**/も使える
Terraform v0.12で変わるHCLの記述について - Qiita localsや変数、リストやマップ等
Terraform職人再入門2020 - Qiita yamldecodeやjsonencode等
Terraformの基本 - Foreverly (hatenablog.com)
変数
 variable(input var)はcmd実行時に変数を上書きできるが、localsはできない
 outputはapply時にterminalで値が確認できる、moduleから値を取得する

google_bigquery_connection | Resources | hashicorp/google | Terraform Registry
ドット繋ぎで値を扱える
resource "google_sql_database_instance" "instance" {
    provider         = google-beta
    name             = "my-database-instance"
}
resource "google_sql_database" "db" {
    instance = google_sql_database_instance.instance.name
    name     = "db"
}

ToSetは値設定をするが順不同で重複を省く
resource "xxx" "aaa" {
    for_each = toset(["foo", "bar", "bar"]) でbar, foo
    name = each.key
}

for_each/eachのループ
locals {
    sg = {
        foo = "FOO"
        bar = "BAR"
    }
}
resource "xxx" "aaa" {
    for_each = local.sg
    name = each.key
    description = each.value
}

mapをリストしたものをfor_each
locals {
  images = [
    { name = "foo", image = "alpine" },
    { name = "bar", image = "debian" },
  ]
}
resource "docker_container" "this" {
  for_each = { for i in local.images : i.name => i } # こう書くのが正しい
  name     = each.value.name
  image    = each.value.image
}

terraform importはリソース単位、更新はできず削除してから追加 terraform state rm google_bigquery_dataset.tf-1
 実設定とimportの内容が違う場合は実設定の情報でtfstate化されるようだ(importは項目を入れ込む感じ?)
  なので実環境に変更を加えるにはterrafrom apply、tfstate化もされtfファイル/tfstate/実設定の3者で同じになる
 apply時にtfstateと実設定が違う場合、例えば既存設定がある場合は重複エラーになりapplyできず、importしtfstateと実設定を同じにしてから、tfファイルの内容をapplyすることが必要
terraform importで対象プロジェクトを間違えるとハマる
 通常のterraform applyではproviderの情報を使用してプロジェクトを決めるが、importはハードコードするのでimportを間違えばなぜ変な変更がでるのかわからなくなる(プロジェクトが変なものはstateを調べ、terraform state rmするしか)

for_eachで書いた.tfをterraform importする | DevelopersIO (classmethod.jp)
 ユーザ指定は user:aaa@xxx.com だったりメールグループなら group:aaa@xxx.com

■セットアップ
 作業ディレクトリの作成(プロジェクトに対するローカルのフォルダ)
 プロバイダを指定したtfファイルの作成(gcsにstateを置く設定が良い
  provider "google" {
    project = "bangboo-kuso"
  }
  terraform {
    backend "gcs" {
      bucket = "bangboo-kuso-terraform"
    }
  }
 terraform init ローカルに対して初期化
 プロジェクトレベルownerのサービスアカウントを持っておく
 セットアップする際にtfsateのbackend保存場所のbucket部分をコメントアウト
 bucketを作るterraformを実施しbucketを作成しつつlocalにtfstateファイルを作成
 再度terraformをするとtfstateファイルがbucketにコピーされる
 bucket部分のコメントアウトを外すと次回tfからはバケットにtfstate更新する
  このときローカルtfstateの内容をバケットに写すか聞かれるが写す
  (写さないと差分しかバケットに行かないのでimport等が必要になる)

■既存リソースのTF化のおおよその作業
 リソースタイプと名前を定義したtfファイルを作成する(任意のリソース名、基本ユニーク、纏められるものは重複してもいい)
  resource "google_cloudfunctions_function" "fuckin" { ... をtfファイルに記載
   tfResourceID(リソースIDというようタイプ:リソース種別)とyourResourceName (リソース名) だけで
 リソースタイプや個別パラメータは公式ドキュメントを参照しながら定義
 https://registry.terraform.io/providers/hashicorp/google/latest/docs
  (簡単)tfファイル内で1行目以外は空で、terraform planをするとエラーで必要なものが分かるので、それを埋める
  planが通ると自動的に値をサーバから拾ってくる(importすればtfstate.tfに入っている or コピーしてTFに入れる)
  planでダメならterraform state show tfResourceID.yourResourceName でstateを見てtfファイルにパラメータを定義していく
   暫定に空でリソースをTFファイルに記載しterraform import、次にtfstateを調査する
    terraform state list tfstateファイルにあるアセットを一覧
    terraform import google_bigquery_table.xxx project/dataset/table インポート
    terraform state show google_bigquery_table.xxx tfstateの該当部を表示
    terraform state rm  google_bigquery_table.xxx インポート取り消し
  TF定義は複数の方法がある、最終GCP公式のRestAPIで確認するしか
 terraform importする(公式ドキュメントの一番下にimportコマンドの指定がある)
 terraform planして差分がなくなるまでtfファイルを修正する
  import(tfstate)の修正は一度stateから削除する terraform state rm google_bigquery_dataset.tf-1
  (既存リソースがあってもあくまでtfファイルとtfstateの差分なのでinitした状態でplanしてもup-to-dateと表示されるだけ)
 tfstateファイルにおかしなものが無いか確認、keyとか含まれないか

■個別
リファレンスでoptionalとなっていてもtfファイルでは必要な場合もある
 tfstateファイルからは必要ないとして自動的に削除されるが
スプシをBQでみれるFederatedQueryはテーブルだけ定義しimportしstate show調査
 urlをTFファイルに記載する
シャーディング(日付別)テーブルは定義できないのでは
 生成するクエリの方をTF化したい
Authorized viewはモジュールがあるがconflictがあり全消えする場合がありTF化にまだ向かない

google_bigquery_dataset_iam_memberでもAuthorized viewをはがしてしまう。
Authorized viewを使っている個所は google_bigquery_dataset_access あるいは google_bigquery_dataset の access フィールドを使う。
google_bigquer_dataset_iam_policy と google_bigquery_iam_binding は Authoritative で権限追加でなく権限強制設定でコンソール付与分を引き剝がすので、使わない方が安全。
なお、Authorized view と Routines はTerraform化できない事が分かっている(2022/4時点)
ScheduledQuery は Terraform化できるが実行者の設定ができない(Terraform実行者がSQ実行者?誰?)

BQ関連ではデータセット定義、テーブル定義、ビュー定義、フェデレテッドクエリ定義、ScheduledQuery定義をTerraformで行い
BQ権限定義、AuthorizedView定義、Routines定義は行わない

 BQ権限を定義するならデータセットレベルはgoogle_bigquery_dataset_access 
  プロジェクトレベルはgoogle_project_iam_memberで実施すると別なので安全らしい?

■TF公式ドキュメント
google_organization_iam_custom_role | Resources | hashicorp/google | Terraform Registry
google_organization_iam | Resources | hashicorp/google | Terraform Registry
カスタムロールを設定して、組織レベルのIAMでそれを使いたい
 TFのorg_iamページのArgument referenceのrole項目を見ると
  Note that custom roles must be of the format organizations/{{org_id}}/roles/{{role_id}}
 TFのorg_iam_custom_roleページのAttributes  referenceのrole項目を見ると
  id - an identifier for the resource with the format organizations/{{org_id}}/roles/{{role_id}}
 で下記と分かる、使用側と被使用側のTFマニュアルを両方確認する
resource "google_organization_iam_custom_role" "my-custom-role" {
  role_id     = "myCustomRole"
  org_id      = "123456789"
  title       = "My Custom Role"
  description = "A description"
  permissions = ["iam.roles.list", "iam.roles.create", "iam.roles.delete"]
}
resource "google_organization_iam_member" "my-organization" {
  org_id  = "123456789"
  role    = google_organization_iam_custom_role.my-custom-role.id
  #あるいは通常"roles/bigquery.dataEditor"のようにいれるがorganizations/0123456789/roles/chinkoといれる
  member  = "user:jane@example.com"
}

resourceの2番目リソース名を定義しますが任意の名前を指定します
 ここが同じ項目はユニーク制限がない場合は追加としてまとめられます
 通常はユニークにしterraformで管理するリソース名(yourResourceName)を宣言します
  ※1番目のリソースタイプ内でユニークにするのが基本(全体でもユニークの方が分かり易い)

TFファイルに定義をしたい →定義したいリソースのArgument referenceの項目を設定
TFファイルに定義した内容を変数で使いたい →使いたいリソースのAttributes referenceを見る
terraform importしたい →インポしたいリソースのページ一番下のimportコマンドの指定を見る

■他に一般的なTF(既存がimportされると以下で変更をapplyして運用)
 terraform -v 稼働確認
 terraform fmt ファイルの記述フォーマットを整える
 terraform validate ファイルの検証
 terraform plan アクションを計画
 terraform apply 最後に変更を適応
 terraform show ステータスを確認、一覧
 terraform destroy で簡単にインフラの吐き、initができないとき必要そう

■特定のリソースだけ適応したい
 terraform plan -target="tfResourceID.yourResourceName"
 terraform apply -target="tfResourceID.yourResourceName"
 TFファイルだけでなくTFステートもターゲットに含まれる
 これでTFファイルにコードがなくTFステートだけにあるものを指定して削除等もできる

■TFのcount
数を指定してその個数のリソースを作る。なのだが
 enable_lien = true モジュール側/変数側でこう設定し
 count = var.enable_lien ? 1 : 0 リソース側で3項演算子を使えばIFのように使える
  ※for loopのようなインクリのcount"+="でなく"="の1発実行なので3項演算子でIFになる

■エラー
bigquery access denied:
gcloud auth login --enable-gdrive-access
gcloud auth application-default login --scopes="https://www.googleapis.com/auth/drive","https://www.googleapis.com/auth/cloud-platform"
BigQueryでGoogleドライブデータへのクエリでエラーが出るときの対処 (zenn.dev)

排他処理でロックが残る:
他の作業者がいなければ、terraform apply -lock=false で一時的に無視をして続行
エラーIDに対して terraform force-unlock id_num963103164
Terraform で state のロックを解除する方法、ロックを手動で行う方法 | ゲンゾウ用ポストイット (genzouw.com)
TerraformでState Lockエラーが発生したら | DevelopersIO (classmethod.jp)


■terraformのバージョン管理
.terraform.lock.hclファイルでGCP provider等のライブラリのバージョン管理をしている、pyenvのPipfile.lockみたいなHash差分が記載されている、terraform init等で生成されapply時の設定が担保される、通常tfファイルでproviderのバージョンを記載すればよいので不要と思われる

.terraform-versionファイルでterraform自体の要求バージョンを担保できる
tfenvの.terraform-versionファイルにはバージョンベタ書きしなくてもOK | DevelopersIO (classmethod.jp)
通常はtfenvを使えばよい、tfファイルでrequired_versionを記載すればよいので不要と思われる

■tfenvを使う場合
tfenv install 1.0.0
tfenv list
tfenv use 1.0.0
 terraform init
 terraform workspace list
 terraform workspace select ore_space
main.tf作成し記載
 terraform fmt tfファイルのフォーマット(書式は適当で書けばいい)
  gcloud auth login ローカル操作のための認証
  gcloud auth application-default login SDKを実行のための認証
   API&Servicesでクレデンシャルは取得できそう、key=xxxx
既存のリソースを調査
terrafrom import google_storage_bucket.pri-bucket project-abc123/asia-northeast1/pri-bucket でimportとか
 terraform refresh tfstateの最新化、どのタイミングで使う?

■既存のリソースを調査
Terraform と gcloud CLI を使用した完璧な Google Cloud インフラストラクチャの構築 | Google Cloud Blog
gcloud beta resource-config bulk-export --help
gcloud beta resource-config bulk-export --project=kuso12345 --resource-format=terraform --path=/path/to/dir/
 対応を見ると数が少ないgcloud beta resource-config list-resource-types --format=json --project=kuso12345

terraformer import google list --projects=xxxx-123 で対象のリソース確認
terraformer import google --resources=instances,forwardingRules --regions=us-west1 --projects=xxxx-123 とか

既存リソースimport
https://www.apps-gcp.com/terraformit-gcp/
https://qiita.com/uu4k/items/48d3ecfefe57dba1d7e1

■Terraform applyで意図しない権限削除で障害が発生する
Terraform x GCP で、IAM権限を全削除してしまった - Qiita
resource "google_project_iam_policy" "unko" {
  project = "my-project"
  role = "roles/noguso"
  members = [
    "serviceAccount:${google_service_account.baka.email}"
  ]
}
google_project_iam_policy:書き換えるので他は無くなる(他を消したいときに使う)
google_project_iam_binding:付与、Authritativeだが他は現状維持?
google_project_iam_member:付与、Non-authoritativeで安全、まとめ難いか
 ※_iam_policyと_iam_bindingとt_iam_memberは一緒に使えない
 ※_iam_bindingと_iam_memberは一緒に使える

google_bigquery_dataset_iam_binding:(承認済みビューの権限はなくなる>google_bigquery_dataset_accessを使え)
google_bigquery_dataset_iam_member:roleとmemberを1対1でresourceを作りまくる、Non-authoritative
 ※_iam_policyや_bindingはまとめ易そうだが権限消しそう

google_bigquery_dataset_iam_memberでもAuthorized viewをはがしてしまう。
Authorized viewを使っている個所は google_bigquery_dataset_access あるいは google_bigquery_dataset の access フィールドを使う。

Terraform で GCP のサービスアカウントを管理する - Eng (なりたい) (hatenablog.com)
Terraform で GCP IAM 設定どれ使うのがいいのか - pokutuna (scrapbox.io)
google_project_iam | Resources | hashicorp/google | Terraform Registry
Authoritative: TFに明示していないものをApply時に削除しますという意、TFの権威
Non-authoritative: TFは権威を示さず、TFに明示していないものは現状維持ですという意

■勝手に公開
terraform vpc auto_create_subnetworks = falseにせなサブネットを公開して作りよる

■Applyの依存関係はdepends_on(プロジェクト作成の前に権限を付与しようとしてエラー等の順序)
[Terraform]Module間の値の受け渡しについて | DevelopersIO (classmethod.jp)
 これより先にあれをTFしてくれという記述

■データセット
google_bigquery_dataset | Resources | hashicorp/google | Terraform Registry
スキーマ取得: bq show --schema --format=prettyjson bangboo-prj:test-dataset.tbl001
ビューはコンソール>BQ>該当ビュー>detailからコピー

■組織ポリシー
google_organization_policy | Resources | hashicorp/google | Terraform Registry
制約について  |  Resource Manager のドキュメント  |  Google Cloud

■parallelismで早くなるかもしれない
あなたのterraform planを手軽に高速化する(かもしれない)魔法の言葉 - Qiita
シェル変数を設定、確認cmdは printenv
export TF_CLI_ARGS_plan="--parallelism=50"
export TF_CLI_ARGS_apply="$TF_CLI_ARGS_plan"

■テスト
TF Apply後には検証をしっかりしたい、最低Apply後にPlanを再実行したい、テストスクリプト的にチェックしたい
適応されていないことや、TF定義とtfstateと実設定の差分が想定と違うことがある感じがするからだ
moduleを含めて条件的な書き方だと、適応の順序の関係で適応が抜け2回以上TF applyしないといけなかったり

■TFファイルを分割し部分的に別環境へTFファイルを移行したい
tf stateファイルを新環境用にコピー
TFファイルを分割:現行の部分的に削除したTFファイル、と新環境用のTFファイルを準備
tf stateから不要部分を削除
 terrafrom state rm {{asset}}
terrafrom planで差分がないことを確認
新環境用にコピーしたtf stateファイルを編集し準備
 下の terraform state push xxx.tfstate で変更された状態をtf stateファイルに書き戻すことができる?
 このコマンドを実行する前に必要に応じて terraform state pull で最新の状態を取得?
 ダメなら terraform state rm で不要分を削る
新環境用にtfファイルを準備
新環境で下記を実行
 terraform init
 terraform state push xxx.tfstate
 terraform planで差分がないことを確認

■GCP権限(メールの変名時)
GCPはGWS gmailメールの変名に追従して権限も付与状態も変化がない
しかしterraformは追従しないためtfファイルで使っている場合は変更する

■gcloud cmd
https://www.devsamurai.com/ja/gcp-terraform-101/
 gcloud projects list 権限あるプロジェクトを表示
 gcloud config set project [prjID] ワーキングプロジェクトの設定
 gcloud services enable iam.googleapis.com サービスの有効化
 gcloud iam service-accounts create terraform-serviceaccount \
  --display-name "Account for Terraform" サービスアカウント作成
 gcloud projects add-iam-policy-binding [PROJECT_ID]
  --member serviceAccount:terraform-serviceaccount@[PROJECT_ID].iam.gserviceaccount.com --role roles/editor 権限付与
 gcloud iam service-accounts keys create path_to_save/account.json
  --iam-account terraform-serviceaccount@[PROJECT_ID].iam.gserviceaccount.com クレデン発行
 export GOOGLE_CLOUD_KEYFILE_JSON=path_to/account.json クレデン設定
↑サービスアカウントで認証 環境変数にファイルパスを渡す
 gcloud auth application-default login だと個人
 これにクレデンシャルファイルのパスを渡すとサービスアカウントでgcloudコマンド打てるはず

Terraformで複数リージョンをまたいだリソース制御する (mosuke.tech)
Terraform workspaceを利用して環境毎のリソース名の変更を行う (mosuke.tech)


End

Posted by funa : 10:14 PM | Web | Comment (0) | Trackback (0)


April 2, 2021

Linux cmd
■Linux terminal
tabで入力補完
↑↓で入力履歴呼び出し
^qはCtrl+qを押すという意味
半角/全角キー 日本語を切り替える(画面右上にもIMEがある、win+spaceの場合も)
ls -la ディレクトリ内を表示
ls -a 隠しファイルを含み表示
 (GUI)ctl+h 隠しファイルを表示(メニューでもチェックで可)
pwd 現ワーク中のディレクトリを表示
cd ../ 上に上がる
clear 表示内容を消す
mv beforeName.text afterName.txt ファイル名変更
rm -R ディレクトリ名 削除、ファイルはrm a.txt
ls -l > hoge.txt >結果を上書き
ls -l >> hoge.txt >>結果を追記
printenv 環境変数表示 printenv xで特定表示
grep aaa -rl ./ カレントディレクトリ以下からファイル内にaaaが含まれるファイルを検索
grep -R $keyword *.py .pyファイルからkeywordを検索
sudo - 一般ユーザが特権操作する sudo省略
sudo -i rootに切り替える
sudo -iu <username> 特権ユーザ切り替え

テキスト選択
 Shift↑or↓ で行全体
 home(+fn)で行頭、end(+fn)で行末移動

nano text.txt 作成あるいは開く、nano簡単かも、画面下コマンドでctrl+?すればいい
 コマンドM-UはEsc+u
 ctrl+k で1行削除

■viエディタ
sudo apt install vim
vi text.txt ファイル作成あるいは開く
 viは2つ+αのモード
 ┣コマンドモード
 ┃┗コロンモード(exモード:祖先のラインエディタ)
 ┗入力モード
 https://docs.oracle.com/cd/E19253-01/816-3946/editorvi-5/index.html
 viのコロンモードコロンモードのコマンドは、このw、q、q!、x、$5... - Yahoo!知恵袋
Escでコマンドへ抜ける
 ┗挿入 i (入力モード)
ファイル名を指定し保存 :w new_file_name.txt
強制保存のコマンド :w!
保存せず終了 :q 強制終了 :q!
:10 10行目に移動
:set number 行数を表示
:num 現在のカーソル位置行数を表示
クリップボードをペースト iで挿入モードに入り Shift+Insert
vi内でコピペ:yコマンドのコピー、pコマンドのペーストなので下記の様にする
 2yw ならカーソルから2単語コピーされます
 3yl ならカーソルから3文字コピーされます
 y$ ならカーソルから行末までコピーされます
 p ならカーソルの後ろにペーストされます
$ カーソルを行末へ
G カーソルを最終行行頭へ
- 前行の行頭へ
Enter 次行の行頭へ
w カーソルを1語進める
b カーソルを1語戻す
Ctrl-d 1/2画面下へ(down)
Ctrl-u 1/2画面上へ(up)
Ctrl-f 1画面下へ(foward)
Ctrl-b 1画面上へ(back)
/文字列(Enter要) 文字列検索(スラッシュ)
 ┣n 次の検索文字列へ
 ┗N 前の検索文字列へ 保存して終了 :wq 保存して強制終了 :wq!
コマンド集 viコマンド集 (ritsumei.ac.jp)
カーソル移動 viでのカーソル移動方法を一通りまとめました (eng-entrance.com)
検索 【初心者向け】viでの文字列の検索方法を一通り (eng-entrance.com)

■環境変数は下記の順で探す、なので必要なら下位のものを上にコピー
~/.bash_profile
~/.bash_login
~/.profile
source ~/.bash_profile 編集したbashrcをbash_profileに反映させる
 bashrcはbash起動毎、bash_profileはログイン毎

■SSHの設定
Linuxコマンド【 ssh-keygen 】認証用の鍵を生成 - Linux入門 - Webkaru
$ ssh-keygen
パスフレーズは空でも設定上は問題ないが塩っ気が足らん気が
秘密鍵(id_rsa)と公開鍵(id_rsa.pub)が生成され、ホームディレクトリに作成される
 /home/yourID/.ssh/id_rsa
 /home/yourID/.ssh/id_rsa.pub.
公開鍵をSSHサーバや外部サービスに登録する等して使う、秘密鍵は明かさないこと

SSHクライアントのproxy越えの設定方法 (mydns.jp)
プロキシbinのインスコ
$ sudo apt-get install connect-proxy
ホームにsshキーができているので
$ vi ~/.ssh/config
Host oketsu
HostName 1.XXX.XXX.XXX
User hoge
IdentityFile ~/.ssh/id_rsa.pub
        LocalForward 5912 localhost:5902
ProxyCommand connect-proxy -H proxy.syanai.in:8022 %h %p
Host github.com
HostName ssh.github.com
Port 443
IdentityFile ~/.ssh/id_rsa.pub
ProxyCommand connect-proxy -H proxy.syanai.in:3128 %h %p
User githoge
$ chmod 600 .ssh/config
下記のように実行すると、ログイン/GITできます。
$ ssh oketsu
$ git clone githoge@github.com:kusogitry.git
$ id 所属グループ等を表示
$ uname -n;id;date

■NW設定
/etc/resolve.conf
 nameserver 88.88.88.88
~/.profile とか .bashrc とか
  export http_proxy=http://proxy/3128
/etc/apt/apt.conf
ip addr

■スクリプト実行
nohup python3 main.py & ユーザディレクトリにnohup.outログが実行完了時に一度に保存される(重いと思われる)
nohup python3 main.py > /dev/null 2>&1 & ログなし
 nohupはバックグラウンド実行、ログアウトしても実行続ける
jobs ジョブリストを出す
fg ジョブ番号 フォアグラウンド実行に変える
bg ジョブ番号 バックグラウンド実行に変える
ctrl c キャンセル
ctrl z 中断(再開できる)
crontab -e 編集
crontab -l 確認
sudo service cron restart 再起動
systemctl status cron 稼働の確認
30 12 * * 0 python3 /home/app_hoge/main.py
 cronはバックグラウンド実行でnohup &を含めると実行されない、多分
top プロセス/CPU/メモリ等の情報、こちらで動いていればpsのstatがsでも問題ない、多分
ps aux
ps f -A プロセスをツリーで表示し便利
kill -l
kill -SIGCONT プロセス番号
sudo less /var/log/cron.log
sudo tail -f /var/log/cron.log
sudo less /var/log/syslog
sudo tail -f /var/log/syslog

■ディスク系
ext4 一般的なデスクトップやファイルサーバ向け、16TBまで、ファイルシステムチェックで遅い
xfs 高負荷IOで大容量データ処理向け、ジャーナルなし、ファイルシステムチェックを短縮
論理ディスク=パーティション
/dev/sda1, /dev/sda2, /dev/sdb, /dev/sdf等、数字はパーティション番号、数字がないとパーティション1つだけ

ディスク拡張
lsblk
df -Th
du -sk * | sort -nr

#xfsの場合
pvdisplay
pvresize /dev/nvm
vgdisplay
lvdisplay
lvextend -l +100%FREE /dev/vg001/lv001
xfs_growfs /opt

#ext4の場合
apt autoclean キャッシュあるがインストールされていないdebファイル削除
apt autoremove 必要なくなったパッケージ削除
disk -l /dev/nvm パーティション情報
growpart /dev/nvm 1 指定パーティションの容量拡張
resize2fs /dev/nvm ファイルシステム拡張

容量調整
/var/cache はapt-get clean, yum cleanで消す程度で

■swapをrootからvarに移動
free
swapon -a
swapを無効化
swapoff -v /swap.extended
swapをvarに移動
mv /swap.extended /var
/etc/fstabからswapのエントリを/varに書き換え
cat /etc/fstab
swapを有効化
swapon -a
確認
free -h

■ライブラリアップデート
sudo apt update
apt list --upgradable | grep mysql
sudo apt install mysql-client=6.6.6-0ubuntu2.1~99.99.9
sudo apt install mysql-client-core=6.6.6-0ubuntu2.1~99.99.9

dpkg-l | grep mysql

■SPF
spfレコードはメールを送信する際、送信元サーバとDNS上のIPアドレスを比較
自社から取引先に送信したメールにSPFレコードを設定していなければ、相手側のメールサーバで迷惑メールとされ届かない場合も

送信元のDNSに送信元IPをSPFレコードに登録する(ドメインをSMTPのIPに変える?
ドメイン IN TXT v=spf1 ip4:172.16.0.1 -all
(+が省略されているがIP許可、allを認証しないという意味)
送信側SMTPサーバではSPFをチェックせず何でも送信

受信側MTAにて設定され(SMTPにはトランスファのMTA、デリバリのMDA
spfを使えば先方がspfレコードを登録していなければメールが受け取れない
postfixやeximのSPFをonにする設定がある

spfレコードが設定されているかを確認
nsookup -type=TXT 調べたいドメイン

■lsofはオープンファイルの略だがネットワークソケットの調査
lsofでファイルを開いているプログラムを特定する | 晴耕雨読 (tex2e.github.io)
lsofコマンド入門 #Linux - Qiita

=============
■VS code
マルチカーソル:ctrl+shift+↓
[Alt]+クリックカーソルを追加
[Ctrl]+[Alt]+[↑]/[↓]カーソルを上下に追加
[Ctrl]+[U]カーソル操作を元に戻す
[Shift]+[Alt]+[I]カーソルを行末に追加
[Ctrl]+[L]行を選択
[Ctrl]+[Shift]+[L]選択中の文字列と同じものをすべて選択
[Ctrl]+[F2]カーソル位置の単語と同じものををすべて選択
[Shift]+[Alt]+[→]選択範囲の拡大
[Shift]+[Alt]+[←]選択範囲の縮小
[Shift]+[Alt]+ドラッグ矩形選択
[Ctrl]+[Alt]+[Shift]+[カーソル]矩形選択
[Ctrl]+[Alt]+[Shift]+[PgUp]/[PgDn]矩形選択 ページ上下
VSCodeのマルチカーソル練習帳 - Qiita
マルチカーソルを使わないVSCodeはただのVSCodeだ!〜解説編〜 - memo_md (hateblo.jp)


Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


March 9, 2021

Treachery

:||

2021/4/25に気づいた、ハニーちゃんおめでとうとありがとう、エピソードは今度どこかで

Posted by funa : 11:39 PM | Column | Comment (0) | Trackback (0)


March 6, 2021

ZERO

値段と糖質とプリン体と度数、モノによっては明らかに太る感じがしない、ゆって0じゃ無い安酒でも糖質15g位らしいので良いのがなければいつものでいいかも。それより現像ができない!!→LightRoom再インスコ→LRよりSony謹製の方が色が良かった→元画像が暗すぎが理由→LRでノイズを追加調整(元画像に注意、14mmf1.8の使い道がなく勿体ない、マクロとして物撮りしたい感じがあるがマクロは70-200の方がええし、14は人物用だな)

極ZERO: 138/0/0/5 ちょい高、不味い、5%で軽いが酔えなくはない、太る感じ×
Asahi Off: 118/0/0/3-4 酔えない、ノンアルの亜種かフルーティで旨い〇
のどごしZERO: 118/0/0/4 フルーティで旨い、軽いが酔えなくはない〇
贅沢ZERO: 118/0/x/6 プリン有 6%で嬉しいが雑味がすごくある気が▲
バーリアル糖質50%off緑: 85/5-10/?/4 かるくない、そもそもZEROでないが旨い◯+
氷結ZEROレモン: 108/0/0/5  レモンが強く旨い、飲みやすい◎
鏡月焼酎ハイ: 98/0/0/7 スッキリ高アルコール度で満足感、ドライが好きかも◯+
いいちんこ下町のハイボール: 168/0/0/7 高ぇ、重い感じがする▲
パーフェクトサントリービール: 168/0/x/5.5 高ぇ、旨い〇
 →氷結Zeroレモン>鏡月ドライのコンボが強い

イオン麻婆豆腐辛口(肉付)vs丸美屋辛口(花椒なし):丸は味穏やか、Aは塩と肉多い
 →Aeonのとろみ入れるの減らす、甘口は邪魔甘さで、中辛が一番いい
イオン四川式(肉無)vs丸美屋大辛(花椒付):Aは高いし辛い、お口は甘め好きda
 冷食が新しくなった、Palmボックスは忘れて何度か買ったが小さい
バターよりマーガリンの方が健康的になったらしい
 小岩井ヘルシー仕立てか、明治コーンソフトは近くで買えるが




ノンアルはどうなのか?飲み比べる、ジンジャエールよりいいか

キリンGreen's free 旨い、ノンアルならビールが良さそうで、ノンアルビールならこれでは?
Suntoryのんある酒場レモンサワー 酸っぱい、旨い(メシが進む感じはしない
Takara辛口ゼロボール スッキリしているが何か不味いので逆に酒感あり旨い
AsahiStyleBalanceハイボール まじウィスキー、旨い(メシが進む感じはしない
トップバリューホワイトサワー カルピスソーダでノンアルの意味なし
トップバリューBeerTaste スッキリ旨いが軽くハレ感が少ない

Suntoryノンアル気分カシスオレンジ 旨い、大人のジュース感
ワイン チェリオ
ジントニック ジントニック
檸檬堂

「カルト」はすぐ隣に: オウムに引き寄せられた若者たち (岩波ジュニア新書) | 紹子, 江川 |本 | 通販 | Amazon
霊的体験は飲み物にLSDを入れていたとなっている、まぁ殆どコレで教祖になれる

Posted by funa : 01:43 PM | Column | Comment (0) | Trackback (0)


February 21, 2021

BigQuery
■Big queryリファレンス
標準SQLとレガシーSQLがある、違いは?
標準 SQL のクエリ構文  |  BigQuery  |  Google Cloud
標準 SQL への移行  |  BigQuery  |  Google Cloud
標準 SQL のデータ型  |  BigQuery  |  Google Cloud
レガシー SQL 関数と演算子  |  BigQuery  |  Google Cloud
レガシー SQL のデータ型  |  BigQuery  |  Google Cloud
BigQuery: クラウド データ ウェアハウス  |  Google Cloud(チュートリアルみたいな) 

BigQuery解説:https://beyondjapan.com/blog/2016/03/what-is-bigquery/
クエリ処理のツリーアーキテクチャによる分散並列処理
複数のサーバーに対してツリー状に拡がっていき、並列にサーバー上で同時に分散処理
 ルートサーバ>intermediateサーバ>leafサーバ
BigQuery MLという機能を利用すると、機械学習モデルをCloud AI PlatformのTensorFlowなどに連携させ、クエリ結果を素早くAIと連携
Lookerというデータ分析プラットフォームとの連携よりクエリ結果を、データ統合、変換、分析、可視化、レポーティングすることができ、非常に強力なBI

列指向型・カラム型データベース・カラムナストレージ(一般的なRDBMSでは行単位でデータが保存)
 必要なカラムのデータを取得するだけでよく、またデータは圧縮できる
https://dev.classmethod.jp/articles/google-bigquery-debut/

GCPプロジェクト>データセット>テーブル(行row列columnで普通のテーブル、ネイティブbigqueryテーブル/Googleドライブのような外部テーブル、SQLクエリによるビュー)
 アンスコ_で始まるデータセット名は隠しでコンソールで非表示
ジョブは非同期で実行され、ステータスをポーリング(データの読み込み、データのエクスポート、データのクエリ、データのコピーなど)

クエリ(ウェブ UI、bq コマンド、BigQuery REST APIの方法がある、SQLと同じ?
SELECT   title, answer_count, view_count
 FROM  `bigquery-public-data.stackoverflow.posts_questions`
 ORDER BY  view_count DESC LIMIT 10
BigQueryはSELECT tag, time FROM [dataset_name.table_name_20151206]のように必要な列だけを選択した場合にはスキャンの幅を狭めることは可能ですが、LIMITやWHERE句には何を書いてもテーブルをフルスキャンしてしまう
節約 Amaのs3に入れRedshift内でテーブルを分割した後にBigQuery

Hadoopでも使われていたGoogle開発のエンジンであるMapReduceは、非構造化データをプログラミングモデルを通して扱うが、巨大なテーブルの結合や巨大な出力結果のエクスポートも可能である半面、処理時間は数分間から数日に及んだ、だが、BigQueryは、あらかじめデータを構造化してBigQueryのテーブルに格納しておかねばならないが、ほとんどのクエリは数秒で完了する

サードパーティ ツール(データの読み込みや視覚化を行うツールなど)を使用して BigQuery のデータにアクセス可
Google Cloud SDKをインストールすればコマンドラインが使える
BQは同一リージョンでないとJoinができない、ゾーンはマルチで良い
 BQでは us と eu がマルチリージョン
  22/4現在のリージョンリスト:asia-east1-2、asia-northeast1-3、asia-south1-2、asia-southeast1-2、australia-southeast1-2、europe-central1-2、europe-north1、europe-west1-6、northamerica-norhteast1-2、southamerica-east1、sourthamerica-west1、us-central1、us-east1-4、us-west1-4

パブリックデータに直でアクセスできる
SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013`
BigQuery の一般公開データセット  |  Google Cloud
 →FROM句の書き方:他のプロジェクトを指す名前にハイフンがあるとバッククォートで囲む必要がある
  `other-prj`.dataset.table あるいは `other-prj.dataset.table`

■標準SQL
先頭行でレガシーか宣言 #standardSQL あるいは #legacySQL
バッククォートでエスケープ、プロジェクト区切りも.(ドット)、From句のカンマはCross joinで全組合せかと思われ通常通りjoinやunionを使う事
配列が使える、カラム一つに配列を入れて多元的に扱える
withで一時テーブルを作れる
exceptでカラムを除外、replaceでカラムの置き換え
 select * except(kuso) from a
分析関数over()とwindowで計算ができる
 rank() over (order by x)は下記moreのRFMに使用している
 ROW_NUMBER() over (order by timestamp) as id,で採番できる
地理関数とかJSON関数とか色々関数もありそう
スクリプトで変数やIfやLoopが使える 標準 SQL のスクリプト  |  BigQuery  |  Google Cloud
join on a.c=b.cはjoin on using (c)とできる

BigQuery 特集: データ操作(DML) | Google Cloud 公式ブログ
insert into tbl_dest select * from tbl_source とselect結果を挿入できる

■レガシーSQL(標準SQLを使うのが由)
予約語は角かっこを使ってエスケープ、プロジェクト区切りは:
集計関数で WITHIN キーワードを使用すると、レコード内の繰り返しの値が集計?
FROM句のカンマは標準SQLのCross joinとは異なりUNION ALL 演算子
通常のSQL処理システムとは異なり、BigQueryは繰り返しデータの処理を前提として設計。繰り返しレコードの構造を操作するクエリを記述。その方法の1つが、FLATTEN 演算子?
JOINは、INNER、[FULL|RIGHT|LEFT] OUTER、および CROSS JOIN 演算子をサポート、デフォルトINNER
除外できる select + from A OMIT RECORD IF COUNT(payload.pages.page_name) <= 80;
TOP を使用するには、SELECT 句に COUNT(*) を含める
分析関数over()とwindowで計算ができる?(標準SQLと同様?)
functionを作って使える(標準SQLと同様?)
JSON等のネストをフラット化

■DDL データ定義言語ステートメントの使用  |  BigQuery  |  Google Cloud
https://www.isoroot.jp/blog/1651/
auto_incrementもdefaultもprimary keyもindexもshow create tableないのでは?
CREATE TABLE IF NOT EXISTS bangboo_data.x_xxx (
  `no` INT64 NOT NULL,
  `user_no` INT64 NOT NULL,
  `name` STRING,
  `date` DATETIME,
)

同じスキーマで作ることもできる
CREATE TABLE ore_ds.test003
 LIKE prj.ds.test001
PARTITION BY _PATITIONDATE

■bqコマンドはコンソールで実行できる
ブラウザで該当プロジェクトに入りコンソールボタン、下記ではスキーマをJSONで取得できる
bq show --schema --format=prettyjson myProject:myDataset.tbl001
bq ls -n 3000 dataset_aho (データセット内のリスト3000件、デフォ50件?)

bq cp --force prj:ds.tbl prj:ds.tbl2
上書きコピー(削除しコピー)コンソールだと同名コピーや下記ができない
bq cp ds.tbl1,ds.tbl2 ds.newtbl
2つのテーブルをnewtable にまとめコピー
bq cp -a ds.tbl2 ds.tbl1
tbl2をtbl1に追加コピー --append_table でも同じ

bq load (csvとかgcsのファイルを読み込む)
bq extract (gcsに抽出)

■データアップロード時のスキーマ指定
自動検出はFirestore、Datastore、Avro、Parquet、ORCだけ?ほぼ手動のutf-8のcsvかjsonlかを使う形
コンソールで手動スキーマ指定可(jsonスキーマを張付ける)、modeは省略可でデフォはnullable、
JSONスキーマファイルupはaqコマンドのみ可、ローカルからup時のコマンドとスキーマ例↓
bq load --source_format=CSV mydataset.mytable ./myfile.csv ./myschema.json
[
  {
    "description": "quarter",
    "mode": "REQUIRED",
    "name": "qtr",
    "type": "STRING"
  },
  {
    "description": "total sales",
    "mode": "NULLABLE",
    "name": "sales",
    "type": "FLOAT"
  }
]
なお一旦Google Cloud Storageに放り込んでからやると高速 BigQueryにデータをバッチでインポートする - Qiita

COUNT DISTINCTだが、BigQueryでは概算値が返ってくる??。正確な値が必要な場合は、GROUP EACH BYとCOUNT(*)を組み合わせる
https://www.buildinsider.net/web/bigquery/01

■BQはUTC(Universal Time, Coordinatedの頭文字)
ScheduledQueryを終了日6/9 13:00JSTで即時設定→6/9 01:20UTCで実行された
(終了時間にJST/UTCの考慮が必要か→SQ実行時間設定についてはJSTかUTCに注意するだけ)
実行履歴はUTCのためJSTに読み替える必要がある(UTCはJSTの-9時間)

■BigQuery機能
///クエリ結果を別テーブルに書き込む
その他>クエリの設定>クエリ結果の宛先テーブルを設定する
BigQueryではSELECT結果を他テーブルにInsert / テーブル洗い替えなどができる - コード日進月歩 (hateblo.jp)
クエリ結果の書き込み  |  BigQuery  |  Google Cloud

///Saved query
プロジェクトに対して保存をして使いまわす等ができる
URLでクエリを共有できる

///Federated Query
スプレッドシートやGCSの外部ソースをBigQueryで
範囲の書き方:シート1!A1:B100
Auto detectにするとHeader skipを1にして1行目をカラム名として使うといい
注意)
 シートで構成を変えると滅茶苦茶になる
 空欄のセルはnullになる
 使う人はBQへもスプレッドシートへも両方権限が必要

///パラメータ(変数)を使う
--parameter=min_count:INT64:250
SELECT word FROM `prj.ds.t` WHERE AND count >= @min_count
パラメータ化されたクエリの実行  |  BigQuery  |  Google Cloud

こういう感じでも使えるのでは
WITH params AS (
 SELECT @sheetInput AS p
),
tmp_pre_processed_src AS (
 SELECT * FROM src
)
SELECT * FROM tmp_pre_processed_src
,params
WHERE
 tmp_pre_processed_src.a = p

///*を受ける_TABLE_SUFFIXを使う(複数テーブルだとunion allになる)
SELECT year FROM `bigquery-public-data.ds.gsod19*`
WHERE _TABLE_SUFFIX BETWEEN '29' and '35'
ワイルドカード テーブルを使用した複数テーブルに対するクエリ  |  BigQuery  |  Google Cloud
 BTWで絞らないと全結合で課金が厳しいかも

 ※ワイルドカード注意
 dataset.product_*と書くとdataset.product_20190425だけでなくdataset.product_special_20190425にもヒットしてしまう

betweenは小さいから大きいで、パーティションのないシャーディングテーブル日付きつきテーブルでも行ける(From句のテーブルに動的な名前を使うにはこれか、EXE IMEDIATEくらいか?)
SELECT year FROM `bigquery-public-data.ds.gsod20*`
where _TABLE_FUFFIX between format_date('%y%m%d', date_sub(current_date("Asia/Tokyo"), interval 3 day))
 and format_date('%y%m%d', current_date("Asia/Tokyo"))

///時間のパラメータを使う
select * from mytable_{run_time-1h|"%Y%m%d"}
実行時間run_time(UTC)から1時間引いた日→mytable_20180214
クエリのスケジューリング  |  BigQuery  |  Google Cloud

///動的にテーブル名を指定してcreate table
パラメータや変数や_TABLE_FUFFIXだけでは難しい。変数はテーブル名とは解釈されない、_table_fuffixはselect分のfrom句に入れwhere句で内容を指定するがcreate分は無理、execute immediateを用いる
DECLARE t STRING;
SET t = (SELECT CONCAT('x_emp_at', FORMAT_DATE("%Y%m%d", DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY))));
EXECUTE IMMEDIATE format('CREATE OR REPLACE TABLE `%s` AS SELECT * FROM `prj.bangboo_data.x_employee`', t);

ScheduledQueryでは出力テーブルの指定が可能でテーブル指定例:table001_{run_time-1h|"%Y%m%d"}でOK、なおSQL内にはrun_timeが使用できない

///既存のテーブルをコピー(CREATE OR REPLACE TABLEもあり)
CREATE TABLE IF NOT EXISTS bangboo_data.x_employee_copy (
  `no` INT64 NOT NULL,
  `name` STRING,
) as
select * from `prj.bangboo_data.x_employee`
データ定義言語ステートメントの使用  |  BigQuery  |  Google Cloud

///timestampとdatetime
datetime型カラムにはCURRENT_DATETIME()、timestamp型カラムにはCURRENT_TIMESTAMP()を使う
 timestampはUTC、datetimeはローカル的で地域指定ができる
 直近3分
 SELECT * FROM `aaa.ds.tbl111`
 WHERE `date` > DATETIME_SUB(CURRENT_DATETIME(), INTERVAL 3 MINUTE)

//stringとdate
func_approved_routine_a('2021-10-31') 引数がstring型
func_approved_routine_a("2021-10-31") 引数がdate型

///日付のキャスト
CAST(date AS STRING)
TIMESTAMP(DATE_SUB(CURRENT_DATE(), INTERVAL 1 month))
BigQueryのStandardSQLで日付(date, datetime, timestamp)を変換する方法 - 寝ても覚めてもこんぴうた (hatenablog.com)
Bigqueryの日時に関係する関数全部試してみた ①Date編 - Qiita

///timeで入っているものを日でサマるSQL
select
count(table_id),
sum(size_bytes),
date(record_time) as record_day
from bq_metadata
where record_time > TIMESTAMP(DATE_SUB(CURRENT_DATE(), INTERVAL 3 month))
group by record_day
order by record_day DESC

///有効期限 table expiration
データセットに対して何日間かにするか設定できる
テーブルに対し特定の日付を設定できる
 何が起こる?>データセット自体は残るが中のテーブルが無くなる

///パーティション
パーティション分割テーブルの概要  |  BigQuery  |  Google Cloud
BigQueryのStandardSQLで日付(date, datetime, timestamp)を変換する方法 - 寝ても覚めてもこんぴうた (hatenablog.com)

パーティション分割テーブルは2種類:パーティショニングとシャーディング
●シャーディングテーブル
 カラムの増減OK、スキーマとメタデータを持ち権限検証され オーバヘッド有り、ワイルドカード誤操作しやすい→保存向き
●パーティションテーブル
 クエリが早い、カラムの増減に対応できない、上限4000位→利用向き
●シャーディングテーブルにパーティション設定
 各シャーディングtblでパーティションを持たせる、特殊用途で通常どちらかで

TIMESTAMP 列とDATETIME列では、パーティションを時間単位、日単位、月単位、年単 位のいずれで
 SQで自動的にtimestampでDAYになる、SQ実行頻度から自動設定される?
ワイルドカード誤操作 *だと_fuyou_20240401等の想定外も含むため_202*にする等の考 慮が必要
シャーディングの作り方、yyyymmではダメだった、create文でテーブル名にyyyymmddを 付ける あるいはSQのテーブル名に_{run_time-2h["%Y%m%d"}等
シャーディングはテーブルごとに権限を付与が必要で日付別なら実質無理でデータセットで権限管理が必要

クラスタリング も同時に考慮したい
事前にソートし、まとまりを作っておく仕組み。
インデックスのようにカーディナリティが高いカラムを指定してあげると列指向のため全スキャンしなくて良くなる。圧縮率も上がり 保存費用も削減できる。
WHERE で指定あるいは GROUP BY される複数列をクラスタ化列として指定するが、指定の順番が重要。
まずパーティションが考慮され、次に最初にクラスタ指定した列で行がソートされ、次にその中で2番めに指定した列でソート、次に3番目...となる
CREATE TABLE ds.tbl_cls (purchase_dt DATE, prod_id STRING, prod_name STRING)
PARTITION BY purchase dt
CLUSTER BY prod_id

1)パーティショニング
BigQueryでパーティション分割テーブルを作成する - goodbyegangsterのブログ (hatenablog.com) を見よ
パーティショニングは事前に作っておくこと
上限が4000のため最大日単位で11年、時間単位で5か月くらいでpartition_expiration_daysも指定しておく事
CREATE TABLE sample.n225 ( 
  trading_day DATE NOT NULL OPTIONS(description="取引日"),
  closing_quotation NUMERIC NOT NULL OPTIONS(description="終値"),
  opening_quotation NUMERIC NOT NULL OPTIONS(description="始値"),
  high NUMERIC NOT NULL OPTIONS(description="高値"),
  low NUMERIC NOT NULL OPTIONS(description="低値")
PARTITION BY
  DATE_TRUNC(trading_day, MONTH)
OPTIONS (
  partition_expiration_days=1825,
  require_partition_filter=true,
  friendly_name="日経225時系列データ",
  description="月別パーティションされた、201901から202107までの日経225時系列データ",
  labels=[("environ", "dev")]
)

クエリはpartitioned byのヤツで絞れば良い
select * from aaa_history wehre
#ParticionIDで絞る(つーかpartitioned byのヤツで日付をキャストしてUTCをJST日付に
date(rec_time) = date(datetime_add(datetime "2000-10-10 00:00:00" interval -9 hour))
AND
#実際の時間で絞る、パーティションが日付区切りなので時間検索だけなら全件検索になる
datetime(rec_time) between datetime_add(datetime "2000-10-10 00:00:00" interval -9 hour)
 and datetime_add(datetime "2000-10-10 00:59:59" interval -9 hour)

2)シャーディング
シャーディングは_TABLE_SUFFIXを使ったり、テーブル名にハードコーディングする。
日付のキャスト select * from `task_*` where _TABLE_SUFFIX = REPLACE(CAST(date AS STRING), '-', '')

DROP TABLE `task_*`のようにワイルドカードは削除時は使えない
大量削除は下記のようにbq cmdリストを作りBashで。(Terminal貼りつけでも可)
 シャーディングはデータセット別にしてデータセットごと消すようにしたいが
Delete BigQuery tables with wildcard - Stack Overflow
select concat("bq rm -f -t ",table_schema,".",   table_name, ";" )
from INSERT_YOUR_DATASET_NAME.INFORMATION_SCHEMA.TABLES
where table_name like "INSERT_YOUR_TABLE_NAME_%"
order by table_name desc

削除されたテーブルは7日以内なら復元することも可能
テーブルの管理  |  BigQuery  |  Google Cloud
BQタイムトラベルで2-7日前のデータを見れる
タイムトラベルを使用した履歴データへのアクセス  |  BigQuery  |  Google Cloud

///UNNEST
UNNESTを知らないとBigQueryを使えない? | 4番は司令塔 (pep4.net)
BigqueryでUNNESTを使いこなせ!クエリ効率100% | by Eureka Engineering
ARRAY を一組の行にフラット化するには、UNNEST 演算子を使用
SELECT id, title FROM games, UNNEST(titles) AS title
idtitles
1[skyrim, fortnite]
2[atvvsmx, mario]
↓フラット化
idtitle
1skyrim
1fortnite
2atvvsmx
2mario

ただしUNNESTで指定したカラムが空の配列やNULLの場合、該当行は無くなってしまうので注意
 id=3 titles=[]やid=4 titles=NULLの時はid=3,4は引っ張れないということ

select * from unnest(['aaa', 'bbb']) as baka -> rowとして2行出る
select ['aaa', 'bbb'] as baka -> 1行目に配列として全て含まれ出る

sql - How to query multiple nested fields in Bigquery? - Stack Overflow
Unnestでもflattenができず空欄ができる場合、結局left join
 空を含むカラムはSelectに残し、repeatedのカラムはleft joinでくっつける
 VariantsをunnestしてるがPricesもrepeatedなのでleft joinのものを出している
  repeatedもarrayと同じらしいが、、、cross joinやarray_to_stringもやったが駄目だった
   なおrepeated以外はunnestが効かない
それでも駄目ならselect句の指定方法やwhere句で絞ると空欄が抜けたよ
select Productid,Variants.SKU,Variants.Size
,Prices.Currency,Prices.Country
from `ga-export-0000.feed.feed_dev`
,UNNEST (Variants) AS Variants
LEFT JOIN UNNEST(Variants.Prices) as Prices 

///ARRAY型とSTRUCT型
Arrayは上のUnnestを参照。
Structは構造体型。順序付きで親子の構造を持つ。各フィールドはデータ型(必須)とフィールド名(オプション)を持つ。

array型 unnestできる、[]なのでarray_length()で数が取れる
struct型 unnestできる、ネストを含みスキーマでrecord型と表記される、struct型の子へは.ドットで指定す
 stringでJSONはjson_extractを使う
 配列との絡みでjson_query_arrayを使う、2段階くらいは関数で対処できるがそれ以上はwith句がいい
 BigQueryでの複雑なJSON文字列の扱い方と注意点 - Qiita
 JSON functions  |  BigQuery  |  Google Cloud

CREATE TABLE IF NOT EXISTS `bangboo-prj.ds.x_list` (
  `record_time` TIMESTAMP,
  `name` ARRAY
)
INSERT INTO `bangboo-prj.ds.x_list` (`record_time`,`name`) VALUES (CURRENT_TIMESTAMP(),['a','b'])

struct型(record型)は子や孫でヒットすれば親を含めて表示されてしまう
見やすくするため*ではなく、カラムを特定すると空欄が表示されなくなり
親が出なくなり理解しやすくなる(必ずカラム指定したい)

Array=String Repeatedつまりリスト(配列)に値を入れる書式(下記で2つしか入らない)
insert into aaa (aaa) value ("['aaa','bbb']") value has STRING
insert into aaa (aaa) value (`['aaa','bbb']`) Unrecognized name: `['aaa','bbb']`
insert into aaa (aaa) value (['aaa','bbb']) OK
insert into aaa (aaa) value ('["aaa","bbb"]') value has STRING
insert into aaa (aaa) value (`["aaa","bbb"]`) Unecognized name
insert into aaa (aaa) value (["aaa","bbb"]) OK
insert into aaa (aaa) value ([`aaa`,`bbb`]) Unrecognized name
insert into aaa (aaa) value ([aaa,bbb]) Unrecognized name: aaa
insert into aaa (aaa) value ([123,456]) Value has type ARRAY

例)権限が変わっていないかの確認する等
降順で最新の日付のアイテムを見る、そして最終ページの古い日付のアイテムを見る
そしてそれらを比較する
select record_time, name, asset_type, m, b.role
from cai_iam_policy_history
,unnest(iam_policy.bindings) b
,unnest(b.members) m
where record_time between timestamp('2021-05-01') and timestamp('2021-06-30')
and b.role in ("roles/bigquery.dataViewer", "roles/bigquery/jobUser")
and m like '%ketsu@bangboo.com%'
and ancestor_path like '%ketsuproject%'
order by record_time desc
SQL解説)struct型が沢山入っていても全部unnestしfromに入れればいい
 from a, unnest(iam_policy.bindings) b, unnest(b.members) m
    unnest(iam_policy)はできないので2階層目から
  一つ階層上ではunnest時に別名を付けて下の階層はその別名でunnest
struct型の子へは.ドットで指定すればいい、フラットでなくてもbでも取得ができる

通常SQLは「表.カラム」だが「親カラム.子カラム」なので、出元がどこかテーブルを探すかスキーマ内を探すかで迷う

///json_extract, json_extract_scalar
2番目の引数はパス
BigQueryでの複雑なJSON文字列の扱い方と注意点 - Qiita
標準 SQL の JSON 関数  |  BigQuery  |  Google Cloud

with t as (
    SELECT unco_data AS col_1 FROM `kuso`
    WHERE date = "2021-08-04"
)
SELECT
    json_extract(col_1, '$.color') as unco_color,
    json_extract(col_1, '$.temperature') as temperature,
    json_extract(col_1, '$.fart.times[0].stink') as first_stink,
FROM t

///Pivot
BigQueryでPreviewになったPIVOTとUNPIVOTを試す | DevelopersIO (classmethod.jp)
【SQL】クロス集計を扱う。PIVOT句とUNPIVOT句についてコードを踏まえて解説。 | ポテパンスタイル (potepan.com)
集計をして行を列に変換(生ログをある単位でまとめカラムにする)

--toolのactiveがonなら1、nullなら0でユーザAとBの状況を見る
SELECT * FROM (
 SELECT user, tool, active FROM `tools`
)
PIVOT(
 MAX( IF (active IS NOT NULL, 1, 0))
 FOR user IN ("a", "b")
)

tool a b
------------
axe 1 0
sword 0 1

※参考にピボットテーブル
集計して行を列に変換、生ログをある単位でまとめる
 生ログが「日 店 金額」の場合
 ↓
 ピボットで「日 金額 (店1 店2 店3)」にする等で、各項目を行と列と値に配置し直す

BigQueryでPreviewになったPIVOTとUNPIVOTを試す | DevelopersIO (classmethod.jp)
PIVOTの中は定数でないとだめだが、
Execute Immediate なら動的にイケる、
がGoogleSheetのConnectedSheetではサポートされておらず無理という罠

///縦持ち横持ち
pivotは集計関数を用いる、単純の入れ替えならSQLならこちら
[SQL]データの縦持ち、横持ちを入れ替える | DevelopersIO (classmethod.jp)

///新旧の差分
比較したいデータの共通してい部分で外部結合をしてnull部分を探す
WITH
 old_e AS (
  SELECT * FROM status WHERE user IN ('a@old.com')
 ),
 new_e AS (
  SELECT * FROM status WHERE user IN ('a@new.com')
 )
SELECT * FROM old_e o
 FULL OUTER JOIN new_e n ON o.id = n.id AND o.date = n.date
 WHERE o.id is null OR n.id is null
 ORDER BY o.id, o.date

unionにexcept distinctをSQLを付けると差分になる
https://qiita.com/tatsuhiko_kawabe/items/2537c562c6d99f83e37b
SELECT * FROM item.item_table 
EXCEPT DISTINCT 
SELECT * FROM item.item_table WHERE user_id = 'A'
 1つ目の結果から2つ目を引いたものを出す

///REGEXP_REPLACE 正規表現で文字を削除
WITH markdown AS
  (SELECT "# Heading" as heading
  UNION ALL
  SELECT "# Another Heading" as heading)
SELECT
  REGEXP_REPLACE(heading, r"^# He", "") AS html
FROM markdown;
標準 SQL の文字列関数  |  BigQuery  |  Google Cloud

///スラッシュで分割するとarrayになるのでオフセットで取得
select SPLIT(path, "/")[OFFSET(3)] from www

スラッシュの最後を取る
ARRAY_REVERSE(SPLIT(aaa, "/"))[SAFE_OFFSET(0)]
引き当てが無い場合はSAFE_OFFSETはNullを返し、OFFSETはエラーを返す

BigQueryの標準SQLでGROUP_CONCATしたいときはSTRING_AGG - GAミント至上主義 (hatenablog.com)
逆にまとめるには
SELECT type, STRING_AGG(DISTINCT name) FROM testData GROUP BY type;
赤身 | ブリ,いわし,アジ,マグロ,カツオ,サバ
白身 | タイ,タラ,フグ,サケ

///Job kill
CALL BQ.JOBS.CANCEL('job_id')
CALL BQ.JOBS.CANCEL('project_id.job_id')

job idでエラー詳細を確認
bq show -j
bq show --project_id bangboo_sandbox --format json -j bqjobidxxxxxxxxxx | jp .
 job idはコンソールのBQのジョブ詳細やスクリプトキックならロギングから見つけてもいい
 クエリならjob/query historyでわかるがbq cmdでもエラーが返る
  bq query --nouse_legacy_sql 'select ketsu from `prj`.oshi.ri'
  unrecognized name: 'kusofuke@ketsu.com' at [1:149]

select * from prj.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
where job_id ="aaaaa" and creation_time > "2022-01-01"

ジョブIDの取得
SELECT
 project_id,
 job_id,
 user_email,
 creation_time,
 start_time,
 --query,
 total_slot_ms
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_USER
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_FOLDER
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE state != "DONE"
 --state = "RUNNING"
 --state = "PENDING"
AND user_email = 'my@email.com'
AND project_id = 'paa'
AND start_time < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 MINUTE)
AND total_slot_ms > (1000 * 30)
AND PARTITIONDATE BETWEEN '2021-01-01' AND '2021-01-02'
 --PARTITIONTIME BETWEEN TIMESTAMP('2021-01-01') AND TIMESTAMP('2021-01-02')

///upsert(アップデートか新規インサート
https://swfz.hatenablog.com/entry/2021/02/08/195024
MERGE aaa target USING tmptbl src
 ON target.time = src.time
WHEN MATCHED AND src.satus = 'rejected' THEN
 DELETE
WHEN MATCHED THEN
 UPDATE SET ...
WHEN NOT MATCHED THEN
 INSERT ROW

///window関数
集約関数(GROUP BY)だと個別データは出力されず集計データだけでるが
window関数だと集計データが個別データにouter joinされた形で出力される

SELECT
  deptname,
  id,
  salary,
  AVG(salary) OVER (PARTITION BY deptname)
FROM emp;

  deptname  | id | salary |  avg_salary
-----------+-------+--------+-------------
 dev        | 11 |   5200 |        5020
 dev        |  7 |   4200 |        5020
 dev        |  9 |   4500 |        5020
 dev        |  8 |   6000 |        5020
 dev        | 10 |   5200 |        5020
 hr         |  5 |   3500 |        3700
 hr         |  2 |   3900 |        3700
 sales      |  3 |   4800 |        4866
 sales      |  1 |   5000 |        4866
 sales      |  4 |   4800 |        4866

deptnameでグループしそのsalaryの集計のAVGが出ている
下のようにover()が空でも良い、4900は大体

SELECT
  deptname,
  id,
  salary,
  AVG(salary) OVER () AS avg
FROM emp;

  deptname  | id | salary |  avg
-----------+-------+--------+-------------
 dev        | 11 |   5200 |        4900
 dev        |  7 |   4200 |        4900
 dev        |  9 |   4500 |        4900
 dev        |  8 |   6000 |        4900
 dev        | 10 |   5200 |        4900
 hr         |  5 |   3500 |        4900
 hr         |  2 |   3900 |        4900
 sales      |  3 |   4800 |        4900
 sales      |  1 |   5000 |        4900
 sales      |  4 |   4800 |        4900

関数としては集計関数がそのまま使えるようだ
OVERはwindow関数を使う宣言、OVERの後にどのようにwindowを作るのかを定義
PARTITIONでwindowでつまりどの範囲でグループを作るか指定
 AVG(salary) OVER (PARTITION BY deptname, sub_deptname) でサブデプト単位での平均となる

///誰が実行しているかをセッションユーザで出す
標準 SQL のセキュリティ関数  |  BigQuery  |  Google Cloud
SELECT SESSION_USER() as user;
+----------------------+
| user                 |
+----------------------+
| jdoe@example.com     |
+----------------------+

///エラーハンドリング
BQのクエリ内の条件によりerror()でエラーが吐ける
 select error('id is not unique.') from tbl having count(a) > 1
 ERROR関数を使ったBigQueryデータ異常検知例 #BigQuery - Qiita
 SQだとメール送信したり、ロギングやモニタリングでエラー検知できる

///プログラムで使う
from google.cloud import bigquery
client = bigquery.Client()
QUERY = ('SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013`')
query_job = client.query(QUERY)
rows = query_job.result()
for row in rows:
    print(row.name)

///Pythonも含めトランザクション
/// BANGBOO BLOG /// - GCP script

///承認済みビュー authorized view
authorized viewを設定するとそのviewを対象とする権限だけ必要で権限をさかのぼり付与しなくていい(通常のviewは参照元の権限も必要)
 この権限移譲は閲覧権限のみで編集権限等は含まない
被参照の元テーブル側に許可するview名を設定する
 参照権限は緩くなるが、編集権限は厳しくなる(設定するビューは変更しない前提で承認する形)
authorized viewを付与すると玄関となったビューはdataEditorではビュー更新ができなくなる
 玄関ビューにも、ソーステーブルにもEditor権限が必要
 基本の安全策はauthorized view設定を外す>ビュー変更>AV再設定がいい
  対象のauthorized viewは管理者を立て一元管理するのが良さそう
  (テーブルやビューを作って権限付与してバッチだとdata ownerが必要なのは注意)

■saturationの場合、詰まっている、サチっている
対象にクエリを発行 select 1
同プロジェクトの他のテーブルにクエリを発行 select 1
別プロジェクトから対象にクエリを発行 select 1
reservationsのoverviewを見る
対象のSQLを発行
別のプロジェクトで同SQLを発行
 時間を比べる
Google側の問題と思われるときはGoogleのサポートへGo
Google Could Status Google Cloud Status Dashboard

INFORMATION_SCHEMA < Audit log で調査
メタデータ(データに対するデータ)
 システムメタデータ(作成更新日時、サイズ、誰いつ参照
 ビジネスメタデータ(オーナ、更新頻度、カラムの意味
select * from prj.ds.INFORMATON_SCHEMA.TABLES
select * from prj.ds.INFORMATON_SCHEMA.PARTITIONS
 longterm storageでサイズが100000b以上で、更新日が1か月以上とか出せる
select * from prj.ds.INFORMATON_SCHEMA.COLUMNS where column_name like '%kuso%'
select * from prj.ds.INFORMATON_SCHEMA.VIEWS where view_definition like '%kuso_table%'
 view_definitionはSQL文が入っている
select * from prj.ds.INFORMATON_SCHEMA.JOBS_BY_(USER / PROJECT / ORGANIZATION)
 誰アクセス/誰作った/何Job等も分かる、180日しか出せないが
 roles.bigquery.resourceViewerが必要
 カラム例:user_email、query、referenced_tables
Auditlogは プロジェクト間で使用されるBQでも情報が取れる
 info_schemaのjobs_byとほぼ同じ内容が取れるがよりリッチ
  利用ユーザ数、旧データを見ている人、権限変更操作ログ等

SELECT `b-sandbox`.test_ds.count_row(1); で実行できる
UDFやテーブル関数のルーティンを承認しておくと誰からでも使える(ビューと違い権限管理できずセキュリティがズブズブになると思われ)
 target_prj.trg_dsに受け入れる関数を共有指定する形
 UDFは戻り値がある、テーブル関数は副問い合わせとして使う形か

///ScheduledQueryの実行者
コンソールの場合:コンソール操作者
Terraformの場合:Terraform実行者
bqコマンドの場合:任意に設定ができる
サービスアカウントをbqコマンドでSQ実行者として登録する場合、通常は問題がないがスプレッドシートを使用するなら@プロジェクト名.iam.gserviceaccount.com等でアクセス権が必要なため、会社のポリシーによってはうまく行かない。batch@unco.comのような共通メールを作成し使用したい。(GWS側でOUを使いTrusted ruleによりSAにGoogleDriveへアクセス許可すると問題回避できるが:OUをつくりそのOU内で専用共有ドライブを作成し設定する)

サービスアカウントにScheduleQueryを実行させる設定に必要な権限
https://cloud.google.com/bigquery/docs/scheduling-queries?hl=ja
操作者
 BQ job user
 BQ transfers.get/update
 BQ data viewer/editor
 ●iam ServiceAccountUser
サービスアカウント
 BQ job user
 BQ transfer
 BQ data viewer/editor

Scheduled queryからの保存先
コンソールだと同じプロジェクト内だが、create文を自由記載ならどこでもOK
job userは同じプロジェクトの権限が必要

設定者一覧を出したい場合
bq --format=json --project_id=bangboo-oketsu ls --transfer_config --transfer_location=us | jq.[].name
bq --format=json show --transfer_config project/1111111/locations/us/tranferConfigs/111111 | jq .ownerInfo.email

■BQ transfer(クエリが不要なBQ連携、3rd partyもあり)
データセットコピー、GCSファイル
Ama S3, Azure storage, Oracle, Salesforce, Ads系等々

■Cloud SQLにBQからクエリ
SELECT * FROM EXTERNAL_QUERY("connection_name", "SELECT * FROM db.tbl")
https://zenn.dev/ykdev/articles/4a4d2fbc6b4fe1

■BQ DMLクォータ超過
割とSQLだとすぐに壁にあたる
上限がテーブル単位のためテーブル名を分けると回避できるらしい
BQ streaming insert->BQ storage read/write APIの上限はDMLと別で、閾値が大きい

APIだとProtocol buffersが必要で、Date/Timestampが対応しておらず
Unixエポックからの日数/秒数への変換が必要、、、

■SQLはカラム数の増加数で構成考える?
left outer joinはカラム数がカラム数の合計から共通のjoin onのカラム数を引いた数(行数はleftに同じ)
 full outer join はカラム数がカラム数の合計から共通のjoin onのカラム数を引いた数(行数はleftの要素数にrightの要素数を合計したもの)
unionは重複を除外し表を足し合わせるため行数が両表の合計行数(カラム数は合致必要でカラム数は変わらない)
unian allは重複を除外せず表を足し合わせるため行数が両表の合計行数(カラム数は合致必要でカラム数は変わらない)
cross joinはカラム数が両表のカラム数の合計、行数は両表の行数の掛け算
 再帰的にSQL処理はcross joinし条件を付けるか?
  標準SQLのFrom句のカンマはcross joinとなる
with句は副問い合わせを見やすくしたもの
distinctで(組み合わせで)一意になる行のみにし重複を省く
UNION とUNION ALLの違い - Qiita
CROSS JOIN (クロス結合)を使ってデータを取得する - JOIN (結合)を使いこなそう - SQL Server 入門 (sql55.com)
SQLのDISTINCTとは?(OracleやMySQLで使用する方法) | IT職種コラム (it-kyujin.jp)

デカい表をいくつか持ちJOINすると再帰的にWhere句で条件検索しなくてよい

■課金
クエリ課金:使用しているプロジェクトで課金される、データの置き場所ではない
 定額フラット:$2000/100slot/m(全プロジェクトでスロットを共有)、オンデマンド:$5/T=2Gスキャンで1円位
  flat rateでもflex slotsとして時間帯によりスロットを増やす等ができる
   Editionsに変更になった:組織に5プロジェクト等しかreservationを置けない、その中で限りなく設定ができる
 課金を減らすには:カラムを減らす、パーティショニング
  プレビューを活用:しかしビューだとプレビュー機能はない。列が501列以上あったら501列以降はプレビュー出ない
データ保管課金:データ量
 $1/50G/m
 active storageからlong term storageへの移行は自動(90日変更がない、50%off)
6,000スロットを使うBigQueryのリソース配分最適化への挑戦 (plaid.co.jp)

■権限
事前定義ロールと権限  |  BigQuery  |  Google Cloud
job user:select文クエリ実行だけでもジョブでjob userとdata viewerが要る(data viewerだけでは不足)
 課金プロジェクトでjob userを持ち、参照先プロジェクトでdata viewerを持つという権限構成だから
 例えばjob userがなくdata ownerだけの場合はデータセットやテーブルやビューの削除作成ができるが、データロードやselect文発行はできない
IAMかデータセット/tblに必要な権限を付与する
 data editorでも自分で作成したものは自分がOwnerになり削除や変更権限がある
meta data viewerならDSとテーブル一覧、テーブルのスキーマや容量等の情報が見れデータは見れない
 これを広く付けておくとデータ管理が楽

■サービスアカウントに対するBQ job user
コンソールであれば画面左上の請求先プロジェクトで切り替えができるが
スクリプトであればgcloud auth login時に切り替える
gceならインスタンスにSA設定するが
 請求先プロジェクトのデフォルトはインスタンスの置いている/SAが作成されたPrj
  ※同プロジェクトからしか選択ができない
 コード上で切り替えができる
  bq --project_id=xxx query 'select count(*) from ds.tbl'

■BigQueryの列レベル・行レベルのセキュリティ
個人情報や機微情報を隠す
BigQuery の行レベルのセキュリティの概要  |  Google Cloud
行レベルなら同じテーブルを使うので同じダッシュボード/Appが使える(AuthorizedViewの方が柔軟だが)
データ マスキングの概要  |  BigQuery  |  Google Cloud
列レベルアクセス権以外にもマスクの種類があり、ハッシュだったり先頭4文字や末尾4文字等で共通文字化としてマスク化できる
BQ画面>左ナビのポリシータグ
 ポリシータグを作成(組織単位で一括一覧表示)
  タグは階層化できるので、全ユーザタグ>管理者タグ>社長タグ
 スキーマ>Addポリシータグ
  タグが付いていればプレビューで見れない
  select * except(tag_column)にする必要がある
  メタデータは見れる(カラム名、型
 ポリシータグ画面>対象ポリシー選択>情報パネルで権限者一覧
  fine-grained readerを付与するとselect *ができるようになる
   社長タグに社長だけ権限付ける等
※APIを有効にし、ポリシーを有効にする必要がある

■マテリアライズドビュー
実体データを保持しリフレッシュ更新で早いため集計等に向く
ベーステーブルは一つ、カウントができない、使用できない関数がある等の制約がある
またマテビューはビューを元に作成できずテーブルからである必要がある
ストレージコストは掛かるが、通常ビューで時間掛かる計算を頻繁にする場合は早く安くなる可能性がある

■IAM(Identity and Access Management) 
/// BANGBOO BLOG /// - GCP


Posted by funa : 01:00 AM | Web | Comment (0) | Trackback (0)


February 11, 2021

Python Python
■importとfrom
Pythonのモジュールとimportとfrom入門 - Qiita
Python, importの使い方(from, as, PEP8の推奨スタイル, 注意点など) | note.nkmk.me
Pythonインポート周り徹底理解への道 - Qiita
Pythonの相対インポートで上位ディレクトリ・サブディレクトリを指定 | note.nkmk.me

標準ライブラリならimport文を本体に書いていれば良い
 標準ライブラリ以外はPyPI(Python Package Index)と呼ばれる3rdパーティライブラリから
 pip(The Python Package Installer)インスコ

import文を使って下記の3つなどをインポートし使う
 標準ライブラリ
 pipでインスコしたパッケージ
 自作のパッケージ
自作は大体わかるがそれ以外はどこにあるのか?
 $ python
 >>> import sys
 >>> sys.path
 でパス一覧が出るので探すと分かる >>> exit()でpythonコマンド終了
例えば Cloud functionsなら requrements.txtに google-api-python-client==3.3.2と記載し
 PyPI · The Python Package Index でバージョンを探す
コードに from google.cloud import bigqueryと宣言する
 requirementがpipインスコ

import フォルダ.ファイル名
from フォルダ.ファイル名 import *
 上下同じだが、fromは一部を指定し直接使うという意、*は非推奨
 つまり
import hello なら下記とする必要があるが
 print(hello.hello)
from hello import hello なら省略ができ下記で良い
 print(hello)
from フォルダ名 の場合
 そのフォルダ名の中に __init__.pyがあれば其れ
from .xxx import aaa の.の意味は?
 mainに対するモジュールから見て相対で隣

モジュール検索パスを出す
from pprint import pprint
import sys
pprint(sys.path)

■pipインスコ
pipの使い方 (2014/1バージョン) — そこはかとなく書くよん。 ドキュメント (tdoc.info)
Python:pip における管理者権限と user install - pyてよn日記 (hatenablog.com)
Python でパッケージを開発して配布する標準的な方法 - Qiita
pythonのsetup.pyについてまとめる - Qiita
PyPIでサードパーティライブラリを管理していてインスコ可
setup.pyが含まれたローカルディレクトリも指定しインスコ可
eオプションで編集可能な状態でインスコ
--userで~/.local下の管理権限不要なユーザディレクトリ以下でシステムが汚れない
--userなしで/usr下にインスコ
pip install --user -e unko
pip3 install pipenv
pip list インスコ済みのものを確認

pip install -r requirements.txt reqirements.txtで一括インスコ
pip freeze > r.txt pip listをファイルに書き出す
pip uninstall -y -r r.txt -yで確認なしで一括アンインストール
Python, pipでrequirements.txtを使ってパッケージ一括インストール | note.nkmk.me

パッケージとバージョンを指定してアップデート
pip install -U google-cloud-bigquery==3.4.0

下記にもろもろ
pipでパッケージをupdate|pip自体のアップデートについても解説 (itc.tokyo)

■envツール
 pyenv install --list インストールできるもの
 pyenv install 3.8.8 指定verをインスコ
 pyenv global 3.8.8 デフォルトに指定
 .python-versionファイルをGITに載せ管理したい?
 pipenvはPipfileとPipfile.lockを利用しpipでrequrements.txtを用いるよりも強力
  PipfileとPipfile.lockとrequirementsをGITに載せ管理したい?
 pipenv --python 3.8.8 など最初にpyバージョンをpipfileに記載
 pipenv install "google-cloud-tasks==1.5.0" バージョン無しでも有りでも入れられる
 Pipfileを書き換える方法
  [packages]
  google-cloud-tasks = "==1.5.0"
  protobuf = "*"
  そして下記cmdでインスコ
  pipenv install PipefileからインストールしPipefile.lockを更新
 pipenv sync Pipfile.lockの最新を取得し環境更新(Pipefileは使わない)
 pipenv shell 仮想環境を起動
 pipenv run python main.py
 他に
 pipenv uninstall google-cloud-tasks アンインスコ
 Pipfile, Pipfile.lockがあれば pip syncでOKだがrequirements.txtも使える
 pipenv lock -r > requirements.txt 生成
 pipenv install -r requirements.txt
pipenvのバージョンが古いと依存関係、Ver整合性で問題が起きやすい
 pipenv --version
 pip install pipenv
 pipenv update
 pipenv upgrade <パケ>でやり直す

■assertでテスト
assert文は組み込み定数__debug__がTrueの時のみ実行されます
実行コマンドにオプションに-Oをつけると__debug__がFalseになりassert文が無効に
def func_so(a, b):
c = a * b
return 
def test():
assert(func_so(1,2) == 2)
if __name__ == "__main__":
test()
main()

■個別
import dataclasses
[詳解] Pythonのdataclasses (zenn.dev)
 データ格納するオブジェクトを作れば使い回しが楽
import datetime
pip install pyyaml > import yaml
pip install requests > import requests

Python + VSCode の環境構築 20240604 (zenn.dev)


↓本家
/// BANGBOO BLOG /// - Python

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


February 10, 2021

Python
おッPythonやるのか?

ファイル拡張子oppython.py デフォUTF-8、全部オブジェクト(list,dict,set等のミュータブルなら参照になる点に注意、必要ならcopy())
#コメント、ドキュメントストリング(三連引用符):"""そのまま表示""" print mymod.__doc__で見れる
変数型不要:p = 500 * num、でもキャストは必要、定数はない
文字繰り返し、キャスト:"文字列" * 4 + str(p) + "Hi\nお元気ですか?\nSee u"
raw文字列でescしない:print(r"インストール先は c:\\code\python\bin です")
 正規表現のrも同意 re_result = re.match('hel', r'hellow python, 123, end.' )
  if re_result: #None以外という意味で、Noneはいわゆるnull、Pythonにnullはない
文字数:len("東京都")→3
文字列[開始:終了]→→ str = "Flower" print(str[1:4]) → low
文字列 % (値1, 値2, ...)→→ num= "10進数では %d 、16進数では %x " % (num, num)
"xxxx{index:書式指定子}xxxx".format(値)→→ "名は{:<8s}で年は{:>3d}で".format(name, age)
f"xxxx{値:書式指定子}xxxx"→→ f"名は{name:<8s}で年は{age:>3d}で" 
0/空の文字列''/値なしはfalse、Noneは? x = None x is None→→true?
//→除算切り捨てし整数、**→べき乗
関数宣言はdef kansu(): で中で宣言する変数はローカル変数
 関数外で宣言された変数はグローバル変数でどの関数の中でも扱えるようになる
 なお関数内でもglobal henでグローバル変数を宣言できる Pythonでのグローバル(global)変数の宣言方法 | UX MILK
返り値複数はcsvでタプルになる、リストが楽か? return a,b → (a, b) あるいは return [a, b] → [a, b]
def func(a, b):
return a, b
result = func()
 result[0]がa、result[1]がb
try/exceptを関数内で設定することも、逆に関数呼び出し時にも使用ができる、else, finally, raiseも使う、エラーが出ても止めたくない場合は try-except Exceptions as e、逆にexceptを入れなければ止まるので安全
try:
get_all_transfer(project_id)
excerpt Exception as e:
print(e)
置換は左辺が要る? a = a.replace('x','')
とほほのPython入門 - リスト・タプル・辞書 - とほほのWWW入門 (tohoho-web.com)
Pythonの辞書とリストとクラス 複数情報の受け渡し|みはみ|note
リストa=[1,2,3]はmap(), filter(), reduce()等が使える
 a=a.append()とかa=a.extend()は値がないんで駄目、単純にappend(b)やextend(b)で左辺不要
 取得:a[0]、for v in a:
 リストの合体:list_a += list_b
セット型set={1,2,3}は重複や順序や添字の無いリスト、set(list)でキャストし重複を無くせる、ミュータブルは格納できない
 取得 for v in a:
tuple→タプルは定数リスト、更新無しならリストより速い a = 1,2,3 a = (1, 2, 3)
 取得:a[0]、for num in a:
dict→辞書は連想配列みたいな{a:1,b:2}はitems(), keys(), valus(), iteritems(), get()を使える
 Python | 辞書に含まれるすべてのキーと値を取得する (javadrive.jp)
 取得:dict_a['key1']、for k in dict_a.keys(): for v in dict_a.values(): for k, v in dict_a.items():
 dictの合体:dict_a.update(dict_b)
クラス→例えば●●クラスを宣言しsampleインスタンスを生成し、getter/setterで変数に入れて置く
 取得:sample.key
BigQuery→別名を付ければ名前で取得できるが、インデックスでも取得できる(これ何?)
 取得:for row in query_job: →row[0], row["t"]
lambdaは無名関数?
str_w = input('何か入力してください-->') #入力させた値を取れるが数字もstr
__iter__()はnext()を持つオブジェクトを返し、next()は次の要素を返し、最後に達するとStopIteration例外を返す?
yield はイテレータを返すジェネレータを定義?
@デコレータは関数を実行する前後に特殊な処理を実行したい場合?
withで終了処理を指定できる、ファイル読込とその後の処理とか
assertや__debug__はテストで機体通りかを確認する?
passは中身の無い関数やクラスを作成しkara.p=1で粋なり属性追加等ができる
execは引数の文字列をPythonとして実行 exec "print 'Hello'"
delはオブジェクトを削除 del x, y, z
継承やオーバーライド class MyClass2(MyClass):
多重継承class MyClassC(MyClassA, MyClassB): で纏めて使えるようになる
class MyClass:
    """A simple example class"""  # 三重クォートによるコメント
    def __init__(self):  # コンストラクタ
        self.name = ""
    def __del__(self): #インスタンスが消滅する際に呼出でコンストラクタ
        print "DEL!"
    def __str__(self): #文字列化
        return "My name is " + self.name
    def getName(self):  # getName()メソッド
        return self.name
    def setName(self, name):  # setName()メソッド
        self.name = name
class MyClass2(MyClass):
    def world(self):
        print "World"
class MyClass3(MyClass):
    def hello(self):  # 親クラスのhello()メソッドをオーバーライド
        print "HELLO"
a = MyClass()  # クラスのインスタンスを生成
a.setName("Tanaka")  # setName()メソッドをコール
print a.getName()    # getName()メソッドをコール
print a  #=> My name is Tanaka 文字列化
b = MyClass2()  #継承
b.hello()    #=> Hello
b.world()    #=> World
c = MyClass3()  #オーバーライド
c.hello()    #=> HELLO
super()を使ってオーバーライドする
 super()は基底クラスのメソッドを継承した上で処理を拡張
 super().__init__(x、y)が使える
with構文で処理の前後で__enter__、__exit__を使う
 __enter__メソッドで事前処理
 __exit__メソッドで事後処理
if __name__ == "__main__":
 モジュール時の勝手実行を抑える
  import helloの時hello.py 内部での __name__ は "hello" 
  python hello.pyのような実行時hello.py の内部の __name__ は "__main__"
from math import pi, radians→mathモジュールから特定のオブジェクト(関数/変数/クラス)をimpo(math.piみたいに書かず省略できる)
import urllib.error→urllibパッケージからerrorモジュールをimpo、パッケージはフォルダ
import numpy as np→別名でしか使えなくなるnp.array()とかで
 モジュール=ファイル名.pyでファイルをimpoしている
from {another_file} import {ClassName}
 another_file.pyがファイル名
 class ClassNameがクラス名
from {パッケージ:ディレクトリ} import {モジュール:ファイル}
 ちゅー書き方もできるらしいが、どっち?
impo順:標準ライブラリ>サードパーティライブラリ>ローカルライブラリ(自作のライブラリ)

関数や変数:小文字スネークケース(sample_func)
クラス名、例外、型変数:キャピタルパスカルケース(SampleClass)
定数名:大文字アンダースコア区切り(SAMPLE_CONST)
モジュール名:小文字(samplemodule, sample_module)
パッケージ(フォルダ)名:小文字。アンダースコア非推奨(samplepackage)

インデントは半角スペース4つ
1行半角で79文字以内
トップレベルの関数やクラスは2行開ける
クラス内部では1行ずつ開けてメソッド定義
ドックストリングでクラスや関数についてコメントする(慣習的にダブルクォート)
 コード中は処理についてのコメントをなくし関数化とdocstringで参照するように
 「コメント(#)とdocstring(""")の違いは?」コメントとdocstringについて
 [Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル) - Qiita

デバッグの方法案
print(type(v)) でどんなメソッドを持っているか等を探る
print(v) をコマンド前後や流れで沢山仕込みでどこでエラーが出ているか探す
is not subscriptableのエラー 添字不可エラーでリストでないのにリストとして入れようとしている

※参照になりコピーされない、必要ならコピー(値を入れた時点で参照が外れるので実際問題少ない?)
a = []
b = a
b.append(1)
print(a) #[1]
https://qiita.com/ponnhide/items/cda0f3f7ac88262eb31e
https://nishiohirokazu.hatenadiary.org/entry/20120125/1327461670

環境変数を扱う
 import os
 print(os.environ["HOME"]) ホームディレクトリ、LANGでja_JP.UTF-8とか
 os.environ["PHASE"] = "staging" 環境変数に代入できるのは文字列だけ
 del os.environ["PHASE"] 削除
コマンドラインの引数を扱う
 python3 sys_arg_test.py a 100
  dst_prj = sys.argv[1] (aが入っている)
  sys.argv (['sys_arg_test.py','a','100']

Pythonのリストと文字列を相互に変換する方法まとめ | HEADBOOST
→リストをStrに変換してSQLにする場合For文が良い(Pythonの書式とSQL書式のコンビなので丁寧に対処するため)
i = 0
v = "["
for s in list_v:
    i += 1
    if i > 1:
        v += ","
    v += "'" + s + "'"
v += "]"
SQL = "insert into aaa (aaa) value ({v})"

※テキスト選択
 Shift↑or↓ で行全体
 home(+fn)で行頭、end(+fn)で行末移動

【基礎一覧】Pythonの基本文法を全て解説してみた!【初心者】 (suwaru.tokyo)
Python基本文法まとめ - Qiita
とほほのPython入門 - とほほのWWW入門 (tohoho-web.com)
Python入門 ~Pythonのインストール方法やPythonを使ったプログラミングの方法について解説します~ | Let'sプログラミング (javadrive.jp)
Welcome to Python.org

HTMLの中に少し埋め込めず、基本的にプログラムの中にHTMLを埋め込む:CGI(Perl然)
 さくらインターネットでPython CGI (mwsoft.jp)
WSGI Python で WSGI (Web Server Gateway Interface) に従ったシンプルな Web サーバで Hello World - Qiita
Python用Webサイト用途フレームワーク:Flask(軽量)、Django
 WSGI について — Webアプリケーションフレームワークの作り方 in Python (c-bata.link)
 GCPでどう使うかは不明だがホスティングは↓
 ウェブ ホスティング | Google Cloud 静的ウェブサイトのホスティング  |  Cloud Storage  |  Google Cloud

str.split() 区切り文字で分割しリスト等に入れる Pythonで文字列を分割(区切り文字、改行、正規表現、文字数) | note.nkmk.me
print('Sam' in 'I am Sam') # True 任意の文字列を含むか判定: in演算子 Pythonで文字列を検索(〜を含むか判定、位置取得、カウント) | note.nkmk.me
==============
ここで動かせるgoogle colaboratory→ Colaboratory へようこそ - Colaboratory (google.com)

コラボラトリはマークダウン Qiita マークダウン記法 一覧表・チートシート - Qiita
半角スペース2個で改行
#の数で見出し
*で箇条書き
数字と.で番号を振る、- でリスト
* or - or _ を3つ以上で水平線
[ ]でチェックボックス、[x]でチェック
| td | td | td |でテーブル
**aaa**で太字、*aaa*で斜体
~~aaa~~で打消し線
[タイトル](URL)でリンク
```でコードの挿入、`でインライン挿入
> or >> で引用
 [^1]で注釈
\バックスラッシュでマークダウンのエスケープ

==============
宗教論争(事実は同じでも他人の認知は違うので意味なし
if self.flag_ok == 1 and self.mode == '1'
↓一見で分からんなら変数名を工夫してこうやんな
if self.file_verify_completed and self.mode == GRANT_PERMISSION:

マジックナンバーを使わない(数字の方が曖昧性が無い場合も)
STATUS_ERROR = -1
STATUS_SUCCESS = 0
self.status_error = STATUS_SUCCESS

初期値をエラー値にし、業務判定エラーでステータスを設定したらreturnで抜ける
def exFunction(self):
self.status_error = STATUS_ERROR
try:
if XX = AAA:
self.status_error = STATUS_XX_ERROR
retrun
self.status_error = STATUS_SUCCESS
retrun
except:
~エラー処理、ステータスは変更しない

エラーメッセのハードコーディングを避ける方法(ハードが場所と内容が分かり易いかも)
MSG_ERROR_OLD_EMAIL = "Error: 旧メール%sです\n"
e_message_list.append(MSG_ERROR_OLD_EMAIL % (old_email))
self.error_message = '\n'.join(e_message_list)


ケチって分厚い本1冊にしたが全然進まぬ、薄い奴星e、?チッPython、誰がJSONじゃ~い、チェーンソー魔わすっぞ

続編、、モジュールとかmportとか、
/// BANGBOO BLOG /// - Python Python

Posted by funa : 07:30 PM | Web | Comment (0) | Trackback (0)


January 27, 2021

Framework
群雄割拠か弱肉強食か政治解決か遣りたい放題の中、当事者なら自然に身につくだろうが時代に参加していない貴殿には到底分からない、シルバーブレットはなく結局は愚直しかない、どう愚直になるか/どう立ち回るかを発見するのがフレームワークだ、もしトレンドを感じればそれに乗ればよい、他にシーズがあればプロダクトアウト、ニーズがあればマーケットインだ

■フレームワーク
3C(Customer/Competitor/Company:自社)
SWOT(Strength-Weakness x Opportunity-Threat)
PEST分析(Politics/Economy/Society/Technology)
3M(人物金、Men/Material/Money)
3M(ムリ:負荷が人に掛かる/ムダ:資源が余り浪費しコスト高/ムラ:負荷と浪費が交互)
7S(<3sはハード>Structure/Strategy/System、<4sはソフト>Shared value:価値観/Skill/Staff/Style:文化)
VRIO(Value/Rarity/Inimitability:模範困難性/Organization)
MVV(Mission:使命why/Vision:将来像what/Value:価値観how)
マーケ4P4C(4p:product/price/place/promotion, 4c:customer cost/customer cost/convenience/communication)
QCD(Quarity品質/Costコスト/Delivery納期)

ポーターの5forces(Competitive Rivalry:競争企業間の敵対関係/Supplier Power:売り手の交渉力/Buyer Power:買い手=顧客の交渉力/Threat of Substitution:代替品の脅威/Threat of New Entry:新規参入業者の脅威)
コトラーのSTP(segmentation:顧客やニーズや特性等で細分化/targeting:セグメ選択/positioning:勝てる位置取り)
競争戦略ポジショニング (コストや差別化や集中戦略等で業界ポジを練る)
PPM:product portfolio mgt(市場成長率xシェア->問題児:花形に育てる/花形:継続投資/金のなる木:投資無し/負け犬:撤退検討)
製品ライフサイクル:PLC(導入期:認知度と需要up/成長期:製品多角化販路拡大/成熟期:差別化とコストダウン/衰退期:選択と集中効率化)
イノベータ理論(Innovators/Early Adopters/Early Majority/Late Majority/Laggards:16%キャズム:段階で戦略を変えていく)
RFM(recency/frequency/monetary->優良顧客を見つけよりマーケ)
ポーターのバリューチェーン(企画/開発/購買/製造/物流/販売/サービス/人事の各々での価値->VRIOで分析)
アンゾフの成長マトリクス(既存市場浸透:既存市場x既存商品/新市場開拓:新規市場x既存商品/新商品開発:既存市場x新規商品/多角化:新規市場x新規商品)
TOWS(クロスSWOT分析:SWOTをSWOTする->SWOTで現状分析、さらにSWOTで戦略化)
SCAMPER(アイデアの展開->substitute代用/combine結合/adapt応用/modify修正-magnify拡大/put to other uses転用/elininate削除-minify削減/reverse逆転-rearrange再編集)
ECRS:イクルス(改善策->排除/統合/交換/簡素)

ギャップ分析(As Is/To Be<-間にaction)
特性要因図:フィッシュボーンチャート(要因を網羅的に調べる、他にも親和図法やマインドマップ)
意思決定マトリックス(縦軸に候補、評価基準を横軸、評価基準に重みをつけて点を出し、合計の総合点で判断)
CS/CE分析(Customer satisfaction/Customer expectation->各機能のcsをceに合わせる、ce高cs低の改善)
リスク評価マップ(インパクトx不確実性、インパクト大に対処し小は静観、不確実性が高いと注意が必要<-pest/5f)
AIDMA...etc...

ユダヤの商法:78対22の法則で上手くいく、契約主義で約束を守る
ケイパビリティ戦略:ビジネスプロセスを能力化、スピード/整合性/明瞭性/俊敏性/革新性が上がる、CEOがツールや組織を検討
ポジショニング戦略:競合との位置付け、STP分析をしどうポジションを取り差別化するか
タイムベース競争戦略:時間こそが希少資源、スピードが一番顧客満足が高い、数稼ぐ
アダプティブ型戦略:多くの新しいアプローチを試し最も有望なものを拡大展開、PDCA、やらな分からん時代

ランチェスターの法則:
奇襲/武器/集中、逆にシェアトップで武器も兵数あると模倣し広域戦
 自分を知る、競合を知る、シェア1位を知る
 地域限定、顧客志向営業、販路、陽動奇襲の企画、強みに集中

■逆転の競争戦略
競合の弱みを攻撃するのがセオリーだったが、イノベーションのジレンマでひっくり返す(客の意見を聞きすぎると安い慣れた商品を求められるが自ら革新を進め避けるべき、サンクコストや業界しがらみを乗り越えるべき)
業界破壊者(枠を壊す)/侵入者(他業種からの参入)/挑戦者(競合が攻撃)がトップシェア企業を脅かす
1)企業資産の負債化=リーダーが持つ競争優位の源泉を攻めリーダーが蓄積してきた優位な経営資源を価値のないものにし負債にしてしまう戦略:モスは店内で調理しマックより優位に、あるいは逆にセントラルキッチン
2)市場資産の負債化=リーダー企業に有利に働いていた競争のルールを変更し、顧客が持つ資産(ソフトウェア、交換部品など)を使えなくする戦略:VISAよりQRのPaypay
3)論理の自縛化=安易に追随するとリーダー企業が発信してきたメッセージと矛盾することになり、企業イメージを低下させてしまう戦略:手作り丁寧より100均
4)事業の共喰化=リーダー企業が強みとしてきた製品・サービスと共喰い関係にあるような製品・サービスを市場に出すことで、リーダー企業内に追随するか否かの不協和音を引き起こす戦略:カーシェア
ランチェスター戦略、マイケルポーター競争優位の戦略

ーーーーーーーーーーーーーーーーーーーーーーーーーー
■現代思想
ニーチェ:ルサンチマン、奴隷道徳<>快と力の高揚感が生を肯定、ニヒリズム
マルクス:神格化、砂漠の水を都市で売ろう、紙一枚が命より大事…社会的関係の錯覚
フロイト:無意識<>理性、理性は単なるハリボテであり無意識が主人で自律神経も管理
 エス(快楽主義)>自我:Ego(調整役)>超自我:Super ego(親/社会/会社の価値観の同一化)
  親や社会等から裏切られると同一化できずトラウマ、葛藤を無意識化に隠したい
ユング:Collective unconscious(人類は人種に限らず同じ記憶を持っている)

ーーーーーーーーーーーーーーーーーーーーーーーーーー
■リーダーシップで面白いほど結果が出る本
(仕事の種類)リーダシップ分類:指示/率先/構想/合意/育成/関係構築
  リーダシップ→変化、コントロール→維持(基本どちらもPDCA)
  若手に新しい変化のリーダシップが期待されている
(担当)鷹の眼と蟻の眼(大きな視点の戦略+現場の改善)
(頭脳)1)構想力、2)推進力、3)育成力
  →アイデア発表、ダメ出し、頼りにされる
1)構想力:戦略をゲームとして導入する、仕事の意味を伝える、今を楽しむフロー没入
2)推進力:手段の目的化を防ぐダメ出し、メンバーに寄り添う:会話の時間が足りない、現場のアイデアや成功事例を吸い出し
3)育成力:個々人の心のベクトルを少しプラスに、共通言語の定着(これがないと心の障壁や違和感)
(発想は言葉から、リーダは言葉が大事)

ーーーーーーーーーーーーーーーーーーーーーーーーーー
JCOM回線不安定:
インターネット回線の信号レベルはタブレットで通信でモデムに入って測れる
宅外でモデムを繋いででも宅外で調査しろ
同時接続数等々でスロットリングしているだろうが

Posted by funa : 03:00 AM | Column | Comment (0) | Trackback (0)


January 21, 2021

Who watches

心拍数は実感でよいが、アポ―に心電図機能が付くらしい、酸素濃度も確認ができる
それらの機能と、GPSとベルトを確認してみたいな、42800円から、無理だ
よく分からんがGPSマップ等も思うような感じで使えそうだ、iPhone要る

=========
2014-04-12に投稿 GPS Watch


ブタさんマークのBryton Cardio40。格安で入手できた。
Garmin910xtと機能が似ていて薄くて軽い。いいよコレは、ヨシオ。
ベルトはANT+に対応しているのでガーミンのGarmin Heart Rate Monitorが推し機器。

http://www.brytonsport.com/
マニュアル

トレーニングとは穴のあいたバケツに水を溜める作業だ
体がNOと叫んだら、私はYESと答える
走った距離は裏切らない。いついかなる時も決して裏切ることのない唯一無二の友、それが筋肉
千回と千1回とでは天と地の隔たり、最後の1発はその前の千に勝るとも劣らない価値がある
君のこめかみに拳銃を突きつけて「あと2repsやれ」と言ったらどうするね?死に物狂いでやるだろう?追い込むとはそういうことさ
http://www.2monkeys.jp/archives/34051594.html

Posted by funa : 09:21 PM | Gadget | Comment (0) | Trackback (0)


Navi: <  1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19  >
PhotoGallery


TWITTER
Search

Mobile
QR for cellphone  QR for smart phone
For mobile click here
For smart phone click here
Popular Page
#1Web
#2Hiace 200
#3Gadget
#4The beginning of CSSレイアウト
#5Column
#6Web font test
#7Ora Ora Ora Ora Ora
#8Wifi cam
#9みたらし団子
#10Arcade Controller
#11G Suite
#12PC SPEC 2012.8
#13Javascript
#14REMIX DTM DAW - Acid
#15RSS Radio
#16Optimost
#17通話SIM
#18Attachment
#19Summer time blues
#20Enigma
#21Git
#22Warning!! Page Expired.
#23Speaker
#24Darwinian Theory Of Evolution
#25AV首相
#26htaccess mod_rewite
#27/// BANGBOO BLOG /// From 2016-01-01 To 2016-01-31
#28竹書房
#29F☆ck CSS
#30Automobile Inspection
#31No ID
#32Win7 / Win10 Insco
#33Speaker
#34Arcade Controller
#35Agile
#36G Suite
#37Personal Information Privacy Act
#38Europe
#39Warning!! Page Expired.
#40GoogleMap Moblile
#41CSS Selectors
#42MySQL DB Database
#43Ant
#44☆od damnit
#45Teeth Teeth
#46Itinerary with a eurail pass
#47PHP Developer
#48Affiliate
#49/// BANGBOO BLOG /// From 2019-01-01 To 2019-01-31
#50/// BANGBOO BLOG /// From 2019-09-01 To 2019-09-30
#51/// BANGBOO BLOG /// On 2020-03-01
#52/// BANGBOO BLOG /// On 2020-04-01
#53Windows env tips
#54恐慌からの脱出方法
#55MARUTAI
#56A Rainbow Between Clouds‏
#57ER
#58PDF in cellphone with microSD
#59DJ
#60ICOCA
#61Departures
#62Update your home page
#63CSS Grid
#64恐慌からの脱出方法
#65ハチロクカフェ
#66/// BANGBOO BLOG /// On 2016-03-31
#67/// BANGBOO BLOG /// From 2017-02-01 To 2017-02-28
#68/// BANGBOO BLOG /// From 2019-07-01 To 2019-07-31
#69/// BANGBOO BLOG /// From 2019-10-01 To 2019-10-31
#70/// BANGBOO BLOG /// On 2020-01-21
#71Bike
#72Where Hiphop lives!!
#73The team that always wins
#74Tora Tora Tora
#75Blog Ping
#76無料ストレージ
#77jQuery - write less, do more.
#78Adobe Premire6.0 (Guru R.I.P.)
#79PC SPEC 2007.7
#80Google Sitemap
#81Information privacy & antispam law
#82Wifi security camera with solar panel & small battery
#83Hope get back to normal
#84Vice versa
#85ハイエースのメンテ
#86Camoufla
#87α7Ⅱ
#88Jack up Hiace
#89Fucking tire
#90Big D
#914 Pole Plug
#925-year-old shit
#93Emancipation Proclamation
#94Windows env tips
#95Meritocracy
#96Focus zone
#97Raspberry Pi
#98Mind Control
#99Interview
#100Branding Excellent
Category
Recent Entry
Trackback
Comment
Archive
<     July 2024     >
Sun Mon Tue Wed Thi Fri Sat
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Link