Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I select from optional fields instead of using a required field?

Tags:

terraform

I'm trying to add a data source data_source_person that supports 2 methods of input:

Schema: map[string]*schema.Schema{
    "id": {
        Type: schema.TypeString,
        Computed:    true,
        Optional:    true,
    },
    "first_name": {
        Type:        schema.TypeString,
        Computed:    true,
        Optional:    true,
    },
},

Namely, a value for either id or first_name should be specified but not both (it's a oneOf relationship).

In case "id" is specified the code will execute GET /people/{ID} otherwise "display_name" must be specified and in this scenario GET /people will be called that will return a list of people and the code will run a filter to find the ID of a person that have response.data.people[i].display_name == {providedDisplayName}.

Does TF data sources support this kind of configuration (both attributes are computed, optional)?

like image 327
Alex Kuzminov Avatar asked Oct 31 '25 20:10

Alex Kuzminov


2 Answers

It is possible to specify in the schema that the attribute is both computed and optional, but you would more often see this in a resource schema. In a resource and data source schema, the optional signifies an optional input, and the computed signifies its value can be computed during provisioning. It is possible for these to co-exist, as the argument or block could either be input or output. It would not be possible for e.g. required to be true and computed to be true, since that would be an input and output, and these would conflict.

Additionally, based on the description in your question, you would also want to utilize ExactlyOneOf:

Schema: map[string]*schema.Schema{
  "id": {
    Type:         schema.TypeString,
    Optional:     true,
    Computed:     true,
    ExactlyOneOf: []string{"id", "first_name"},
  },
  "first_name": {
    Type:         schema.TypeString,
    Optional:     true,
    Computed:     true,
    ExactlyOneOf: []string{"id", "first_name"},
  },
},
like image 118
Matt Schuchard Avatar answered Nov 02 '25 21:11

Matt Schuchard


Optional and Computed together is a good choice for any argument which is serving as a sort of filtering constraint, where the user may either specify it in order to constrain the request or omit it in order to learn the value of that attribute as configured in the remote system.

You can see some real examples of this in the AWS provider. For example, the aws_vpc data source uses this pattern for its cidr_block argument, which can be used either as a constraint or as an output:

    "cidr_block": {
        Type:     schema.TypeString,
        Optional: true,
        Computed: true,
    },

When using this pattern, the provider should distinguish between the argument being set or unset, treating it as an extra constraint on the query if set, or leaving it unconstrained if unset. Then in the latter case, the corresponding value from the query to the remote system would be written into the attribute as part of the result.

like image 32
Martin Atkins Avatar answered Nov 02 '25 22:11

Martin Atkins