# Provider Configuration

## 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.

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, data sources, actions, or functions

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
  additionalActions:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_action
      action: custom.NewCustomAction
  additionalFunctions:
    - importAlias: custom
      importLocation: github.com/custom/terraform-provider-example/src/custom_function
      function: custom.NewCustomFunction
```

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.

The `additionalActions` key is expected to contain a list of `{ importLocation?: string, importAlias?: string, action: string }` objects. Each `action` is inserted into the provider-managed action list. If `importLocation` or `importAlias` is defined, Speakeasy adds them to the import list at the top of the provider file.

The `additionalFunctions` key is expected to contain a list of `{ importLocation?: string, importAlias?: string, function: string }` objects. Each `function` is inserted into the provider-managed function list. If `importLocation` or `importAlias` is defined, Speakeasy adds them to the import list at the top of the provider file.

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

## Override provider type name

<Callout title="Uncommon customization" type="info">
  Most providers should omit `providerTypeNameOverride` and rely on the default
  behavior of prefixing resource type names with `packageName`. Only use this
  configuration to ship a variant provider that must share resource type names
  with another provider.
</Callout>

By default, Terraform resource and action type names are prefixed with the `packageName` value from `gen.yaml`. Set the `providerTypeNameOverride` configuration to replace that prefix with a different value, while retaining `packageName` for Go module naming, binary naming, and Terraform Registry publishing.

The common use case for this is supporting a variant provider, such as a beta provider, that intentionally shares resource type names with a related provider. It mirrors the `google` and `google-beta` provider pattern, where both providers expose the same resource type names so Terraform configurations can switch between them using the [`provider` meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/provider).

In this example, a beta provider published as `examplecloud-beta` exposes resources with the `examplecloud` prefix to match the stable `examplecloud` provider:

```yaml
terraform:
  packageName: examplecloud-beta
  providerTypeNameOverride: examplecloud
```

Without this configuration, resources would be named `examplecloud-beta_thing`. With this configuration, resources are instead named `examplecloud_thing`, matching the resource type names of the stable provider. Terraform configurations can then select the beta implementation using the `provider` meta-argument:

```hcl
resource "examplecloud_thing" "example" {
  provider = examplecloud-beta

  # ...
}
```
