# Authoring desired state

This guide explains how to **author the desired state** in MechCloud Stateless IaC for GCP. You define your infrastructure using a clean, hierarchical YAML format that is inspired by Terraform but significantly simpler — no logical IDs, no state files, and no HCL. Instead, you use **nesting for relationships**, **`snake_case` for properties**, and **`ref:` syntax** for cross-resource references.

### Key Principles

| Principle                    | Description                                                                                                     |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
| **Hierarchy = Relationship** | Nest resources to define parent-child relationships (e.g., subnetwork inside VPC network).                      |
| **Unique Relative Paths**    | Every resource must have a unique path (e.g., `vpc1/subnet1/vm1`). You are responsible for ensuring uniqueness. |
| **`snake_case` Properties**  | All keys use lowercase with underscores (e.g., `auto_create_subnetworks`, not `autoCreateSubnetworks`).         |
| **No Parent Links**          | Do **not** include `network` for subnetwork — MechCloud infers them from nesting.                               |
| **Sibling References**       | Use `ref:<name>` **only** if both resources are in the **same `resources:` block**.                             |
| **Non-Sibling References**   | Use `ref:<full_path>` to reference resources outside the current parent.                                        |

### Step-by-Step: Example to MechCloud Desired State

Here is a GCP desired state example using the `compute.v1.instance` resource. It assumes that the linked resources (Network, Subnetwork) already exist in the same environment.

#### MechCloud Desired State

```yaml
defaults:
  zone: us-central1-a

resources:
  - type: compute.v1.instance
    name: vm1
    props:
      machine_type: machineTypes/e2-micro
      disks:
        - boot: true
          auto_delete: true
          initialize_params:
            # Set to 30GB to maximize the Free Tier limit
            disk_size_gb: 30
            # Set to pd-standard (Standard Persistent Disk) for Free Tier eligibility
            disk_type: diskTypes/pd-standard
            source_image: projects/ubuntu-os-cloud/global/images/family/ubuntu-2404-lts
      network_interfaces:
        - subnetwork: subnetworks/subnet1
          access_configs:
            - type: ONE_TO_ONE_NAT
              name: External NAT
```

### Using `defaults` for Zonal Resources

In GCP, many resources are zonal or regional and require a `zone` or `location` property, as well as full paths that include the region or zone (e.g., `zones/us-central1-a/machineTypes/e2-micro`). To simplify authoring, you can use the `defaults:` block at the top of your YAML file for zones, while the region is automatically inferred from the Execution Context.

By setting a default `zone` in the YAML, MechCloud does two things automatically:

1. **Property Injection**: It injects the `zone` into the resource's `props` if it is missing. You don't need to repeatedly specify `zone: us-central1-a` on every disk or instance, or `location: us-central1-a` on a GKE cluster. (For regional resources, the region selected in the Execution Context dropdown is automatically injected).
2. **Path Expansion**: It expands short paths for you:
   * `machineTypes/e2-micro` becomes `zones/us-central1-a/machineTypes/e2-micro`
   * `diskTypes/pd-standard` becomes `zones/us-central1-a/diskTypes/pd-standard`

This makes your desired state much easier to read and maintain across different environments.

### Referencing Resources

In this template, the instance (`vm1`) needs to refer to the subnetwork in its network interfaces. There is no need to specify the `network` property for the instance, as specifying the subnetwork is sufficient.

Because the subnetwork reference points to a resource that is already existing and not defined in the same template, we provide a path relative to the project id (e.g. `subnetworks/subnet1`) instead of using `ref:`.

**Regional vs Global Paths**:

* If the target subnetwork exists in the **same region** selected in your Execution Context, you can use the short path: `subnetworks/subnet1`. MechCloud will automatically expand this to the full regional path (`regions/<selected-region>/subnetworks/subnet1`).
* If the target subnetwork is in a **different region**, you must specify the full relative path: `regions/europe-west1/subnetworks/subnet1`.
* For global resources (like VPC Networks), you must use the full path: `global/networks/vpc1`.

If the linked resources were being created in the *same* template, you would use the `ref:<name>` or `ref:<full_path>` syntax so MechCloud could resolve their IDs dynamically during plan and apply:

* **Short name (sibling) form:** `ref:<name>` — used when one resource needs the link of another resource that is declared **together under the same parent**.
* **Full-path (non-sibling) form:** `ref:<relative_path>` — used when the referencing resource is in a different part of the hierarchy (different parent).

### Conversion Rules

> **Tip**: Use hyphens in names for readability (e.g., `my-vpc`), but avoid spaces or special characters.

| Terraform / API Property                   | → | MechCloud                    |
| ------------------------------------------ | - | ---------------------------- |
| `type: google_compute_network`             | → | `type: compute.v1.network`   |
| `autoCreateSubnetworks`                    | → | `auto_create_subnetworks`    |
| `network` (for Subnetwork)                 | → | **Remove** — use nesting     |
| `subnetwork: google_compute_subnetwork.id` | → | `subnetwork: ref:vpc/subnet` |

Notes and clarifications:

* `snake_case` is mandatory in MechCloud YAML. MechCloud translates these property names to the GCP API property names when making provider calls (for example `auto_create_subnetworks` → `autoCreateSubnetworks`).
* There are two kinds of `ref:` forms:
  * **Short name (sibling) form:** `ref:<name>` — used when one resource needs the link of another resource that is declared **together under the same parent**.
  * **Full-path (non-sibling) form:** `ref:<relative_path>` — used when the referencing resource is in a different part of the hierarchy (different parent).

### **Resource Paths (Must Be Unique)**

Each resource gets a **unique relative path** based on its nesting within the hierarchy. This path allows MechCloud to resolve references (`ref:`) precisely at plan and apply time.

| Resource   | Path             |
| ---------- | ---------------- |
| Network    | `vpc1`           |
| Subnetwork | `vpc1/subnet1`   |
| Firewall   | `vpc1/allow-ssh` |
| Instance   | `vm1`            |

Each resource’s path must be unique across the entire desired state file.

### Next Steps

1. **Select Execution Context** At the top of the MechCloud console, select the execution context for your operation:
   * **Team** — e.g., `Academy (User 2)`
   * **Cloud Provider** — e.g., `GCP`
   * **Cloud Account** — e.g., `My GCP Project`
   * **Region** — e.g., `us-central1`
   * **Context** — e.g., `app1-dev1`
2. **Generate the Plan** Click **Plan** to generate an execution plan. MechCloud compares the desired state (defined in YAML) with the actual GCP infrastructure and determines which resources require changes.
3. **Review Plan Actions** Each resource in the plan shows an `action` indicating how MechCloud will reconcile it:
   * `create` — the resource does not exist and will be created.
   * `update` — the resource exists but properties differ and will be updated.
   * `delete` — the resource exists but is no longer in the desired state and will be removed.
   * `recreate` — the resource will be deleted and then created again (for non-updatable property changes).
   * `none` — the resource is already in the desired state; no action required.
4. **Apply the Plan (When Changes Exist)**
   * The **Apply** button becomes visible **only when** the plan includes at least one resource whose `action` is not `none`.
   * Click **Apply** to provision or update resources as per the plan.
   * MechCloud will execute the required operations and bring your GCP environment to match the desired state.
5. **Verify Post-Apply State**
   * Once the apply completes, click **Plan** again to re-run the comparison.
   * If all resources now display `action: none`, the desired and actual states are in sync.
   * In this case, the **Apply** button will not be visible because no further changes are required.
6. **Handle Errors (If Any)**
   * If any errors occur during the apply step, re-run **Plan** to refresh dependencies and reconcile state.
   * Then click **Apply** again to retry provisioning with the updated plan.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mechcloud.io/cloud-computing/stateless-iac/gcp/authoring-desired-state.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
