Customer provider authentication fields not passed

Hi,

I’m using the hashicorp/terraform-provider-scaffolding repo to test a custom provider I’m writing as a learning exercise but I’ve gotten stuck trying to authenticate the provider.

This is my error…

│ Error: InternalValidate
│ 
│   with provider["hashicorp.com/edu/acloudguru"],
│   on provider.tf line 1, in provider "acloudguru":
│    1: provider "acloudguru" {
│ 
│ Internal validation of the provider failed! This is always a bug
│ with the provider itself, and not a user issue. Please report
│ this bug:
│ 
│ 1 error occurred:
│       * apikey: One of optional, required, or computed must be set

Snippets of the code used…

func New(version string) func() *schema.Provider {
	return func() *schema.Provider {
		p := &schema.Provider{
			Schema: map[string]*schema.Schema{
				"apikey": &schema.Schema{
					Type:        schema.TypeString,
					Optional:    false,
					Sensitive:   true,
					DefaultFunc: schema.EnvDefaultFunc("ACLOUDGURU_API_KEY", nil),
				},
				"consumerid": &schema.Schema{
					Type:        schema.TypeString,
					Optional:    false,
					Sensitive:   true,
					DefaultFunc: schema.EnvDefaultFunc("ACLOUDGURU_CONSUMER_ID", nil),
				},
			},
			DataSourcesMap: map[string]*schema.Resource{
				"acloudguru_subscription": dataSourceSubscription(),
			},
		}
		p.ConfigureContextFunc = configure(version, p)
		return p
	}
}

type apiClient struct {
	client *acloudguru.Client
}

func configure(version string, p *schema.Provider) func(context.Context, *schema.ResourceData) (interface{}, diag.Diagnostics) {
	return func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
		p.UserAgent("terraform-provider-acloudguru", version)
		apiKey := d.Get("apikey").(string)
		consumerID := d.Get("consumerid").(string)

		client, err := acloudguru.NewClient(&apiKey, &consumerID)
		if err != nil {
			return nil, diag.FromErr(err)
		}

		return &apiClient{
			client: client,
		}, nil
	}
}

func dataSourceSubscriptionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	// use the meta value to retrieve your client from the provider configure method
	client := meta.(*apiClient)

	subscription, err := client.client.GetSubscription()
	if err != nil {
		return diag.FromErr(err)
	}

	if err := d.Set("organisation_id", subscription.OrganisationId); err != nil {
		return diag.FromErr(err)
	}
	if err := d.Set("name", subscription.Name); err != nil {
		return diag.FromErr(err)
	}
	if err := d.Set("start_date", subscription.StartDate.String()); err != nil {
		return diag.FromErr(err)
	}
	if err := d.Set("end_date", subscription.EndDate.String()); err != nil {
		return diag.FromErr(err)
	}
	if err := d.Set("total_seats", subscription.TotalSeats); err != nil {
		return diag.FromErr(err)
	}
	if err := d.Set("seats_in_use", subscription.SeatsInUse); err != nil {
		return diag.FromErr(err)
	}

	d.SetId(strconv.FormatInt(time.Now().Unix(), 10))

	return diag.Errorf("not implemented")
}

Any help would be hugely appreciated as I’ve just hit a complete brick wall with this one.

Cheers, Rich

│       * apikey: One of optional, required, or computed must be set

It means one must be set to true so either Optional or Required.

These fields are set in my terraform config, sorry should have also posted this…

provider "acloudguru" {
  consumerid = "keyshere"
  apikey     = "keyshere"
}

terraform {
  required_providers {
    acloudguru = {
      version = "~> 0.0.1"
      source  = "hashicorp.com/edu/acloudguru"
    }
  }
}

data "acloudguru_subscription" "this" {}

sorry to be clear, you need to tell the configure the provider fields to be either optional: true or required: true

so the above would be below (if both fields are required)

"apikey": &schema.Schema{
	Type:        schema.TypeString,
	Required:    true,
	Sensitive:   true,
	DefaultFunc: schema.EnvDefaultFunc("ACLOUDGURU_API_KEY", nil),
},
"consumerid": &schema.Schema{
	Type:        schema.TypeString,
	Required:    true,
	Sensitive:   true,
	DefaultFunc: schema.EnvDefaultFunc("ACLOUDGURU_CONSUMER_ID", nil),
},
1 Like

Apologies I got side-tracked with work but took another look at this last night and you’re 100% correct. Once I added required as you’ve outlined it worked right away!

Thank you for the written example and the explanation, that helps immensely :slight_smile: