Page cover

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.

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
}
  • 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{}).

    • 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.

Create
Update
Updatable?

name

name

Yes

description

description

Yes

domain_name

No. This is an endpoint generated by CloudFront and is pretty much permanent.

town

No. Technically, we can get it updated if we modify the Update function to allow Town reassignment.

content_version

content_version

Yes

Multiverse of Madness: CRUD functions, when and who?

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?

  • Terraform is an infrastructure-as-code software.

  • A plug-in is a software component that adds a specific feature to an existing computer program (Wikipedia). It provides extra functionalities to facilitate the operation of the main software.

  • So what our CRUD functions are doing is helping Terraform to operate better on our custom Cloud resources. So... 🙄 ?

    • Plugin's job: the role of our custom plugin is to help Terraform to stay up to date with the multiple states (2. the state in RAM / 3. the state on the Cloud) 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.

The answers to the Questions

  • Who is calling the CRUD functions?

  • When are the CRUD functions running?

    • When we execute terraform apply. Terraform 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 Update operation of the CRUD functions is different from Updating the actual Cloud resources.

Resources

Last updated