Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add allowed_account_id provider configuration parameter #226

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ provider "temporalcloud" {
# Also can be set by environment variable `TEMPORAL_CLOUD_ALLOW_INSECURE`
allow_insecure = false
# Also can be set by environment variable `TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID`
allowed_account_id = "my-temporalcloud-account-id"
}
```

Expand All @@ -58,5 +61,6 @@ provider "temporalcloud" {
### Optional

- `allow_insecure` (Boolean) If set to True, it allows for an insecure connection to the Temporal Cloud API. This should never be set to 'true' in production and defaults to false.
- `allowed_account_id` (String) The ID of the account to operate on. Prevents accidental mutation of accounts other than that provided.
- `api_key` (String, Sensitive) The API key for Temporal Cloud. See [this documentation](https://docs.temporal.io/cloud/api-keys) for information on how to obtain an API key.
- `endpoint` (String) The endpoint for the Temporal Cloud API. Defaults to `saas-api.tmprl.cloud:443`.
3 changes: 3 additions & 0 deletions examples/provider/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ provider "temporalcloud" {

# Also can be set by environment variable `TEMPORAL_CLOUD_ALLOW_INSECURE`
allow_insecure = false

# Also can be set by environment variable `TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID`
allowed_account_id = "my-temporalcloud-account-id"
}
45 changes: 39 additions & 6 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package provider

import (
"context"
"fmt"
"os"

"github.com/hashicorp/terraform-plugin-framework/datasource"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"go.temporal.io/api/cloud/cloudservice/v1"

"github.com/temporalio/terraform-provider-temporalcloud/internal/client"
)
Expand All @@ -27,9 +29,10 @@ type TerraformCloudProvider struct {

// TerraformCloudProviderModel describes the provider data model.
type TerraformCloudProviderModel struct {
APIKey types.String `tfsdk:"api_key"`
Endpoint types.String `tfsdk:"endpoint"`
AllowInsecure types.Bool `tfsdk:"allow_insecure"`
APIKey types.String `tfsdk:"api_key"`
Endpoint types.String `tfsdk:"endpoint"`
AllowInsecure types.Bool `tfsdk:"allow_insecure"`
AllowedAccountID types.String `tfsdk:"allowed_account_id"`
}

func (p *TerraformCloudProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
Expand Down Expand Up @@ -69,6 +72,10 @@ in version control. We recommend passing credentials to this provider via enviro
Description: "If set to True, it allows for an insecure connection to the Temporal Cloud API. This should never be set to 'true' in production and defaults to false.",
Optional: true,
},
"allowed_account_id": schema.StringAttribute{
Description: "The ID of the account to operate on. Prevents accidental mutation of accounts other than that provided.",
Optional: true,
},
},
}
}
Expand Down Expand Up @@ -105,6 +112,14 @@ func (p *TerraformCloudProvider) Configure(ctx context.Context, req provider.Con
" Either apply the source of the value first, or statically set the allow_insecure flag via environment variable or in configuration.")
}

if data.AllowedAccountID.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("allowed_account_id"),
"Unknown Terraform Cloud Allowed Account ID Value",
"The provider cannot create a Terraform Cloud API client as there is an unknown configuration value for `allowed_account_id`."+
" Either apply the source of the value first, or statically set the Allowed Account ID value via environment variable or in configuration.")
}

apiKey := os.Getenv("TEMPORAL_CLOUD_API_KEY")
if !data.APIKey.IsNull() {
apiKey = data.APIKey.ValueString()
Expand All @@ -123,14 +138,32 @@ func (p *TerraformCloudProvider) Configure(ctx context.Context, req provider.Con
allowInsecure = data.AllowInsecure.ValueBool()
}

client, err := client.NewConnectionWithAPIKey(endpoint, allowInsecure, apiKey)
allowedAccountID := os.Getenv("TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID")
if !data.AllowedAccountID.IsNull() {
allowedAccountID = data.AllowedAccountID.ValueString()
}

cc, err := client.NewConnectionWithAPIKey(endpoint, allowInsecure, apiKey)
if err != nil {
resp.Diagnostics.AddError("Failed to connect to Temporal Cloud API", err.Error())
return
}

resp.DataSourceData = client
resp.ResourceData = client
if allowedAccountID != "" {
accountResp, err := cc.CloudService().GetAccount(ctx, &cloudservice.GetAccountRequest{})
if err != nil {
resp.Diagnostics.AddError("Failed to validate allowed account ID", fmt.Sprintf("failed to get account details: %s", err.Error()))
return
}
currentAccountID := accountResp.GetAccount().GetId()
if currentAccountID != allowedAccountID {
resp.Diagnostics.AddError("Failed to validate allowed account ID", fmt.Sprintf("current account ID '%s' does not match allowed account ID '%s'", currentAccountID, allowedAccountID))
return
}
}

resp.DataSourceData = cc
resp.ResourceData = cc
}

func (p *TerraformCloudProvider) Resources(ctx context.Context) []func() resource.Resource {
Expand Down
Loading