원클릭으로
tgc-add-new-handwritten-resource-skill
Add a new handwritten resource to TGC. Use when you need to add a new handwritten resource to TGC Next.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Add a new handwritten resource to TGC. Use when you need to add a new handwritten resource to TGC Next.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Skill for reviewing Magic Modules schemas. Currently covers the Enum vs. String decision via the knowledge base.
Opt resource into MMv1 list-resource generation by setting `generate_list_resource: true`, validate it locally, and open a one-resource PR against GoogleCloudPlatform/magic-modules. Invoke when the user asks to add list-resource support for a specific MMv1 resource or to enable `generate_list_resource` for an eligible resource.
Fallback workflow for general implementation and debugging tasks that do not involve creating a new resource.
Workflow specifically for creating a new resource, supporting both autogen and manual generation.
Create a Pull Request (PR) against GoogleCloudPlatform/magic-modules following repository standards, including branch management, commit formatting, mandatory release notes, pre-PR verification checks, and gh CLI commands.
Validate that changes to the generated providers don't introduce breaking changes or fields with missing tests or missing documentation. Use this skill when the user wants to check for breaking changes, missing tests, or missing documentation, or other problems in the downstream providers.
| name | tgc-add-new-handwritten-resource-skill |
| description | Add a new handwritten resource to TGC. Use when you need to add a new handwritten resource to TGC Next. |
When you need to add a new handwritten resource to the TGC Next conversion pipeline, use this skill.
Adding a new handwritten resource to TGC Next involves creating Go-level definitions, implementing the flattener and expander, registering them in code generator templates, and validating.
Locate the resource's configuration YAML under mmv1/products/<product>/<ResourceName>.yaml.
include_in_tgc_next: true is set at the top level.Resource struct in mmv1/api/resource.go.exclude_resource: true should generally be set to skip standard autogeneration of provider and converter code.If the product service folder does not exist under mmv1/third_party/tgc_next/pkg/services/<product>/, create it. Then, add three files:
resource_<resource_name>.go (Schema Definition)This file defines the CAI asset type, the Terraform schema name, the resource schema, and handles registry initialization.
package <product>
import (
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/cai2hcl/models"
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/cai2hcl/registry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// The CAI asset type corresponding to this resource
const <ResourceName>AssetType string = "whatever.googleapis.com/<AssetType>"
// The Terraform resource name
const <ResourceName>SchemaName string = "google_<product>_<resource_name>"
// Return the resource schema (typically copied from the Terraform Google provider)
func Resource<ResourceName>() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Schema: map[string]*schema.Schema{
"field_name": {
Type: schema.TypeString,
Optional: true,
// ...
},
},
}
}
func init() {
registry.Schema{
Name: <ResourceName>SchemaName,
ProductName: "<product>",
Type: registry.SchemaTypeResource,
Schema: Resource<ResourceName>(),
}.Register()
}
resource_<resource_name>_tfplan2cai.go (Expander / HCL to CAI Converter)This file converts the planned Terraform resource data into raw CAI asset JSON payloads during roundtrip tests and plan conversions.
package <product>
import (
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/tfplan2cai/converters/cai"
)
func <ResourceName>Tfplan2caiConverter() cai.ResourceConverter {
return cai.ResourceConverter{
Convert: Get<ResourceName>CaiObject,
}
}
func Get<ResourceName>CaiObject(d cai.TerraformResourceData, config *cai.Config) ([]cai.Asset, error) {
// Construct the CAI asset path matching GCS/CAI requirements
name, err := cai.AssetName(d, config, "//whatever.googleapis.com/projects/{{project}}/whatevers/{{name}}")
if err != nil {
return []cai.Asset{}, err
}
if obj, err := Get<ResourceName>ApiObject(d, config); err == nil {
return []cai.Asset{{
Name: name,
Type: <ResourceName>AssetType,
Resource: &cai.AssetResource{
Version: "v1",
DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/...",
DiscoveryName: "<ResourceName>",
Data: obj,
},
}}, nil
} else {
return []cai.Asset{}, err
}
}
func Get<ResourceName>ApiObject(d cai.TerraformResourceData, config *cai.Config) (map[string]interface{}, error) {
obj := make(map[string]interface{})
// Map values from the Terraform resource data 'd' into the 'obj' map
if v, ok := d.GetOk("field_name"); ok {
obj["fieldName"] = v
}
// Add custom field expansions here
return obj, nil
}
resource_<resource_name>_cai2hcl.go (Flattener / CAI to HCL Converter)This file takes the CAI asset payload and converts it back into HCL resource blocks.
package <product>
import (
"fmt"
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/cai2hcl/common"
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/cai2hcl/models"
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/caiasset"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
type <ResourceName>Cai2hclConverter struct {
name string
schema map[string]*schema.Schema
}
func New<ResourceName>Cai2hclConverter(provider *schema.Provider) models.Cai2hclConverter {
schema := provider.ResourcesMap[<ResourceName>SchemaName].Schema
return &<ResourceName>Cai2hclConverter{
name: <ResourceName>SchemaName,
schema: schema,
}
}
func (c *<ResourceName>Cai2hclConverter) Convert(assets []caiasset.Asset, options *models.ResourceConverterOptions) ([]*models.TerraformResourceBlock, error) {
var blocks []*models.TerraformResourceBlock
for _, asset := range assets {
block, err := c.convertResourceData(asset, options)
if err != nil {
return nil, err
}
if block != nil {
blocks = append(blocks, block)
}
}
return blocks, nil
}
func (c *<ResourceName>Cai2hclConverter) convertResourceData(asset caiasset.Asset, options *models.ResourceConverterOptions) (*models.TerraformResourceBlock, error) {
if asset.Resource == nil || asset.Resource.Data == nil {
return nil, fmt.Errorf("asset resource data is nil")
}
hclData := make(map[string]interface{})
// Map fields from asset.Resource.Data (which is a map[string]interface{}) into hclData
if val, ok := asset.Resource.Data["fieldName"]; ok {
hclData["field_name"] = val
}
// Add custom flattening logic here
ctyVal, err := common.MapToCtyValWithSchema(hclData, c.schema)
if err != nil {
return nil, err
}
// Determine the HCL block name, using options if provided
var resourceName string
if options != nil && options.ResourceName != "" {
resourceName = options.ResourceName
} else {
var err error
resourceName, err = common.GetResourceName(asset.Name)
if err != nil {
resourceName = "default"
}
}
return &models.TerraformResourceBlock{
Labels: []string{c.name, resourceName},
Value: ctyVal,
}, nil
}
To implement the schema definitions, flatteners, and expanders for individual fields of the resource, follow the steps in tgc-add-field-to-handwritten-resource-skill.
Because conversion mappings are generated dynamically into the downstream binary, you must register your custom converters inside the template files:
mmv1/templates/tgc_next/cai2hcl/resource_converters.go.tmpl and add the mapping under // ####### START handwritten resources ###########:
"<cai_asset_type>": {
"Default": <product>.New<ResourceName>Cai2hclConverter(provider),
},
mmv1/templates/tgc_next/tfplan2cai/resource_converters.go.tmpl and add the mapping under // ####### START handwritten resources ###########:
"google_<product>_<resource_name>": <product>.<ResourceName>Tfplan2caiConverter(),
Follow these commands to generate code and compile changes:
# 1. Generate TGC downstream code
make tgc OUTPUT_PATH="/path/to/your/terraform-google-conversion"
# 2. Compile and run downstream tests
cd /path/to/your/terraform-google-conversion
make mod-clean
make build
Verify your new resource mapping by executing the appropriate integration test.