Upgrade to Pro — share decks privately, control downloads, hide ads and more …

データを用いた組織移行戦略

Avatar for a1008u a1008u
March 16, 2023

 データを用いた組織移行戦略

Google Cloudでの組織を跨いだ安全なプロジェクト移行を行いました。
その時の内容を資料にまとめました。

Avatar for a1008u

a1008u

March 16, 2023
Tweet

More Decks by a1008u

Other Decks in Technology

Transcript

  1. 事前準備 - プロジェクト移行理解 - 取り組み 公式ドキュメントのプロジェクト移行を確認して、 今回の移行で一番問題になる部分を洗い出す。 プロジェクトを移行すると、 リソース階層内の現在の場所からポリシーが継承されなくなり、 移行先の有効なポリシー評価の対象となります。

    プロジェクトの移行先の有効なポリシー が、そのプロジェクトの元の場所にあるポリシーとできる限り一致するようにすることをおす すめします。 プロジェクト移行より 組織ドメイン:AAA 組織ドメイン:BBB プロジェクト:X プロジェクト:X フォルダ:111 フォルダ:111
  2. 事前準備 - 事前準備の作業整理 - 作業 移行元をきれいにした上で、移行先に展開すれば。。。 現状のポリシーの構成を把握する必要がある。 移行元 移行先 フォルダやGoogle

    Groupの構成を移行元に合わせる。 現行の不要なポリシーを削除する。 移行後に移行前とポリシーで差異がないことを 確認するテストなどが必要。 理想の階層構成を定める。
  3. 事前準備 - 現行把握① - 利用サービス Cloud Asset Inventory Google Cloud

    のプロジェクトやフォルダ、組織に紐づくリソースやポ リシー、ランタイム情報などのメタデータを検索、分析できるサービス です。 引用:Cloud Asset Inventory で一般公開されたリソースを自動検出してみた。 概要 機能 アセット検索 エクスポート モニタリング 分析 アセット リソース ポリシー ランタイム情報
  4. 事前準備 - 現行把握② - 利用サービス Cloud Asset Inventory GUIベースでもIAM検索ができます。 (画像は少し古いです)

    引用:https://tech.nri-net.com/entry/gcp-cai リソース単位や、ユーザ単位で アドホックにポリシーの調査ができる。
  5. 事前準備 - 現行把握③ - 今回の方針 SQLで操作できたほうがのちに楽になると思ったので、 エクスポート機能を利用して、 BigQueryにIAM情報を格納した。 可視化にはLooker studioを利用。(配列があるため)

    Cloud Asset Inventory gcloud asset export \ --organization= '[組織ID]' \ --bigquery-table= 'projects/[ プロジェクト ID]/datasets/[ データセット ID]/tables/[ テーブル名 ]' \ --output-bigquery-force \ --content-type= 'iam-policy' ;
  6. 事前準備 - 理想構成定義① - 階層 + IAM(ポリシー)を整理しました。 *基本的には、Google Groupの活用と継承を生かしてフォルダでの IAM設定をしました。

    組織ドメイン:AAA プロジェクト:X フォルダ:111 フォルダ:222 プロジェクト:Y プロジェクト:Z Google Gourp: 1XY user: c service account: cc Google Gourp: 2Z service account: d Google Gourp: ADMIN
  7. 事前準備 - 理想構成定義② - 移行先に対して、移行元と階層構造や Google Groupなどを合わせる。 組織ドメイン:BBB プロジェクト:X フォルダ:111

    フォルダ:222 プロジェクト:Y プロジェクト:Z Google Gourp: 1XY user: c service account: cc Google Gourp: 2Z service account: d Google Gourp: ADMIN
  8. 事前準備 - テスト設計 - 上記図のような構成になった場合に、利用者が BigQueryへアクセスできるようにしないといけない。 原則 プロジェクトに紐づいている IAMが、 移行前後で同じであれば動作には問題ないはず。

    組織ドメイン: AAA 組織ドメイン: BBB プロジェクト: A プロジェクト: B ただ、問題として。。。 • 弊社(データ基盤)では、別プロジェク トのBQをviewが参照するなどの構成 をとっていた。 • IAMはGoogle Groupを利用。
  9. 事前準備 - テスト設計 - 利用中のサービスアカウントから別に keyを取得して、 クエリが実行できるかを確認することで、移行後した後に問題ないことを保証する。 テスト内容 移行前後でプロジェクトに生成されているサービスアカウントを取得して、 移行対象のBigQuery(table、

    別プロジェクト参照view)にクエリする。 組織ドメイン: AAA 組織ドメイン: BBB プロジェクト: A プロジェクト: B ②shellスクリプト(bqコマンド)でクエリ ①shellスクリプトでSAのkeyを取得
  10. 移行+確認 - issueの整備 - 後から見てもわかりやすいように、 プロジェクトごとにGitHub issueを準備して下記を記載しました。 【以下のエビデンスを準備】 • 移行対象のプロジェクトからGoogle

    Groupを特定 • 対象のGoogle Groupに所属するSA 全てを利用して移行対象プロジェクトの BQに対してクエリができる確認 移行後 移行時 移行前 【以下のエビデンスを準備】 • プロジェクト移行には、gcloud beta projects moveのコマンドを利用す るため、そちらの結果 【以下のエビデンスを準備】 • 移行対象のプロジェクトからGoogle Groupを特定 • 対象のGoogle Groupに所属するSA 全てを利用して移行対象プロジェクトの BQに対してクエリができる確認 issue(エビデンス)の構成
  11. 移行+確認 - 組織間でのGoogle Group確認方法 - Google Groupの情報はCloud Asset Inventoryでは不十分だったので、 gcloud

    identity groups を利用してデータを取得して BigQueryに格納して、クエリで比較しました。 WITH all_jp_data as ( select user, group_name from [移行元のgroup情報が格納されたテーブル名]), inc AS (select user, group_name from [移行先のgroup情報が格納されたテーブル名]), a_intersect_inc AS (SELECT * FROM a INTERSECT DISTINCT SELECT * FROM inc ), a_except_inc AS (SELECT * FROM a EXCEPT DISTINCT SELECT * FROM inc ), inc_except_a AS (SELECT * FROM inc EXCEPT DISTINCT SELECT * FROM a ), all_records AS ( SELECT *, TRUE AS in_a, TRUE AS in_inc FROM a_intersect_inc UNION ALL SELECT *, TRUE AS in_a, FALSE AS in_inc FROM a_except_inc UNION ALL SELECT *, FALSE AS in_a, TRUE AS in_inc FROM inc_except_a ) select * from all_records #!bin/bash IFS=$'\n'; for group in `gcloud identity groups search --organization="[組織ID]" --labels="cloudidentity.googleapis.com/groups.discussion_forum" --format=json | jq -r '.groups | .[].groupKey.id'`; do gcloud identity groups memberships list --group-email="$group" --format=json | jq --arg Group_value $group -r -c '.[] | {group_name: $Group_value, user: .preferredMemberKey.id, id: .name}' >> tmp_group.jsonl done bq --location=asia-northeast1 load \ --autodetect=true \ --replace=true \ --source_format=NEWLINE_DELIMITED_JSON \ [格納先テーブル名] \ ./tmp_group.jsonl 組織に紐づく Google Groupと 所属するアカウント を取得用shell Google Groupを 比較するためのクエリ
  12. 移行+確認 - 移行前後でクエリチェック用 - 移行前後でクエリが実行できれば、移行後も問題なく利用ができる。 # 関数の定義 + 引数 $group

    $PROJECT $TABLE $VIEW ck_query () { gcloud auth login echo [対象Google Group::: $1 ] for id in `gcloud identity groups memberships list --group-email="$1" --format=json | jq -r -c '.[].preferredMemberKey.id'`; do if [[ $id =~ "@組織ドメイン" ]] || [[ $id =~ "@cloudbuild.gserviceaccount.com" ]] || [[ $id =~ "@cloudservices.gserviceaccount.com" ]]; then echo "対象外:$id" else echo [対象アカウント::: $id ] [bqの確認::: $3 ] [bqの確認::: $4] gcloud iam service-accounts keys create key.json --iam-account=$id gcloud auth activate-service-account $id --key-file=./key.json bq query \ --nouse_legacy_sql \ --label=purpose:move_check \ --use_cache=false \ --project_id=$2 \ "SELECT count(*) FROM $3" bq query \ --nouse_legacy_sql \ --label=purpose:move_check \ --use_cache=false \ --project_id=$2 \ "SELECT count(*) FROM $4" # echo 対象サービスアカウントキーの削除 gcloud auth activate-service-account [削除用のサービスアカウント] --key-file=./delete_key.json PRIVATE_KEY_ID=`cat ./key.json | jq -r '.private_key_id'` echo Y| gcloud iam service-accounts keys delete $PRIVATE_KEY_ID --iam-account=$id rm -rf ./key.json fi done } 移行前後に行う テストロジックのメイン *共通パーツです。 SAがクエリを実行できるか確認 • 対象のGoogle Group • 対象のプロジェクト • 対象のテーブル • 対象のview
  13. 移行+確認 - 組織間でのIAMの確認方法 - こちらは、プロジェクトの移行で確認するよりは現状把握(移行直前の事前確認)として利用 *プロジェクト移行のタイミングで定期的にチェックをしました。 WITH 移行元 as (

    SELECT name, members,role, FROM [移行元のcloud asset inventoryのiam policy] r CROSS JOIN UNNEST(r.iam_policy.bindings) as binding CROSS JOIN UNNEST(binding.members) as members WHERE asset_type="cloudresourcemanager.googleapis.com/Folder" and binding.role is not null and members not like ("user%") and name in ([フォルダの指定]) ), 移行先 as ( SELECT name, members, role, FROM [移行先のcloud asset inventoryのiam policy] r CROSS JOIN UNNEST(r.iam_policy.bindings) as binding CROSS JOIN UNNEST(binding.members) as members where asset_type="cloudresourcemanager.googleapis.com/Folder" and members not like ("user%") and binding.role is not null and name in ([フォルダの指定]) ), 移行元_intersect_移行先 AS (SELECT * FROM a INTERSECT DISTINCT SELECT * FROM 移行先 ), 移行元_except_移行先 AS (SELECT * FROM a EXCEPT DISTINCT SELECT * FROM 移行先 ), 移行先_except_移行元 AS (SELECT * FROM 移行先 EXCEPT DISTINCT SELECT * FROM a ), all_records AS ( SELECT *, TRUE AS in_移行元, TRUE AS in_移行先 FROM 移行元_intersect_移行先 UNION ALL SELECT *, TRUE AS in_移行元, FALSE AS in_移行先 FROM 移行元_except_移行先 UNION ALL SELECT*, FALSE AS in_移行元, TRUE AS in_移行先 FROM 移行先_except_移行元 ), select * from all_records order by 1 Cloud Asset Inventoryで 取得したIAM Policyの 比較クエリ *フォルダ間の確認 ◆注意 組織ドメインが違うので、 case文とかで少し修正が必要です。
  14. 移行+確認 - end - 無事に移行完了。 テストを通じ業務に支障ないことを確認できていたので、安心して移行作業ができました。 組織ドメ イン :AAA プロジェ

    クト:X フォルダ :111 フォルダ :222 プロジェ クト:Y プロジェ クト:Z Google Gourp: 1XY user: c service accoun t: cc Google Gourp: 2Z service accoun t: d Google Gourp: ADMIN 組織ドメイ ン:BBB プロジェク ト:X フォルダ :111 フォルダ :222 プロジェク ト:Y プロジェク ト:Z Google Gourp: 1XY user: c service account: cc Google Gourp: 2Z service account: d Google Gourp: ADMIN
  15. まとめ ポイント① 公式や他社事例 プロジェクト移行の作業業自体は単純で、慣れると難しくないのですが、まずは全容理解するのが大切 ポイント② 人間がやるには面倒なことを機械に 移行前後でのクエリ確認などは人が作業すると必ずミスをする作業 + 何回もしたくないので、 そのような作業は機械にやらせてしまいましょう。その分の作成工数は惜しまないように。

    ポイント③ Cloud Asset Inventory 組織全体を調査するには非常に最適なサービスです。 弊社では、一日一回ですがBigQueryに同期するようにしました。今後ダッシュボードなど作成予定。 ポイント④ 比較するならクエリで 少量ならスプレッドシートでもいいのですが、最新データでの比較やスプレッドシートで確認するには大きすぎるデー タ量があると思うので、なるべくBigQueryに格納させてしまうのをお勧めします。