# Provider configuration
Source: https://speakeasy.com/docs/terraform/customize/provider-configuration

import { Callout } from "@/mdx/components";
import { Table } from "@/mdx/components";



## Security

The generated Terraform Provider will automatically implement all global security, as defined in the OpenAPI Specification, via the root-level `security` property and its associated `securitySchemes` components. Multiple security options are supported.

<Table
  data={[
    {
      mechanism: "HTTP Basic",
      support: "✅",
    },
    {
      mechanism: "HTTP Bearer",
      support: "✅",
    },
    {
      mechanism: "API Key",
      support: "✅ Header and Query",
    },
    {
      mechanism: "OAuth 2",
      support: "✅ Client Credentials flow",
    },
    {
      mechanism: "Custom security schemes",
      support:
        "✅ [Fully customizable](/docs/customize/authentication/custom-security-schemes)",
    },
  ]}
  columns={[
    { key: "mechanism", header: "Authentication Mechanism" },
    { key: "support", header: "Terraform Support" },
  ]}
/>

In this example, the generated provider requires a bearer authentication token using an `access_token` provider-level attribute:

```yaml
components:
  securitySchemes:
    accessToken:
      type: http
      scheme: bearer
security:
  - accessToken: []
```

Refer to the [Configuring environment variables](#configuring-environment-variables) section to optionally enable the fallback environment variable configuration of the value.

Operation-level security is also supported where it is implemented per-resource, however it is not recommended. Instead, we recommend implementing separate providers for each security layer. Terraform practitioners are conventionally used to the layering of provider implementations for this use case, and Terraform itself is designed around this separation of concerns. Refer to the [HashiCorp provider design principles](https://developer.hashicorp.com/terraform/plugin/best-practices/hashicorp-provider-design-principles) for more context.

## Server URL

Choose how the generated Terraform Provider will handle the server URL for API requests:

- Hardcoded server URL in Speakeasy generation configuration (`gen.yaml` file `generation` section `baseServerUrl` property) and not configurable in Terraform configurations.
- As defined in the OpenAPI Specification, via the root-level `servers` property. The generation will automatically handle:
  - Creating a `server_url` attribute that defaults to the first defined `url` value and is configurable in Terraform configurations.
  - Creating server URL variable attributes that default to their defined `default` values and are configurable in Terraform configurations.

<Callout title="Use single server URL" type="info">
  It is recommended to use a single server URL for Terraform generation. Setting
  up multiple server URLs will create potentially confusing configuration
  options for Terraform consumers since variables across all server URLs are
  exposed.
</Callout>

In this example, the provider configuration is generated with configurable `location` and `server_url` attributes:

```yaml
servers:
  - url: https://{location}.example.com
    variables:
      location:
        default: production
```

Refer to the [Configuring environment variables](#configuring-environment-variables) section to optionally enable the fallback environment variable configuration of the value(s).

Path-level and operation-level servers are also supported where it is implemented per-resource, however it is not recommended. Instead, we recommend implementing separate providers for each server layer. Terraform practitioners are conventionally used to the layering of provider implementations for this use case, and Terraform itself is designed around this separation of concerns. Refer to the [HashiCorp provider design principles](https://developer.hashicorp.com/terraform/plugin/best-practices/hashicorp-provider-design-principles) for more context.

## Globals

Use the [`x-speakeasy-globals` extension](/docs/customize/globals) to enable provider-level configuration of common properties across multiple resources. This customization allows Terraform practitioners to configure a value in three ways:

- **Provider-level only:** The default value is applied to any resources that use the global.
- **Resource-level only:** The explicit value is applied only to those resource instance(s).
- **Provider-level with resource-level override:** The default value is applied to any resources that use the global, but any explicit resource-level configurations override the provider-level value.

In this example, the provider will accept an `organization_id` configuration as a global:

```yaml
x-speakeasy-globals:
  parameters:
    - name: organizationId
      in: path
      schema:
        type: string
```

## Configuring environment variables

Use the `environmentVariables` configuration in the `gen.yaml` to set up an environment variable fallback for configuring provider attribute data. For example, the fallback may be accepting an access token value via an environment variable, rather than requiring an explicit `provider` block attribute configuration from Terraform practitioners.

```yaml
terraform:
  environmentVariables:
    - env: EXAMPLE_SERVER_URL_FROM_ENV_VAR
      providerAttribute: server_url
    - env: EXAMPLE_ACCESS_TOKEN
      providerAttribute: access_token
```

The `environmentVariables` configuration is expected to be a list of objects with `{env: string, providerAttribute: string}` keys and values. These associate environment variables (referenced as `env`) with provider attributes (referenced as `providerAttribute`).

## Additional provider configurations

Use the `additionalProviderAttributes` configuration in the `gen.yaml` file to enable Terraform configurations to specify additional provider-wide customizations. For example:

```yaml
terraform:
  additionalProviderAttributes:
    # ... configuration ...
```

### Custom HTTP headers

Set the `httpHeaders` configuration with the desired attribute name to enable Terraform configurations to map additional HTTP headers for all HTTP requests.

In this example, HTTP header customization is enabled using the `http_headers` provider attribute name:

```yaml
terraform:
  additionalProviderAttributes:
    httpHeaders: http_headers
```

This configuration enables a provider configuration, such as:

```hcl
provider "examplecloud" {
  http_headers = {
    "X-Example-Header" = "example-value"
  }
}
```

### Skip TLS verification

Set the `tlsSkipVerify` configuration with the desired attribute name to enable Terraform configurations to specify a Boolean to disable TLS verification in the HTTP client.

In this example, TLS verification customization is enabled using the `tls_skip_verify` provider attribute name:

```yaml
terraform:
  additionalProviderAttributes:
    tlsSkipVerify: tls_skip_verify
```

This configuration enables a provider configuration, such as:

```hcl
provider "examplecloud" {
  tls_skip_verify = true
}
```

## Custom resources or data sources

To include an existing resource that is outside of the Speakeasy-generated provider, reference it in `gen.yaml` as follows:

```yaml
terraform:
  additionalResources:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_resource
      resource: custom.NewCustomResource
  additionalDataSources:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_datasource
      datasource: custom.NewCustomDataSource
  additionalEphemeralResources:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_ephemeral_resource
      resource: custom.NewCustomEphemeralResource
  additionalListResources:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_list_resource
      resource: custom.NewCustomListResource
```

The `additionalResources` key is expected to contain a list of `{ importLocation?: string, importAlias?: string, resource: string }` objects. Each `resource` is inserted into the provider-managed resource list. If `importLocation` or `importAlias` is defined, Speakeasy adds them to the import list at the top of the provider file. The value of `resource` is arbitrary text, and could contain a function invocation if desired.

The `additionalEphemeralResources` and `additionalListResources` keys follow the same syntax, but insert ephemeral resources and list resources into the provider respectively.

The `additionalDataSources` key follows the same syntax, but inserts data resources into the provider using `datasource` (instead of `resource`) as the value inserted into the list.

To learn more about how to write a Terraform resource, please consult the [official Terraform documentation](https://developer.hashicorp.com/terraform/plugin/framework).