Search code examples
goterraformterraform-provider-aws

How to configure provider level attributes using the Terraform provider framework


I wanted to implement a provider level configuration functionality so that I can pass an optional specific ARN for the provider to use in special cases.

for eg.

provider "custom_provider" {
     arn = "arn:aws:service:region-1:123456789012"
}

I created providers Schema.

func (p *customProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "arn": schema.StringAttribute{
                Optional: true,
        },
    }
}

and implement provider data model

type customProviderModel struct {
    Arn     types.String `tfsdk:"arn"`
}

Implement configuration functionality

func (p *customProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
    var config customProviderModel
    var arn string    

    diags := req.Config.Get(ctx, &config)
    resp.Diagnostics.Append(diags...)
    if resp.Diagnostics.HasError() {
        return
    }

    if !config.Arn.IsNull() {
        arn = config.Arn.ValueString()
    }


but I don't know how to pass the arn to Data Source from the configuration so that I can use the arn to assume a role while I'm doing a Read functionality inside the Data source.

Basically I wanted to have something similar to aws provider where we can pass the region on some special cases.

provider "aws" {
     region = "us-east-1"
}

Solution

  • The resp *provider.ConfigureResponse argument to your Configure implementation is a ConfigureResponse object that you need to populate in your function.

    The DataSourceData and ResourceData fields both accept an object of any type, and the framework will store those two values and then pass them verbatim to the Configure methods of your DataSource or Resource implementations.

    To recieve those values your DataSource and Resource objects must implement DataSourceWithConfigure or ResourceWithConfigure respectively. The ConfigureRequest objects passed to each of those includes the same data object you returned in DataSourceData or ResourceData.

    You can use this mechanism to save whatever information your data source and resource type implementations will need from the provider configuration. A typical design is for the provider-level Configure to return a pre-configured client for whatever client library you are using to interact with the real remote system, and then the data source and resource type implementations will make their requests using that client.