mcpField
P
pulumi-migrate-from-discovered-stack

pulumi-migrate-from-discovered-stack

github.com/pulumiクラウド・DevOps78195 回インストール3 週間前に更新
リポジトリ

pulumi-migrate-from-discovered-stack について

Pulumi Cloud Discovery がスキャン済みのクラウドリソースを Pulumi stack に移行するスキルです。クラウド状態からインポートし、API アノテーションで進捗や例外を管理して、差分ゼロの確認とプルリクエスト作成を目指します。

主な機能

  1. 01検出済みリソースの取得と分類
  2. 02クラウド状態からリソースをインポート
  3. 03API アノテーションで移行を追跡
  4. 04pulumi preview で差分ゼロを確認
  5. 05移行コードとレポートを作成

活用シーン

  1. 01スキャン済み CloudFormation stack の移行
  2. 02スキャン済み Azure ARM リソースの移行
  3. 03既存移行の再開と進捗管理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/pulumi/agent-skills --skill pulumi-migrate-from-discovered-stack

インストール後、Claude Code で/pulumi-migrate-from-discovered-stackを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

arm.md
cloudformation.md
refactor.md
use_cases.yaml
agents/
openai.yaml
scripts/
build_import.py
triage.py

詳細

対象範囲:このスキルは、Pulumi Cloud の Discovery 機能によるスキャンがすでに完了し、discovered-stacks API(下記の GET .../discovered-stacks/{projectName}/{stackName}/resources)を通じて公開されているスタックにのみ適用されます。 Discovery がまだスキャンしていない任意の CloudFormation/ARM テンプレートやアカウントを移行するためのものではありません。移行元に検出済みスタックが存在しない場合、このスキルで読み取れるものはなく、適用できません。

このスキルと同時に cloudformation-to-pulumi または pulumi-arm-to-pulumi を読み込まないでください。 これら2つのスキルでは、テンプレートを先に処理するワークフロー(機械的な変換→インポート)が指定されており、AWS では aws-native の使用が必須です。このスキルでは、クラウドの状態を先に処理するワークフロー(検出済みの状態からインポート→必要に応じて後からテンプレートに照らしてリファクタリング)を採用し、デフォルトでは aws classic/azure-native を使用します。これら2つのスキルに含まれる有用な参考資料は、このフォルダー内の cloudformation.md と arm.md にまとめられています。


計画の調整

このスキルを読み込む前に移行計画を作成している場合は、以下のワークフローに照らして確認し、更新してください。ここに示すフェーズは、それ以前の計画より優先されます。作業を進める前に、調整後の計画をユーザーに伝えてください。

成功基準

移行が完了したとみなされるのは、次の条件を満たしたときです。

  1. リソースを漏れなく網羅 — 検出されたすべてのリソースがインポートされているか、インポートしない理由を説明する注釈が付いていること。
  2. 差分ゼロ — pulumi preview に変更が表示されないこと。これはコードがクラウドの状態と完全に一致していることを証明します。
  3. API を通じて進捗を追跡 — compareTo と移行の注釈を使用し、エージェントの記憶だけでなく、Pulumi Cloud 上で進捗を確認できるようにすること。
  4. 成果物は PR — 移行済みのコードと移行レポートを含むプルリクエストを作成すること。

THE DISCOVERED-STACKS API

リソースの取得
GET /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/resources?compareTo={targetProject}/{targetStack}

対象の Pulumi スタックが存在する場合は、必ず compareTo を含めてください(以前の移行を試みた際に、すでに状態が保存されている可能性があります)。DiscoveredResourceInfo オブジェクトのリストが返されます。以下の JSON パスは正確です。使用前に確認してください。

  • name — 最上位:論理名(CF 論理 ID/ARM リソース名)。これを Pulumi リソース名として使用します。
  • originType — 最上位:ネイティブのクラウド型(例:AWS::S3::Bucket、Microsoft.Storage/storageAccounts)
  • providerType — 最上位:マッピングされた Pulumi 型トークン(例:aws:s3/bucket:Bucket)。マッピングがない場合は null。
  • resource.inputs.providerId — pulumi import 用の物理クラウド ID。
  • resource.urn — アノテーションリクエストで resourceUrn として使用する URN(そのままコピーしてください)。
  • migrationStatus — 最上位:以下のいずれかのステータス。
  • annotation — 最上位:ユーザーまたはエージェントのアノテーションが存在する場合に設定されます(以下の「アノテーション」を参照)。

resource.inputs オブジェクトには、未加工のクラウドプロバイダーデータも含まれます。

CloudFormation の場合 — resource.inputs.cloudFormation:

  • physicalResourceId — 元の CF 物理 ID
  • resourceType — CF 型(例:AWS::IAM::Role)
  • resourceStatus — 例:CREATE_COMPLETE、DELETE_COMPLETE
  • driftStatus — NOT_CHECKED、IN_SYNC、DRIFTED

CDK で合成された CF スタックでは、inputs.cdkPath も存在します。使用方法については、cloudformation.md §5 を参照してください。

ARM の場合 — resource.inputs.arm。ARM リソースはデプロイ単位ではなく、リソースグループ単位でグループ化されます。そのため、現在そのリソースを支えるデプロイがないリソース(デプロイ履歴が Azure の保持期間を過ぎた場合や、追跡対象のデプロイ外で作成された場合)も、プレースホルダーとして返されます。この場合、resource.inputs.deploymentName は空で、arm の形状が異なります。

  • デプロイに関連付けられたリソース(resource.inputs.deploymentName が空でない)— arm はデプロイ操作オブジェクトです。properties.targetResource.id/.resourceType/.resourceName、properties.provisioningState(例:Succeeded)が含まれます。
  • プレースホルダー(resource.inputs.deploymentName が空)— arm は代わりに未加工の Azure 汎用リソースオブジェクトです。最上位に id、name、type、location、tags が含まれます。properties.targetResource はありません。探さないでください。

どちらの場合も、arm の内部を参照するのではなく、インポート ID には最上位の resource.inputs.providerId を優先してください(上記を参照)。両方の形状ですでに正規化されています。

移行ステータス

ステータスは PascalCase です。最初に一致したものが適用されます。

  1. Migrated — compareTo の Pulumi スタック内でリソースが見つかりました。すでに Pulumi の管理下にあるため、スキップします。
  2. Ready — providerType と providerId が設定され、スキャナーがリソースの存在を確認しました。pulumi import <providerType> <name> <providerId> --generate-code --out <file>.ts でインポートします(--generate-code --out なしでは絶対に実行しないでください。フェーズ 4 を参照)。
  3. NotFound — providerType と providerId は設定されていますが、スキャナーがリソースの現在の状態を確認できませんでした。削除されている、マッピングが不完全である、またはスキャナーが検出できなかった可能性があります。インポートする前に確認してください。
  4. NotApplicable — コンテナー型またはラッパー型(AWS::CloudFormation::Stack、Microsoft.Resources/deployments、Microsoft.Resources/resourceGroups、pulumi:providers:*)は個別に移行できません。何も通知せずにスキップします。
  5. NoMatch — providerType が null です。マッピングが見つかりません。よくある例:
    • CF カスタムリソース(例:Custom::VpcRestrictDefaultSG)— 直接対応する Pulumi の型はありません。
    • インラインポリシー — AWS::IAM::Policy は aws:iam/role:Role のインラインプロパティとしてモデル化されます。親の Role を移行した後、ポリシーを移行済みとしてアノテーションしてください。
  6. PulumiOnly — compareTo スタック内に存在し、検出された対応リソースがないか、NoMatch リソースの移行のために作成されたリソースです。ユーザーに提示してください。

annotation.statusOverride があるリソースは、計算されたステータスと異なる場合でも、オーバーライドに従って解決済みとして扱ってください。

アノテーション
PUT  /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/migration
DELETE /api/preview/insights/{orgName}/discovered-stacks/{projectName}/{stackName}/migration?resourceUrn={urn}

PUT body:

{
  "resourceUrn": "<copy verbatim from resource.urn in the list response>",
  "note": "explanation of what happened",
  "statusOverride": "Migrated" | "",
  "linkedResourceUrn": "<optional: URN of the Pulumi resource paired 1:1 with this origin>"
}

すべてのアノテーションリクエストには、Pulumi Cloud API を使用してください。note または statusOverride の少なくとも一方は空でない値にする必要があります。ノートのみを更新する場合は、statusOverride を省略してください(null は送信しないでください)。DELETE エンドポイントは、ノートと statusOverride の両方をクリアします。

アノテーションは、次の用途に使用します。

  • 削除されたリソースに、存在しなくなったことを説明するノートを添えて Migrated のフラグを付ける
  • 親の移行に含まれるインライン/子リソースに、親の名前を記したノートを添えて Migrated のフラグを付ける — ここでは linkedResourceUrn を使用しないでください(1 対多の関係であり、UI がマージするのは 1 対 1 のペアのみです)
  • マッピングを修正した後、NotFound または NoMatch の起点を対応する PulumiOnly に結び付ける(statusOverride=Migrated + linkedResourceUrn → PulumiOnly の URN)。linkedResourceUrn の有効な用途はこれだけです。
  • 妨げとなっている要因や実施した手動手順を説明するノートを残す
  • 自動分類で解決できないリソースに関する判断を記録する

アノテーションエンドポイントは、移行の進捗を追跡する共通の場所です。リソースに対して操作する前に、必ず既存のアノテーションを読み取り、ユーザーが設定したオーバーライドを尊重してください。

note フィールドは、ユーザーが記述するコンテキストです。特定のリソースに関する優先度の高い指示として扱ってください。一般的な用途として、名前の希望、インポート ID のヒント、スキップするリソース、特別な処理の指示などがあります。ノートは、次の 2 つの経路を通じてエージェントに届きます。

  1. 開始時のプロンプト — ユーザーが移行タスクを開始すると、選択したリソースに付いているノートが、そのリソースの行に追加されます。

    - aws:s3/bucket:Bucket "my-bucket" (provider ID: my-bucket-prod) — note: use logical name "appBucket" in code
    

    API を呼び出す前に、これらを読んでください。

  2. API レスポンス — GET .../resources を呼び出したとき、各 DiscoveredResourceInfo の annotation.note フィールドに含まれます。アノテーションが設定されていない場合、annotation オブジェクト自体が省略されます。


移行ワークフロー

フェーズ 0 — 前提条件と対象範囲の確認

ツールを呼び出す前に、以下のすべてを収集して確認してください。不足している情報があれば、推測で進めず、質問してください。

ソース(検出されたスタック):

  • 組織名(例:pulumi_local)
  • 検出されたプロジェクト名(例:AcmeCdkExampleStack)
  • 検出されたスタック名(例:dev-sandbox-disc_us-west-2__Dev)— スキャナーが生成した名前で、通常はアカウント、リージョン、CF/ARM スタック名が含まれています。
  • リージョン(スタック名から推測できる場合でも確認してください)。

ターゲット(Pulumi コードと状態を配置する場所):

  • ターゲットの Git リポジトリ URL — ユーザーに確認してください。最初からすべての作業をこのリポジトリ内で行います。
  • サブフォルダー(任意)— ユーザーに希望を確認してください。指定がなければリポジトリのルートを使用します。
  • ターゲットのプロジェクト名とスタック名 — 推測せず、ユーザーに確認してください。スタックがすでに存在する場合はフェーズ 1 で compareTo を使用し、存在しない場合はフェーズ 2 で作成します。
  • ターゲット言語 — デフォルトは TypeScript です。

リファクタリングの希望(フェーズ 7 向け):

  • ユーザーは元のソースコード(CDK リポジトリ、Bicep プロジェクト、Terraform モジュール)を持っていますか?持っている場合は、パスまたは URL を確認してください。これはフェーズ 7 における主要な構造上の参照資料です。リファクタリング後の Pulumi コードは、インポートモデルで実際に生成された内容に合わせて調整しつつ、コンポーネントの境界、ファイル構成、命名規則を参考にします。
  • Pulumi の出力に希望するプログラム構成はありますか?(例:「サービスごとに 1 ファイル」「既存のリポジトリ構成に合わせる」「特に希望はない」)
  • フェーズ 7 も実施しますか?それともゼロ差分の状態(フェーズ 6)で終了しますか?

認証情報:

  • クラウド認証情報に使用する ESC 環境(指定がなければ確認してください。決して推測しないでください)。ESC が推奨されます。cloudformation.md §1 または arm.md §1 を参照してください。

上記すべての確認が済むまで、フェーズ 1 を開始しないでください。 計画をユーザーに要約して伝え、承認を待ってください。

フェーズ 1 — リソースの取得とトリアージ

既存の移行を再開する場合も、毎回ここから始めてください。これまでの作業状況を示す信頼できる情報源は、API と既存のアノテーションです。対象リポジトリにすでに Pulumi コードがある場合は、それを読んでください。規約、既存のリソース、以前の試行がどこまで進んだかがわかります。

  1. 検出済みリソースを取得します:GET .../discovered-stacks/{projectName}/{stackName}/resources。
    • 対象スタックが存在する場合(移行の再開):?compareTo=<targetProject>/<targetStack> を追加します。
    • 対象スタックが存在しない場合(新規作成):compareTo は省略します — 対象スタックが見つからないと、API は 404 を返します。フェーズ 2 でスタックを作成した後は、以降の呼び出しで指定できます。
  2. レスポンスをディスクに保存します — ./.migration/resources-baseline.json。
  3. トリアージを実行します:python3 <skill-base-dir>/scripts/triage.py .migration/resources-baseline.json — アノテーションによる上書きを考慮したステータスの件数と、リソースごとの一覧表を出力します。
  4. ユーザーに計画を提示します:

    「N 個のリソースが見つかりました。A 個は移行済み、M 個は準備完了、K 個は未検出、J 個は一致なし、L 個は移行できないコンテナーです。まず準備完了のリソースをインポートし、次に未検出のリソースを確認してから、一致なしのリソースを一緒にトリアージします。よろしいですか?」

コードを書く前に確認を得てください。

フェーズ 2 — 対象リポジトリと Pulumi スタックのセットアップ
  1. 対象の Git リポジトリをクローンし(フェーズ 0 から取得)、以降のすべてのフェーズでその中で作業します。リポジトリにすでにコードがある場合は、新しいコードを追加する前に読み、既存の規約とリソースを把握してください。
  2. 対象スタックがすでに存在する場合(フェーズ 0 で確認)、それを選択します。存在しない場合は、次の手順を実行します。
    • Pulumi プロジェクトを作成します:pulumi new <language> --name <project> --stack <org>/<project>/<stack> --yes。
  3. プロバイダーの設定を行います:pulumi config set aws:region <r>(または azure-native:location)。
  4. 指定されている場合は、ESC 環境をリンクします。

空の状態で pulumi up を実行する必要はありません。

プロジェクトとスタックのセットアップ、リージョンの設定、プロバイダーのインストールに関する具体的なコマンドについては、cloudformation.md §2 または arm.md §2 を参照してください。

フェーズ 3 — インポートファイルの作成

インポートファイルを生成します:python3 <skill-base-dir>/scripts/build_import.py .migration/resources-baseline.json .migration/import.json。これにより、準備完了および未検出のリソース(すでにアノテーションが付いたものを除く)が抽出され、API フィールドが Pulumi のインポート形式にマッピングされます(type ← providerType、name ← name、id ← resource.inputs.providerId)。

フェーズ 4 — インポート

フェーズ 3 で作成した import.json を使用します。

必ず --generate-code --out を指定してください — 指定しないと、コードがないままリソースが state に登録され、pulumi preview が失敗します。

pulumi import --file import.json --generate-code --out batch.<ext>
# then: append generated code into the main program file and delete the batch file

バッチごとの手順:インポート → プレビュー → コミット → アノテーション。 1 バッチあたり約 20 個のリソースを目安にします。CDK スタックでは cdkPath の最上位グループごとにバッチ分けし、それ以外ではリソースタイプのプレフィックスごとに分けます。

  1. バッチをインポートします。
  2. pulumi preview — 差分がゼロであることが必要です。先に進む前に、差分を修正してください。
  3. プログラムの変更をブランチにコミットします。
  4. インポートした各リソースにアノテーションを付けます — メモを付け、statusOverride は指定せずに PUT .../migration を実行します。アノテーションはコンテキストのリセット後も保持され、UI で確認できます。

?compareTo はリアルタイムの進捗シグナルです — pulumi import はすぐに state を書き込むため、各インポート後に migrationStatus は Migrated に切り替わります。pulumi up は実行しないでください(フェーズ 6 を参照)。

計算されたステータスが誤りになる場合に限り、statusOverride を使用します。

  • statusOverride=Migrated(linkedResourceUrn を指定)— 別のリソースに含まれるリソース(インライン IAM ポリシー → 親 Role、IGW アタッチメント → IGW など)。
  • statusOverride=Migrated(linkedResourceUrn を指定せず、メモを付ける)— 削除済み、参照先のない、または Pulumi に同等のリソースがないリソース。解決済みとしてフラグを付け、未対応の作業から除外します。
フェーズ 5 — NotFound と NoMatch のトリアージ

デフォルトの方針:まず試し、その後に注記します。 NotFound とマッピング修正のどちらの場合も、まず pulumi import を試すのが、実際の問題を把握する最速の方法です。エラーメッセージは正確で、具体的な対処方法が示されています。

NotFound(providerType が設定済みで、状態が未確認):

よくある結果:

  1. リソースが削除されています。 pulumi import は Preview failed: resource '<id>' does not exist を返します。注記にエラーをそのまま記載し、statusOverride=Migrated を指定します。再試行しないでください。 実際には、NotFound リソースのかなりの割合がマッピングエラーではなく、削除済みだと判明します。

  2. providerType のマッピングが誤っています。 インポートが型検証エラーまたはスキーマ不一致で失敗します。複数の有効な Pulumi マッピングがある CF 型もあります(VPC ゲートウェイアタッチメント/VPN と IGW、S3 と s3control、RDS インスタンスとクラスターインスタンス、SES v2 と v1 など)。スキャナーが選ぶ主なマッピングが、リソースに合わない場合があります。cloudformation.md §7 で originType を調べ、インポートファイルの providerType を上書きしてから、再試行します。その後、フィンガープリント照合による副作用に対処します(次の項目を参照)。

  3. マッピング誤りによる副作用:PulumiOnly が表示されます。 エージェントが修正した providerType でインポートすると、検出されたリソースとのフィンガープリント照合に失敗します。検出されたリソースは NotFound(または NoMatch)のままになり、新しい PulumiOnly エントリーが表示されます。元のオリジン行に statusOverride=Migrated を指定し、linkedResourceUrn に PulumiOnly の URN を設定します。 これにより UI 上で両者が紐付けられ、記録も適切に保たれます。

  4. リソースが存在し、マッピングも正しい場合。 インポートが成功します。ステータスは自動的に Migrated に切り替わります。

NoMatch(providerType が null):

よくあるパターン:

  1. インライン IAM ポリシー。 名前が移行済みのロールのプレフィックスと一致する AWS::IAM::Policy は、そのロールのインポート時に inlinePolicies としてすでに取り込まれているインラインポリシーです。注記に "inline policy of <RoleName>" と記載し、statusOverride=Migrated を指定します。

  2. AWS::SecretsManager::SecretTargetAttachment には、直接対応する Pulumi マッピングがありません。 シークレットとターゲット(RDS クラスターなど)の関連付けは、クラスターの認証情報設定を介して暗黙的に行われます。暗黙的な関連付けについて説明する注記を付け、statusOverride=Migrated を指定します。

  3. CDK カスタムリソース(Custom::*)。通常は、実際の処理を行う Lambda ハンドラーです。既知のハンドラーから Pulumi への置き換えマッピングについては、cloudformation.md §5 を確認してください。ユーザーに確認せずに Migrated を注記しないでください。ハンドラーの処理内容を提示し、判断をユーザーに委ねます。

  4. その他の NoMatch 型。 クラウドプロバイダーのドキュメント(CF リソース型リファレンスまたは ARM リソース型リファレンス)で originType を調べてリソースの内容を確認し、一致するプロバイダー型を Pulumi レジストリで検索します。マッピングが曖昧な場合は、ユーザーに情報を提示して確認を求めます。

既存の PulumiOnly エントリー。 上記のマッピング修正によるもののほか、移行対象ではない、ターゲットスタックにすでに存在するリソースも PulumiOnly に含まれます。これらはそのままにしておき、注記は不要です。

クラウド固有の検索コマンド(リソースの存在確認、インポート ID の特定、クラウドへのクエリ)、プロバイダー選択ルール(aws classic と aws-native、azure-native と azure)、Preview Resolution Workflow、既知のインポート時の注意点については、cloudformation.md §3–§6 または arm.md §3–§6 を参照してください。

フェーズ 6 — 調整と PR
  1. pulumi preview を実行し、変更がないことを確認します。差分がある場合、生成されたコードがインポート済みの状態と一致していません。差分は次の 3 種類です。

    • 削除(-) — クラウドには存在するものの、コードで設定されていないフィールドです。実際のクラウドの値でコードに追加します。ignoreChanges は使用しないでください。
    • 追加(+) — コードで設定されているものの、プロバイダーから返されなかったフィールドです。計算値または読み取り専用の場合は、ignoreChanges を使用します。プロバイダーのデフォルト値を再設定している場合は、コードから削除します。
    • 変更(~) — 値が一致していません。クラウドに問い合わせて正しい値を確認し、コードを更新します。ignoreChanges で隠すことは絶対にしないでください。

    複雑なリソースでは、プレビューを 2~5 回繰り返すことを想定してください。差分を解消するために pulumi up を実行しないでください。これはコードではなくクラウドを変更します。 クラウド固有の差分パターンについては、cloudformation.md §6 または arm.md §6 を参照してください。

  2. 最後に GET resources?compareTo=... を実行し、想定される内訳を確認します(これは現在のバックエンドの状態を反映しています。すべての pulumi import で状態が書き込まれるため、migrationStatus はすでに最新です)。

    • Migrated — インポート済みのすべてのリソース
    • PulumiOnly — アノテーションによって関連付けられた修正済みマッピングのインポートを含む、Pulumi のみのリソース
    • 残っている NoMatch — すべてにアノテーションが付いている必要があります
    • NotApplicable(コンテナー)— 何もせずにスキップされます
  3. PR を作成する前に、フェーズ 7(リファクタリングの提案)に進みます。

プレビューに差分がなく、API のトリアージで未解決のリソースがないことを確認できれば、移行は機能的に完了です。pulumi up は実行しないでください。 インポート済みの状態は pulumi import によってすでに Pulumi Cloud と同期されています。移行のために pulumi up で行うことはありません。


Phase 7 — リファクタリングと保守性のレビュー(PR の前)

差分ゼロを達成しましたが、インポートしたコードは「フラット」で、値がハードコードされ、リソース間の参照がなく、すべてのリソースがトップレベルにあります。PR を作成する前に、可読性を高めるリファクタリングをユーザーに提案してください。

7a — 提案と方針の確認

Phase 0 で明示的なリファクタリングの希望を確認できていない場合、またはユーザーが明確に辞退していない場合は、ここで確認してください。

「プレビューに問題はなく、すべてのリソースを確認できました。PR を作成する前に、保守性を高めるためにコードをリファクタリングしたいと思います。具体的には、ハードコードされた値をリソース間参照に置き換え、設定パラメーターを抽出し、関連するリソースをグループ化します。(ソースリポジトリを提供いただいている場合は、構造の手本として使い、意図されたファイル構成とコンポーネント名を反映します。)進めてもよろしいですか?」

辞退された場合は、Phase 8 に進みます。

7b — リファクタリングの実施

戦略、不変条件、テンプレートの参照方法については、refactor.md を読んでください。優先順位は次のとおりです。

  1. まずソースリポジトリの構造を参考にする — ユーザーがソースリポジトリを提供している場合は、ここで読み込みます(クローンするか、Phase 0 で指定されたローカルパスを使用します)。ファイル構成、コンポーネント/モジュールの境界、命名規則を参考にします。リソースのグループがソース内のクラス、モジュール、サブディレクトリに自然に対応し、そのグループ化がインポートした Pulumi プログラムにも自然に当てはまる場合は、その構造を反映します。それ以外の場合は、ソースに機械的に合わせるためだけに不自然なグループ化を強制しないでください。
  2. リテラルの ARN/ID 参照をリソース間の出力参照に置き換える。
  3. 設定パラメーターを抽出する(リージョン、アカウント ID、環境タグ)。
  4. ソースリポジトリや CDK のパスから自然なグループ化が示される場合は、ComponentResource クラスにまとめる。
  5. ファイルの分割は最後に行い、自然なまとまりがある場合に限ります。

重要な変更を加えるたびに pulumi preview を実行します。差分ゼロを常に維持してください。プレビューで差分が表示された場合は、ほかの作業を試す前にその変更だけを元に戻します。復旧手順については、refactor.md § The invariant を参照してください。

7c — ユーザーへの説明と保守性の確認

リファクタリング後、PR を作成する前に、変更内容をユーザーに提示してください。

  1. 変更内容の概要を示します。作成/名前変更したファイル、導入したコンポーネント、置き換えたリテラル、追加した設定キーを含めます。
  2. トップレベルの index.ts(または同等のファイル)が約 80 行未満であれば、1 行ずつ説明します。それ以上の場合は、モジュールの構成を説明します。
  3. 判断した点を示します(例:「ソースリポジトリの lib/iam/ ディレクトリに合わせて IAM リソースを iam.ts にまとめました。別の名前がよければお知らせください」)。
  4. 「この構成は、このコードの保守方法として想定されているものと一致していますか?」 と明確に尋ねます。ユーザーの回答を待ちます。変更を求められた場合は対応し(必ずプレビューを実行)、納得してもらえるまで説明を繰り返します。

ユーザーが構成を問題ないと確認してから、Phase 8 に進んでください。


Phase 8 — PR と移行レポート

移行レポート(以下を参照)を作成し、PR を作成します。PR には、その時点のコードが含まれます。Phase 7 をスキップした場合はインポートしたままのコード、リファクタリングを選択した場合はリファクタリング後のコードが含まれます。


移行レポートの形式

PR の説明に次の項目を含めます。

  1. 概要 — 検出したソーススタックから移行先の Pulumi スタック、リージョン、言語。
  2. トリアージの概要 — 開始時と終了時のステータス別件数。
  3. リソースのマッピング表 — 名前、元のタイプ、プロバイダーのタイプ、ステータス、注記。
  4. 不足事項 — マッピングされていないリソースとその理由(注釈付き)。
  5. 進捗 URL — 継続的な追跡に使用する、検出済みスタックの比較エンドポイントへのリンク。
  6. 次のステップ — 未決のユーザー判断事項、任意のリファクタリング。

コメント