> For the complete documentation index, see [llms.txt](https://gwen-leigh.gitbook.io/multiverse-of-madness-terraform-with-go/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](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).

# 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&amp;token=12e65b46-8578-4250-a549-a09ff08df3bf" alt=""><figcaption></figcaption></figure>

### Resources

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