A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/identity below:

Resources - Identity | Terraform

A resource identity is a data object, determined by the provider, that is stored alongside the resource state to uniquely identify a remote object. Resource identity is supported in Terraform 1.12 and later.

A resource identity should have the following properties:

To define the identity object for a managed resource, a resource identity schema is provided that consists of a map of attribute names and associated behaviors.

The resource identity schema is similar to the resource state schema, but with the following differences:

It is expected that exactly one of RequiredForImport or OptionalForImport is set to true. Regardless of which option is chosen, the provider can decide exactly what data is stored in the identity during import, similar to Computed attributes in resource state.

The identity schema can be set in a new (*schema.Resource).Identity field:

func resourceThing() *schema.Resource {
  return &schema.Resource{
    CreateContext: resourceThingCreate,
    ReadContext:   resourceThingRead,
    UpdateContext: resourceThingUpdate,
    DeleteContext: resourceThingDelete,

    Schema: map[string]*schema.Schema{
      // .. resource schema for examplecloud_thing
    },

    Identity: &schema.ResourceIdentity{
      SchemaFunc: func() map[string]*schema.Schema {
        return map[string]*schema.Schema{
          "id": {
            Type:              schema.TypeString,
            RequiredForImport: true, // must be set during import by the practitioner
          },
          "region": {
            Type:              schema.TypeString,
            OptionalForImport: true, // can be defaulted by the provider configuration
          },
        }
      },
    },
  }
}

Identity data, similar to resource state data, can be set or retrieved during the resource Create, Read, Update, Delete and Importer functions. Unlike resource state data, identity data is expected to be immutable after it is set during Create, so typically the only locations a provider should need to write identity data is during Create and Read.

Read should return identity data so that the managed resource can support importing, especially if not all of the identity attributes are provided by the practitioner during import (like provider configuration values and remote API data).

Writing Identity

Typically, identity data should be set during Create and Read. The *schema.IdentityData struct is used to write identity data and can be retrieved via the *schema.ResourceData struct, for example:

// .. rest of resource implementation

func resourceThingCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
  // Read data from *schema.ResourceData

  // Call remote API to create resource (i.e. apiResp)

  // Set data returned by API in state with (*schema.ResourceData).Set()

  // Retrieve the identity data object
  identity, err := d.Identity()
  if err != nil {
    return diag.FromErr(err)
  }

  // Set data returned by the API in identity
  err = identity.Set("id", apiResp.ID)
  if err != nil {
    return diag.FromErr(err)
  }
  err = identity.Set("region", apiResp.Region)
  if err != nil {
    return diag.FromErr(err)
  }

  return nil
}
Reading Identity

The *schema.IdentityData struct is used to read identity data and can be retrieved via the *schema.ResourceData struct, for example:

// .. rest of resource implementation

func resourceThingRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
  // Retrieving ID from resource state
  thingID := d.Id()

  // Retrieving ID from resource identity
  identity, err := d.Identity()
  if err != nil {
    return diag.FromErr(err)
  }
  thingIDFromIdentity := identity.Get("id").(string)

  // Call remote API to read resource

  // Set data returned by API in state with (*schema.ResourceData).Set()
  // Set data returned by API in identity

  return nil
}

Managed resources that define an identity can be imported by either the id or the resource identity. The user must set either id or identity and not both. Supplying both or none will result in a validation error. For example, the identity presented in the "Define Identity" section, can be imported via the following methods:

terraform import examplecloud_thing.test id-123
import {
  to = examplecloud_thing.test
  id = "id-123"
}
import {
  to = examplecloud_thing.test
  identity = {
    id = "id-123" # required for import
    region = "us-east-1" # optional for import
  }
}

If identity data is present in the request, the provider is expected to ignore anything returned by the (*schema.ResourceData).ID() function (which Core will set to ""). To maintain compatibility with the terraform import CLI command and the import block with id field, providers must continue to support importing via import ID if the identity data is not present.

For resources that only need to support Terraform v1.12+, providers may choose not to support an import ID at all. In this case, if the user supplies an import ID (via the terraform import CLI command or in an import block), Terraform will send an import request to the provider including a non-empty string returned by the (*schema.ResourceData).ID() function, and the provider can choose to return an error saying that it is not supported.

An example Importer implementation that accounts for both importing by id and importing by identity:

func resourceThing() *schema.Resource {
  return &schema.Resource{
    // .. other resource fields

    Importer: &schema.ResourceImporter{
      StateContext: func(ctx context.Context, d *ResourceData, m interface{}) ([]*ResourceData, error) {
        // If importing by ID, we just set the ID field to state, allowing the read to fill in the rest of the data.
        if d.Id() != "" {
          return []*ResourceData{d}, nil
        }
    
        // Otherwise, we're importing by identity. We can read the identity and use it to set data to state to be used in Read.
        identity, err := d.Identity()
        if err != nil {
          return nil, fmt.Errorf("error getting identity: %s", err)
        }
    
        // It's still required by SDKv2 to set ID, we can also use other attributes in the identity
        // to set more state data on *schema.ResourceData
        d.SetId(identity.Get("id").(string))
    
        return []*ResourceData{d}, nil
      },
    },
  }
}

If the identity is a single attribute that is passed through to a single attribute in state, the schema.ImportStatePassthroughWithIdentity helper function can be used, which will set the same state attribute with either identity data or the ID string field:

func resourceThing() *schema.Resource {
  return &schema.Resource{
    // .. other resource fields

    Importer: &schema.ResourceImporter{
      StateContext: schema.ImportStatePassthroughWithIdentity("id"), // will call d.SetId with either the ID import string or the identity attribute value at "id".
    },
  }
}

By default, if identity data unexpectedly changes during the resource's lifecycle, an error will be raised by the SDK:

Error: Unexpected Identity Change

During the <update/read/planning> operation, the Terraform Provider unexpectedly returned a
different identity then the previously stored one. 

If the remote object has an identity that can be changed without being destroyed/re-created, this validation can be disabled by setting the schema.ResourceBehavior.MutableIdentity field to true, which is set on the schema.Resource struct:

func resourceThing() *schema.Resource {
  return &schema.Resource{
    // .. other resource fields

    Identity: &schema.ResourceIdentity{
      SchemaFunc: func() map[string]*schema.Schema {
        return map[string]*schema.Schema{
          // .. identity schema
        }
      },
    },
    ResourceBehavior: schema.ResourceBehavior{
      MutableIdentity: true,
    },
  }
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4