I’m writing my own terraform provider that I recently upgrade to using the sdk.
Lately I’ve noticed that this errors keep showing up in the logs:
rovider "ecs" produced an unexpected new value for ecs_test.a-test, but we are tolerating it because it is using the legacy plugin SDK.
The following problems may be the cause of any confusing errors from downstream operations:
- .notifier[0].to: was null, but now cty.StringVal("")
- .notifier[0].url: was null, but now cty.StringVal("")
- .notifier[0].service: was null, but now cty.StringVal("")
- .steps[0].body: was null, but now cty.StringVal("")
I’ve read this: Context around the log entry "...tolerating it because it is using the legacy plugin SDK." and after reading it I understand that my provider is working correctly as of right now.
Seeing that I don’t have a requisite to support 0.11. Are there any changes I can do that will allow me to get rid of this warnings?
Another issue I’ve faced is that I have the following schema definition:
"steps": &schema.Schema{
Type: schema.TypeList,
Required: true,
Optional: false,
ForceNew: true,
MinItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"url": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"body": {
Type: schema.TypeString,
Required: false,
ForceNew: true,
Optional: true,
},
"body_json": {
Type: schema.TypeMap,
Required: false,
ForceNew: true,
Optional: true,
},
"method": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
}, true),
},
"timeout": {
Type: schema.TypeString,
ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
v, ok := val.(string)
if !ok {
errs = append(errs, fmt.Errorf("error casting val %s to string", val))
return
}
_, err := time.ParseDuration(v)
if err != nil {
errs = append(errs, fmt.Errorf("error parsing intervale to a valid duration %+v", err))
}
return
},
Required: false,
Optional: true,
ForceNew: true,
Default: "10s",
},
"headers": {
Type: schema.TypeMap,
Required: false,
ForceNew: true,
Optional: true,
},
"vars": {
Type: schema.TypeMap,
Required: false,
Optional: true,
ForceNew: true,
StateFunc: func(v interface{}) string {
if v == nil {
log.Printf("VARS IS NIL")
} else {
log.Printf("VARS: Storing %+v", v)
}
switch v.(type) {
case map[string]interface{}:
b, err := json.Marshal(v)
if err != nil {
panic(fmt.Errorf("error marshalling state to store %+v", err))
}
return string(b[:])
default:
return "{}"
}
},
},
"checks": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: jsonDiffSuppress,
StateFunc: jsonStringCompact,
ValidateFunc: validation.ValidateJsonString,
},
"proxy": {
Type: schema.TypeBool,
Required: false,
Optional: true,
ForceNew: true,
Default: false,
},
},
},
},
So the problem I’m getting is that when I need to recreate this resource. I end up seeing diffs that say this:
- vars = {} -> null
And if i check the tfstate i see a “null” string. Is there something I can do to avoid seeing this change? I’ve tried setting up the “StateFunc” but I’m guessing it’s not called for “sub-resources”
I understand that it won’t brake anything but the issue is that people with less terraform knowledge will use this provider and I’d like for them to be as easy as possible.