|
1 | 1 | # Copilot Instructions for meshStack Terraform Provider |
2 | 2 |
|
3 | | -## Repository Overview |
| 3 | +## Overview |
4 | 4 |
|
5 | | -This is the official **meshStack Terraform Provider** developed by meshcloud GmbH. It enables Infrastructure as Code (IaC) management of meshStack resources through Terraform by integrating with the meshStack meshObject API. |
| 5 | +Official Terraform Provider for managing meshStack resources via Infrastructure as Code using the meshObject API (`/api/meshobjects`). |
| 6 | +- **API Docs**: https://docs.meshcloud.io/api/index.html#mesh_objects |
| 7 | +- **Architecture**: Standard Terraform Provider Plugin Framework |
6 | 8 |
|
7 | | -**Key Information:** |
8 | | -- **Purpose**: Manage meshStack cloud resources (projects, workspaces, tenants, building blocks, etc.) using Terraform |
9 | | -- **API Integration**: Uses the meshStack meshObject API (`/api/meshobjects` endpoints) |
10 | | -- **API Documentation**: https://docs.meshcloud.io/api/index.html#mesh_objects |
11 | | -- **Provider Registry**: https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs |
12 | | -- **License**: MPL-2.0 |
| 9 | +## Key Directories |
13 | 10 |
|
14 | | -## Architecture Overview |
15 | | - |
16 | | -This provider follows the standard Terraform Provider Plugin Framework pattern: |
17 | | - |
18 | | -``` |
19 | | -├── main.go # Provider entry point |
20 | | -├── internal/provider/ # Provider implementation (resources, data sources) |
21 | | -├── client/ # API client for meshStack meshObject API |
22 | | -├── docs/ # Terraform registry documentation |
23 | | -├── examples/ # Example Terraform configurations |
24 | | -└── templates/ # Documentation templates |
25 | | -``` |
26 | | - |
27 | | -## Directory Structure |
28 | | - |
29 | | -### `/internal/provider/` |
30 | | -Contains all Terraform provider implementation: |
31 | | -- **`provider.go`**: Main provider configuration and setup |
32 | | -- **`*_resource.go`**: Resource implementations (Create, Read, Update, Delete) |
33 | | -- **`*_data_source.go`**: Data source implementations (Read-only) |
34 | | -- **Pattern**: Each meshObject type has separate resource and data source files |
35 | | - |
36 | | -### `/client/` |
37 | | -meshStack API client implementation: |
38 | | -- **`client.go`**: Core HTTP client with authentication |
39 | | -- **`*.go`**: Individual API client methods for each resource type |
40 | | -- **Authentication**: JWT token-based with automatic refresh |
41 | | -- **API Base Path**: `/api/meshobjects` |
42 | | - |
43 | | -### `/docs/` |
44 | | -Terraform registry documentation (auto-generated): |
45 | | -- **`index.md`**: Provider documentation |
46 | | -- **`resources/`**: Resource documentation |
47 | | -- **`data-sources/`**: Data source documentation |
48 | | - |
49 | | -### `/examples/` |
50 | | -Example Terraform configurations for testing and documentation |
| 11 | +- **`internal/provider/`**: Provider implementation (`provider.go`, `*_resource.go`, `*_data_source.go`) |
| 12 | +- **`client/`**: meshStack API client (JWT auth, RESTful CRUD operations) |
| 13 | +- **`docs/`**: Auto-generated Terraform registry documentation |
| 14 | +- **`examples/`**: Example Terraform configurations |
51 | 15 |
|
52 | 16 | ## Development Patterns |
53 | 17 |
|
54 | | -### Resource Implementation Pattern |
55 | | -Each resource follows this structure: |
56 | | -```go |
57 | | -type resourceName struct { |
58 | | - client *client.MeshStackProviderClient |
59 | | -} |
60 | | - |
61 | | -// Standard Terraform resource interface methods: |
62 | | -func (r *resourceName) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) |
63 | | -func (r *resourceName) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) |
64 | | -func (r *resourceName) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) |
65 | | -func (r *resourceName) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) |
66 | | -func (r *resourceName) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) |
67 | | -``` |
68 | | - |
69 | | -### API Client Pattern |
70 | | -API clients follow RESTful patterns: |
71 | | -```go |
72 | | -func (c *MeshStackProviderClient) CreateResource(resource ResourceType) (*ResourceType, error) |
73 | | -func (c *MeshStackProviderClient) ReadResource(id string) (*ResourceType, error) |
74 | | -func (c *MeshStackProviderClient) UpdateResource(resource ResourceType) (*ResourceType, error) |
75 | | -func (c *MeshStackProviderClient) DeleteResource(id string) error |
76 | | -``` |
77 | | - |
78 | | -### Schema Patterns |
79 | | -Resources use consistent schema structures: |
80 | | -- `api_version` - meshObject API version |
| 18 | +### meshObject Schema Structure |
| 19 | +All resources follow this standard schema: |
| 20 | +- `api_version` - API version |
81 | 21 | - `kind` - meshObject type (e.g., "meshProject", "meshWorkspace") |
82 | | -- `metadata` - Object metadata (name, uuid, timestamps, etc.) |
83 | | -- `spec` - Object specification (user-defined configuration) |
84 | | -- `status` - Object status (system-managed state) |
| 22 | +- `metadata` - Object metadata (name, uuid, timestamps) |
| 23 | +- `spec` - User-defined configuration |
| 24 | +- `status` - System-managed state |
85 | 25 |
|
86 | 26 | ### meshEntity Reference Pattern |
87 | | -When referring to other meshEntities (like `project_role_ref` in landingzone resources), implement them with this pattern: |
88 | | -- **User provides**: Only the `name` attribute (required) |
89 | | -- **System sets**: The `kind` attribute automatically (computed with default value) |
90 | | - |
91 | | -Example implementation: |
92 | | -```go |
93 | | -schema.SingleNestedAttribute{ |
94 | | - MarkdownDescription: "the meshProject role", |
95 | | - Required: true, |
96 | | - Attributes: map[string]schema.Attribute{ |
97 | | - "name": schema.StringAttribute{ |
98 | | - Required: true, |
99 | | - MarkdownDescription: "The identifier of the meshProjectRole", |
100 | | - }, |
101 | | - "kind": schema.StringAttribute{ |
102 | | - MarkdownDescription: "meshObject type, always `meshProjectRole`.", |
103 | | - Computed: true, |
104 | | - Default: stringdefault.StaticString("meshProjectRole"), |
105 | | - Validators: []validator.String{ |
106 | | - stringvalidator.OneOf([]string{"meshProjectRole"}...), |
107 | | - }, |
108 | | - PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, |
109 | | - }, |
110 | | - }, |
111 | | -} |
112 | | -``` |
113 | | - |
114 | | -This pattern ensures: |
115 | | -- Simplified user experience (only need to specify the name) |
116 | | -- Consistent reference structure across all meshEntity references |
117 | | - |
118 | | -## Common Development Tasks |
119 | | - |
120 | | -### Adding a New Resource |
121 | | -1. Create `*_resource.go` in `/internal/provider/` |
122 | | -2. Implement the resource interface (Create, Read, Update, Delete, Schema) |
123 | | -3. Add API client methods in `/client/` |
124 | | -4. Register resource in `provider.go` |
125 | | -5. Create example in `/examples/resources/*/` |
126 | | -6. Run `go generate` to update documentation |
127 | | - |
128 | | -### meshObject API Integration |
129 | | -- All resources are meshObjects with standard structure |
130 | | -- Use consistent error handling and HTTP status checking |
131 | | -- Implement proper authentication token refresh |
132 | | -- Follow meshStack API conventions for CRUD operations |
133 | | - |
134 | | -### Data Structure Guidelines |
135 | | -**Pointer and `omitempty` Usage:** |
136 | | -- Only use pointers (`*type`) and `omitempty` JSON tags for fields that are **actually nullable** in the backend API |
137 | | -- Non-nullable fields should use value types (e.g., `string`, `int64`, `bool`) without `omitempty` |
138 | | -- This ensures proper validation and prevents sending incorrect null values to the API |
| 27 | +For references to other meshEntities (e.g., `project_role_ref`): |
| 28 | +- User provides: `name` (required) |
| 29 | +- System sets: `kind` (computed with default, e.g., `stringdefault.StaticString("meshProjectRole")`) |
| 30 | +- Use validators: `stringvalidator.OneOf()` for kind validation |
| 31 | +- Use plan modifiers: `stringplanmodifier.UseStateForUnknown()` for kind |
| 32 | + |
| 33 | +## Development Guidelines |
| 34 | + |
| 35 | +### Code Review Requirements |
| 36 | +- Verify that `CHANGELOG.md` includes entries for all changes (features, fixes, breaking changes) |
| 37 | + |
| 38 | +### Adding New Resources |
| 39 | +1. Create `*_resource.go` in `/internal/provider/` with CRUD + Schema methods |
| 40 | +2. Add API client methods in `/client/` |
| 41 | +3. Register in `provider.go` |
| 42 | +4. Add example in `/examples/resources/*/` |
| 43 | +5. Run `go generate` for docs |
| 44 | +6. Update `CHANGELOG.md` with appropriate entry |
| 45 | + |
| 46 | +### Data Structure Rules |
| 47 | +- **Use pointers & `omitempty`** only for fields that are **actually nullable** in the backend API |
| 48 | +- **Non-nullable fields**: Use value types (`string`, `int64`, `bool`) without `omitempty` |
139 | 49 | - Example: |
140 | 50 | ```go |
141 | 51 | type Resource struct { |
142 | 52 | RequiredField string `json:"requiredField" tfsdk:"required_field"` // Non-nullable |
143 | | - OptionalField *string `json:"optionalField,omitempty" tfsdk:"optional_field"` // Nullable in backend |
| 53 | + OptionalField *string `json:"optionalField,omitempty" tfsdk:"optional_field"` // Nullable |
144 | 54 | } |
145 | 55 | ``` |
146 | | - |
147 | | -## Key Dependencies |
148 | | - |
149 | | -- **Terraform Plugin Framework**: Latest stable version for provider development |
150 | | -- **Standard Library**: HTTP client, JSON marshaling, context handling |
151 | | -- **meshStack API**: RESTful API following meshObject patterns |
0 commit comments