provider-actions
Terraform ProviderのアクションをPlugin Frameworkを使用して実装します。作成・更新・削除などのライフサイクルイベント前後に実行される命令的な操作を開発する際に使用してください。
description の原文を見る
Implement Terraform Provider actions using the Plugin Framework. Use when developing imperative operations that execute at lifecycle events (before/after create, update, destroy).
SKILL.md 本文
Terraform Provider Actions 実装ガイド
概要
Terraform Actions は Terraform ライフサイクル中に命令型操作を実行します。Actions は特定のライフサイクルイベント(作成前/後、更新、削除)でプロバイダー操作を実行できる実験的機能です。
リファレンス:
ファイル構造
Actions は標準的なサービスパッケージ構造に従います:
internal/service/<service>/
├── <action_name>_action.go # Action 実装
├── <action_name>_action_test.go # Action テスト
└── service_package_gen.go # 自動生成されたサービス登録
ドキュメント構造:
website/docs/actions/
└── <service>_<action_name>.html.markdown # ユーザー向けドキュメント
更新ログエントリ:
.changelog/
└── <pr_number_or_description>.txt # リリースノートエントリ
Action スキーマ定義
Actions は標準的なスキーマパターンで Terraform Plugin Framework を使用します:
func (a *actionType) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
// 必須設定パラメータ
"resource_id": schema.StringAttribute{
Required: true,
Description: "操作対象のリソースのID",
},
// デフォルト値を持つオプションパラメータ
"timeout": schema.Int64Attribute{
Optional: true,
Description: "操作タイムアウト(秒単位)",
Default: int64default.StaticInt64(1800),
Computed: true,
},
},
}
}
一般的なスキーマの問題
スキーマ定義に特に注意してください - 初稿後の一般的な問題:
-
型の不一致
- モデル構造体で
fwtypes.Stringの代わりにtypes.Stringを使用 - スキーマで
fwtypes.StringTypeの代わりにtypes.StringTypeを使用 - フレームワーク型と plugin-framework 型の混在
- モデル構造体で
-
List/Map 要素型
// 間違い - ElementType がない "items": schema.ListAttribute{ Optional: true, } // 正しい "items": schema.ListAttribute{ Optional: true, ElementType: fwtypes.StringType, } -
Computed vs Optional
- デフォルト値を持つ属性は
Optional: trueとComputed: trueの両方でマークする必要があります - デフォルト値を持たない限り、action 入力を
Computedとしてマークしないでください
- デフォルト値を持つ属性は
-
Validator インポート
// 正しいインポート確認 "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" -
Region/Provider 属性
- 利用可能な場合はフレームワーク提供の region 処理を使用
- フレームワークが処理する場合、スキーマにプロバイダー固有設定を手動で定義しないでください
-
ネストされた属性
- 複雑な構造には適切なネストされたオブジェクト型を使用
- ネストされた型が正しく定義されていることを確認
スキーマ検証チェックリスト
送信前に以下を確認してください:
- すべての属性に説明がある
- List/Map 属性に ElementType が定義されている
- Validator がインポートされ正しく適用されている
- モデル構造体が正しいフレームワーク型を使用している
- デフォルト値を持つ Optional 属性が Computed としてマークされている
- コードが型エラーなくコンパイルされる
-
go buildを実行して型の不一致をキャッチ
Action Invoke メソッド
Invoke メソッドは action ロジックを含みます:
func (a *actionType) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
var data actionModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
// プロバイダークライアントを作成
conn := a.Meta().Client(ctx)
// 長時間実行操作の進行状況更新
resp.Progress.Set(ctx, "操作を開始中...")
// error ハンドリングで action ロジックを実装
// context をタイムアウト管理に使用
// async 操作の場合は完了をポーリング
resp.Progress.Set(ctx, "操作が完了しました")
}
主要な実装要件
1. 進行状況レポート
- 長時間実行される操作中はリアルタイム更新に
resp.SendProgress(action.InvokeProgressEvent{...})を使用 - 長時間実行される操作中に意味のある進行状況メッセージを提供
- 主要なマイルストーンで進行状況を更新
- 長時間実行される操作に経過時間を含める
2. タイムアウト管理
- 常に設定可能なタイムアウトパラメータを含める(デフォルト: 1800秒)
- API 呼び出しに
context.WithTimeout()を使用 - タイムアウトエラーを適切に処理
- タイムアウト範囲を検証(通常 60-7200 秒)
3. エラーハンドリング
resp.Diagnostics.AddError()で診断を追加- コンテキスト付きの明確なエラーメッセージを提供
- 関連する場合は API エラー詳細を含める
- プロバイダーエラー型をユーザーフレンドリーなメッセージにマップ
- すべての可能なエラーケースをドキュメント化
エラーハンドリングの例:
// 特定のエラーを処理
var notFound *types.ResourceNotFoundException
if errors.As(err, ¬Found) {
resp.Diagnostics.AddError(
"リソースが見つかりません",
fmt.Sprintf("リソース %s が見つかりませんでした", resourceID),
)
return
}
// 一般的なエラーハンドリング
resp.Diagnostics.AddError(
"操作が失敗しました",
fmt.Sprintf("%s の操作を完了できませんでした: %s", resourceID, err),
)
4. プロバイダー SDK 統合
a.Meta().<Service>Client(ctx)からプロバイダー SDK クライアントを使用- リスト操作のページネーションを処理
- 一時的な失敗に対する再試行ロジックを実装
- 適切なエラー型を使用
5. パラメータ検証
- 入力検証にフレームワーク validator を使用
- 操作前にリソースの存在を検証
- 矛盾するパラメータをチェック
- プロバイダーの命名要件に対して検証
6. ポーリングと待機
完了を待つ必要がある操作の場合:
result, err := wait.WaitForStatus(ctx,
func(ctx context.Context) (wait.FetchResult[*ResourceType], error) {
// 現在のステータスを取得
resource, err := findResource(ctx, conn, id)
if err != nil {
return wait.FetchResult[*ResourceType]{}, err
}
return wait.FetchResult[*ResourceType]{
Status: wait.Status(resource.Status),
Value: resource,
}, nil
},
wait.Options[*ResourceType]{
Timeout: timeout,
Interval: wait.FixedInterval(5 * time.Second),
SuccessStates: []wait.Status{"AVAILABLE", "COMPLETED"},
TransitionalStates: []wait.Status{"CREATING", "PENDING"},
ProgressInterval: 30 * time.Second,
ProgressSink: func(fr wait.FetchResult[any], meta wait.ProgressMeta) {
resp.SendProgress(action.InvokeProgressEvent{
Message: fmt.Sprintf("ステータス: %s、経過時間: %v", fr.Status, meta.Elapsed.Round(time.Second)),
})
},
},
)
一般的な Action パターン
バッチ操作
- 設定可能なバッチでアイテムを処理
- バッチごとに進行状況をレポート
- 部分的な失敗を適切に処理
- プレフィックス/フィルターパラメータをサポート
コマンド実行
- コマンドを送信して操作 ID を取得
- 完了ステータスをポーリング
- 出力をレポートして取得
- ポーリング中のタイムアウトを処理
- 実行前にリソースの存在を検証
サービス呼び出し
- パラメータでサービスを呼び出し
- 完了を待機(同期の場合)
- 出力/結果を返す
- サービス固有のエラーを処理
リソーススタイト変更
- 現在のステータスを検証
- ステータス変更を適用
- ターゲットステータスをポーリング
- 過渡的ステータスを処理
Async ジョブ送信
- 設定でジョブを送信
- ジョブ ID を取得
- 必要に応じて完了を待機
- ジョブステータスをレポート
Action トリガー
Actions は Terraform 設定で action_trigger ライフサイクルブロックを介して呼び出されます:
action "provider_service_action" "name" {
config {
parameter = value
}
}
resource "terraform_data" "trigger" {
lifecycle {
action_trigger {
events = [after_create]
actions = [action.provider_service_action.name]
}
}
}
利用可能なトリガーイベント
Terraform 1.14.0 でサポートされるイベント:
before_create- リソース作成前after_create- リソース作成後before_update- リソース更新前after_update- リソース更新後
Terraform 1.14.0 でサポートされていない:
before_destroy- 利用不可(検証エラーが発生)after_destroy- 利用不可(検証エラーが発生)
Actions のテスト
アクセプタンステスト
- 有効なパラメータで action 呼び出しをテスト
- タイムアウトシナリオをテスト
- エラー条件をテスト
- プロバイダーステート変更を検証
- 進行状況レポートをテスト
- カスタムパラメータでテスト
- トリガーベースの呼び出しをテスト
テストパターン
func TestAccServiceAction_basic(t *testing.T) {
ctx := acctest.Context(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(tfversion.Version1_14_0),
},
Steps: []resource.TestStep{
{
Config: testAccActionConfig_basic(),
Check: resource.ComposeTestCheckFunc(
testAccCheckResourceExists(ctx, "provider_resource.test"),
),
},
},
})
}
Sweep 関数を使用したテストクリーンアップ
sweep 関数を追加してテストリソースをクリーンアップ:
func sweepResources(region string) error {
ctx := context.Background()
client := /* region 用クライアントを取得 */
input := &service.ListInput{
// テストリソースをフィルター
}
var sweeperErrs *multierror.Error
pages := service.NewListPaginator(client, input)
for pages.HasMorePages() {
page, err := pages.NextPage(ctx)
if err != nil {
sweeperErrs = multierror.Append(sweeperErrs, err)
continue
}
for _, item := range page.Items {
id := item.Id
// テスト以外のリソースをスキップ
if !strings.HasPrefix(id, "tf-acc-test") {
continue
}
_, err := client.Delete(ctx, &service.DeleteInput{
Id: id,
})
if err != nil {
sweeperErrs = multierror.Append(sweeperErrs, err)
}
}
}
return sweeperErrs.ErrorOrNil()
}
テストのベストプラクティス
サービス固有の前提条件
- action が成功する前に満たす必要があるサービス固有の前提条件を常にチェック
- action ドキュメントとテスト設定で前提条件をドキュメント化
エラーパターンマッチング
- Terraform は action エラーに追加のコンテキストを付与
- 柔軟な正規表現パターンを使用:
regexache.MustCompile(\(?s)Error Title.*key phrase`)`
Actions に適用されないテストパターン
- Actions はライフサイクルイベント時にトリガーされ、config 再適用ではトリガーされない
- Before/After Destroy テスト: Terraform 1.14.0 ではサポートされていない
テスト実行
テストをコンパイルしてエラーをチェック:
go test -c -o /dev/null ./internal/service/<service>
特定の action テストを実行:
TF_ACC=1 go test ./internal/service/<service> -run TestAccServiceAction_ -v
sweep を実行してテストリソースをクリーンアップ:
TF_ACC=1 go test ./internal/service/<service> -sweep=<region> -v
ドキュメント標準
各 action ドキュメントファイルには以下を含める必要があります:
-
フロントマター
--- subcategory: "Service Name" layout: "provider" page_title: "Provider: provider_service_action" description: |- action が何をするかの簡潔な説明。 --- -
警告付きヘッダー
- 実験的ステータスに関する Beta/Alpha 通知
- 意図しない結果の可能性についての警告
- プロバイダードキュメントへのリンク
-
使用例
- 基本的な使用例
- すべてのオプションを含む高度な使用例
terraform_dataを含むトリガーベースの例- 実世界のユースケース例
-
引数リファレンス
- すべての必須および optional 引数をリスト
- 説明とデフォルトを含める
- 検証ルールを記載
-
ドキュメント Linting
- 送信前に
terrafmt fmtを実行 terrafmt diffで検証
- 送信前に
更新ログエントリ形式
.changelog/ ディレクトリに更新ログエントリを作成:
.changelog/<pr_number_or_description>.txt
コンテンツ形式:
action/provider_service_action: action の簡潔な説明
送信前チェックリスト
action 実装を送信する前に:
- コードがコンパイルされる:
go build -o /dev/null . - テストがコンパイルされる:
go test -c -o /dev/null ./internal/service/<service> - コードが形式化されている:
make fmt - ドキュメントが形式化されている:
terrafmt fmt website/docs/actions/<action>.html.markdown - 更新ログエントリが作成されている
- スキーマが正しい型を使用している
- すべての List/Map 属性に ElementType がある
- 長時間実行操作に進行状況更新が実装されている
- エラーメッセージにコンテキストとリソース識別子が含まれている
- ドキュメントに複数の例が含まれている
- ドキュメントに前提条件と警告が含まれている
リファレンス
ライセンス: MPL-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- hashicorp
- ライセンス
- MPL-2.0
- 最終更新
- 不明
Source: https://github.com/hashicorp/agent-skills / ライセンス: MPL-2.0
関連スキル
superpowers-streamer-cli
SuperPowers デスクトップストリーマーの npm パッケージをインストール、ログイン、実行、トラブルシューティングできます。ユーザーが npm から `superpowers-ai` をセットアップしたい場合、メールまたは電話でサインインもしくはアカウント作成を行いたい場合、ストリーマーを起動したい場合、表示されたコントロールリンクを開きたい場合、後で停止したい場合、またはソースコードへのアクセスなしに npm やランタイムの一般的な問題から復旧したい場合に使用します。
catc-client-ops
Catalyst Centerのクライアント操作・監視機能 - 有線・無線クライアントのリスト表示・フィルタリング、MACアドレスによる詳細なクライアント検索、クライアント数分析、時間軸での分析、SSIDおよび周波数帯によるフィルタリング、無線トラブルシューティング機能を提供します。MACアドレスやIPアドレスでのクライアント検索、サイト別やSSID別のクライアント数集計、無線周波数帯の分布分析、Wi-Fi信号の問題調査が必要な場合に活用できます。
ci-cd-and-automation
CI/CDパイプラインの設定を自動化します。ビルドおよびデプロイメントパイプラインの構築または変更時に使用できます。品質ゲートの自動化、CI内のテストランナー設定、またはデプロイメント戦略の確立が必要な場合に活用します。
shipping-and-launch
本番環境へのリリース準備を行います。本番環境へのデプロイ準備が必要な場合、リリース前チェックリストが必要な場合、監視機能の設定を行う場合、段階的なロールアウトを計画する場合、またはロールバック戦略が必要な場合に使用します。
linear-release-setup
Linear Releaseに向けたCI/CD設定を生成します。リリース追跡の設定、LinearのCIパイプライン構築、またはLinearリリースとのデプロイメント連携を実施する際に利用できます。GitHub Actions、GitLab CI、CircleCIなど複数のプラットフォームに対応しています。
tracking-application-response-times
API エンドポイント、データベースクエリ、サービスコール全体にわたるアプリケーションのレスポンスタイムを追跡・最適化できます。パフォーマンス監視やボトルネック特定の際に活用してください。「レスポンスタイムを追跡する」「API パフォーマンスを監視する」「遅延を分析する」といった表現で呼び出せます。