Is there a way to say a parameter is not present in a terraform resource

When I am creating a resource is there a way to know a parameter is not set on a given resource?

When you do a plan or before you accept changes on an apply Terraform should be showing you all the changes it will make. So you should be able to see exactly what is going to be set for any resources that will be created.

ok thanks, but every parameter will get a value if it is set or not

Could you give a more concrete example of a resource you are asking about?

The plan should be saying exactly what every parameter is being set to (including the null value which indicates it isn’t set to anything)

I am trying to auto-generate a tf-provider from yang files. this would help the networking industry a lot.
Here is an example:

E.g. I have a resource with the following parameter:

“export_policy”: {
Type: schema.TypeString,
Optional: true,
},

Now if I create the resource and if export_policy is not defined.
Like this:

resource “bgp_neighbor” “this” {
network_instance_id = network_instance.this.id
bgp_id = bgp.this.id
neighbor {
peer_address = “172.1.1.1”
admin_state = “enable”
description = “terraform neighbor”
peer_as = 65002
peer_group =bgp_group.this.id
}
}

What I see when I create the resource the parameter gets an empty string assigned, but the device does not accept empty strings. The yang rules of the device require the string to have at least 1 char.

typedef name {
type alphanumeric {
length “1…255”;
}

So right now the user should define all the parameters if they are needed or not. So I am trying to see how I can improve this. Any suggestion ?

When you say that you are “trying to auto-generate a tf-provider from yang files”, do you mean you are writing a custom Terraform provider plugin, or that you are using an existing provider but are generating tf files using a tool?

If you are using an existing provider, which one is it?

I am writing a new provider which would be generated from the yang files of the device

If you are writing a new provider you get to choose how everything works. So if an attribute is required or needs a certain structure your code can enforce that. Equally you can decide what happens when an optional attribute isn’t set.

The provider is basically a converter between a set of resource definitions (which generally map fairly simply to the underlying calls, but might have differences to align better with Terraform styles - for example using multiple blocks for some sort of rule, or a block for related settings) and the underlying API the system/device needs.

You have the freedom to determine the interface you are exposing to Terraform (in the form of whatever resources and data sources you design), any local validation or manipulation you want (the more you can do the better as it means a terraform validate or plan will tell you about errors, instead of an apply failing with an error passed from the system/device) and how the system/device is communicated with.

From what you are saying it sounds like either there is a required field that needs to have a value of at least one character or that you need to not be sending certain API calls or fields if an optional attribute isn’t enabled. For the former that sounds like you need to adjust the interface definition and validation code for the resource. For the second it sounds like you need to adjust the code that actually constructs the API calls for your device.

Sorry if I’m not understanding what this new provider does.

Indeed I was trying to see if there was an ability to check in the sdk that a parameter was set or not. Would make my job a bit easier :slight_smile:

Ahh. I now understand the question :smile:

Hi!

Determining if an optional parameter is set or not within the configuration is sometimes rather difficult and often not functionally possible, sadly - due to zero values. Especially so with a string type and not something more simple like a boolean, I believe.

The functions you’re looking for are GetOk and its deprecated (but still used) sibling GetOkExists within the SDK.

See this other thread regarding the unfortunate pitfalls of these, though.

Indeed, the current SDK is built around Terraform v0.11 concepts and so it’s not yet aware of null (unset) values which were introduced for the first time in Terraform v0.12. As @chrisarcand noted, the SDK either replaces them with the default value, if set, or with Go’s idea of the “zero value” of the specified type.

For now I would suggest treating "" as meaning “unset” and accepting that this means that users could in theory write export_policy = "" and have it treated as the same as omitting export_policy altogether. While that’s not ideal, it’s consistent with how other Terraform providers written against the current SDK behave, and so should not be surprising to folks who are familiar with Terraform.

The Terraform SDK team is working towards a new SDK which has full understanding of the Terraform language type system from Terraform v0.12 and later, which will hopefully eventually allow explicitly distinguishing set from unset without this ambiguity. However, so far (at the time I’m writing this) there is only a low-level utility library which is at a very low level of abstraction. You could potentially build a provider against that library and thus be able to distinguish null from "", but it will require considerably more code than using the current higher-level SDK framework so I personally would not go to that effort just for the situation you’ve described, where the ambiguity doesn’t seem to have any serious consequences.

1 Like