package test import ( "github.com/hashicorp/terraform/helper/schema" ) func testResourceList() *schema.Resource { return &schema.Resource{ Create: testResourceListCreate, Read: testResourceListRead, Update: testResourceListUpdate, Delete: testResourceListDelete, CustomizeDiff: func(d *schema.ResourceDiff, _ interface{}) error { if d.HasChange("dependent_list") { d.SetNewComputed("computed_list") } return nil }, Schema: map[string]*schema.Schema{ "list_block": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "string": { Type: schema.TypeString, Optional: true, }, "int": { Type: schema.TypeInt, Optional: true, }, "force_new": { Type: schema.TypeString, Optional: true, ForceNew: true, }, "sublist": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, }, }, "sublist_block": { Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "string": { Type: schema.TypeString, Required: true, }, "int": { Type: schema.TypeInt, Required: true, }, }, }, }, "sublist_block_optional": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "list": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, }, }, }, }, "dependent_list": { Type: schema.TypeList, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "val": { Type: schema.TypeString, Required: true, }, }, }, }, "computed_list": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "min_items": { Type: schema.TypeList, Optional: true, MinItems: 2, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "val": { Type: schema.TypeString, Required: true, }, }, }, }, "never_set": { Type: schema.TypeList, MaxItems: 1, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "sublist": { Type: schema.TypeList, MaxItems: 1, ForceNew: true, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "bool": { Type: schema.TypeBool, ForceNew: true, Required: true, }, "string": { Type: schema.TypeString, Computed: true, }, }, }, }, }, }, }, "map_list": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeMap}, }, }, } } func testResourceListCreate(d *schema.ResourceData, meta interface{}) error { d.SetId("testId") return testResourceListRead(d, meta) } func testResourceListRead(d *schema.ResourceData, meta interface{}) error { fixedIps := d.Get("dependent_list") // all_fixed_ips should be set as computed with a CustomizeDiff func, but // we're trying to emulate legacy provider behavior, and updating a // computed field was a common case. ips := []interface{}{} if fixedIps != nil { for _, v := range fixedIps.([]interface{}) { m := v.(map[string]interface{}) ips = append(ips, m["val"]) } } if err := d.Set("computed_list", ips); err != nil { return err } // "computing" these values should insert empty containers into the // never_set block. values := make(map[string]interface{}) values["sublist"] = []interface{}{} d.Set("never_set", []interface{}{values}) return nil } func testResourceListUpdate(d *schema.ResourceData, meta interface{}) error { block := d.Get("never_set").([]interface{}) if len(block) > 0 { // if profiles contains any values, they should not be nil _ = block[0].(map[string]interface{}) } return testResourceListRead(d, meta) } func testResourceListDelete(d *schema.ResourceData, meta interface{}) error { d.SetId("") return nil }