'Can an attribute be both computed and optional in data source in 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)?



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Atkins