# crUd resourceHouseUpdate()

* **TL;DR**
  * The `Read` and `Update` functions in our custom plugin are used for updating the local states. They compare against and set the object `d` (the local in-memory state) with the actual state fetched from the cloud service.
  * Both the `Read` and `Update` functions typically run under the hood by Terraform engine when we run `terraform apply`. Once the in-memory state is updated based on the current state on the cloud through our plugin, Terraform takes over and performs the actual resource update operation itself. &#x20;
* [The source code: main.go](https://github.com/omenking/terraform-beginner-bootcamp-2023/blob/2.4.0/terraform-provider-terratowns/main.go#L240)

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```go
func resourceHouseUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
	var diags diag.Diagnostics

	config := m.(*Config)

	homeUUID := d.Id()

	payload := map[string]interface{}{
		"name": d.Get("name").(string),
		"description": d.Get("description").(string),
		"content_version": d.Get("content_version").(int),
	}
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return diag.FromErr(err)
	}

	// Construct the HTTP Request
	url := config.Endpoint+"/u/"+config.UserUuid+"/homes/"+homeUUID
	
	req, err := http.NewRequest("PUT", url, bytes.NewBuffer(payloadBytes))
	if err != nil {
		return diag.FromErr(err)
	}

	// Set Headers
	req.Header.Set("Authorization", "Bearer "+config.Token)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json")

	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return diag.FromErr(err)
	}
	defer resp.Body.Close()

	// StatusOK = 200 HTTP Response Code
	if resp.StatusCode != http.StatusOK {
		return diag.FromErr(fmt.Errorf("failed to update home resource, status_code: %d, status: %s", resp.StatusCode, resp.Status))
	}

	d.Set("name",payload["name"])
	d.Set("description",payload["description"])
	d.Set("content_version",payload["content_version"])
	return diags
}
```

{% endcode %}

* **Lines 8-12**: Construct a data structure called `payload`
  * `payload` is a map of string-type keys (`map[string]`) that takes any types of data for value (`interface{}`).&#x20;
  * Compare the `payload` for the Update function against the `payload` for Create. While Create requires the values for all five attributes for the house resource, Update allows modification of only three attributes.

<table><thead><tr><th width="200.33333333333331">Create</th><th width="185">Update</th><th>Updatable?</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>name</code></td><td>Yes</td></tr><tr><td><code>description</code></td><td><code>description</code></td><td>Yes</td></tr><tr><td><code>domain_name</code></td><td></td><td>No. This is an endpoint generated by CloudFront and is pretty much permanent.</td></tr><tr><td><code>town</code></td><td></td><td>No. Technically, we can get it updated if we modify the Update function to allow Town reassignment. </td></tr><tr><td><code>content_version</code></td><td><code>content_version</code></td><td>Yes</td></tr></tbody></table>

## Multiverse of Madness: CRUD functions, when and who?&#x20;

Did you notice that the Read and Update functions are actually not doing anything other than updating the in-memory terraform state in line with the actual state on the cloud? Then when exactly is the actual update of the actual cloud resources happening?&#x20;

* Terraform is an infrastructure-as-code software.&#x20;
* A plug-in is *a software component that adds a specific feature to an existing computer program* ([Wikipedia](https://en.wikipedia.org/wiki/Plug-in_\(computing\))). It provides extra functionalities to facilitate the operation of the main software.&#x20;
* So what our CRUD functions are doing is helping Terraform to operate better on our custom Cloud resources. So... :rolling\_eyes: ?&#x20;
  * **Plugin's job**: the role of our custom plugin is to help Terraform to stay up to date with the multiple states (<mark style="background-color:purple;">2. the state in RAM</mark> / <mark style="background-color:green;">3. the state on the Cloud</mark>) of the custom resources we use.
  * **Terraform's job**: when the plug-in's job is complete, Terraform's core engine takes over and performs the actual update of the actual resources.&#x20;

### The answers to the Questions

* <mark style="background-color:purple;">**Who**</mark>**&#x20;is calling** the CRUD functions?&#x20;
* <mark style="color:red;">**When**</mark> are the CRUD functions running?&#x20;
  * <mark style="color:red;">**When we execute**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`terraform apply`**</mark>. <mark style="background-color:purple;">**Terraform**</mark> calls the Read and Update functions under the hood to see if there is any difference between the local RAM state and the actual on-the-Cloud state.
* Note that the <mark style="background-color:purple;">Update operation of the CRUD functions</mark> is different from <mark style="color:green;">Updating the actual Cloud resources</mark>.

<figure><img src="https://1712665346-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F56KCNXKO8CxQIkEx9FB3%2Fuploads%2FcEFsOdpnDCW15zT0B67P%2FCRUD%20-%20update.png?alt=media&#x26;token=12e65b46-8578-4250-a549-a09ff08df3bf" alt=""><figcaption></figcaption></figure>

### Resources

* [Plug-in](https://en.wikipedia.org/wiki/Plug-in_\(computing\))


---

# 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://gwen-leigh.gitbook.io/multiverse-of-madness-terraform-with-go/2-4-0-custom-terraform-provider-resource-and-crud-go/crud-functions/crud-resourcehouseupdate.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.
