Configure Terraform provider auth through env vars (#290)

## Changes

Auth relied on setting a profile. In this change we enumerate all
configuration properties and export all non-empty ones as a map with
environment variables. We then pass this map to the Terraform execution
wrapper.

This results in Terraform using the bundle's authentication
configuration.

This change is needed to make #287 work.

## Tests

Manually.
This commit is contained in:
Pieter Noordhuis 2023-03-29 20:46:09 +02:00 committed by GitHub
parent cfd32c9602
commit 87207bba78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 1 deletions

View File

@ -17,6 +17,7 @@ import (
"github.com/databricks/bricks/libs/git" "github.com/databricks/bricks/libs/git"
"github.com/databricks/bricks/libs/locker" "github.com/databricks/bricks/libs/locker"
"github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go"
sdkconfig "github.com/databricks/databricks-sdk-go/config"
"github.com/hashicorp/terraform-exec/tfexec" "github.com/hashicorp/terraform-exec/tfexec"
) )
@ -127,3 +128,34 @@ func (b *Bundle) GitRepository() (*git.Repository, error) {
return git.NewRepository(rootPath) return git.NewRepository(rootPath)
} }
// AuthEnv returns a map with environment variables and their values
// derived from the workspace client configuration that was resolved
// in the context of this bundle.
//
// This map can be used to configure authentication for tools that
// we call into from this bundle context.
func (b *Bundle) AuthEnv() (map[string]string, error) {
if b.client == nil {
return nil, fmt.Errorf("workspace client not initialized yet")
}
cfg := b.client.Config
out := make(map[string]string)
for _, attr := range sdkconfig.ConfigAttributes {
// Ignore profile so that downstream tools don't try and reload
// the profile even though we know the current configuration is valid.
if attr.Name == "profile" {
continue
}
if len(attr.EnvVars) == 0 {
continue
}
if attr.IsZero(cfg) {
continue
}
out[attr.EnvVars[0]] = attr.GetString(cfg)
}
return out, nil
}

View File

@ -52,7 +52,6 @@ func convPermission(ac resources.Permission) schema.ResourcePermissionsAccessCon
func BundleToTerraform(config *config.Root) *schema.Root { func BundleToTerraform(config *config.Root) *schema.Root {
tfroot := schema.NewRoot() tfroot := schema.NewRoot()
tfroot.Provider = schema.NewProviders() tfroot.Provider = schema.NewProviders()
tfroot.Provider.Databricks.Profile = config.Workspace.Profile
tfroot.Resource = schema.NewResources() tfroot.Resource = schema.NewResources()
for k, src := range config.Resources.Jobs { for k, src := range config.Resources.Jobs {

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings"
"github.com/databricks/bricks/bundle" "github.com/databricks/bricks/bundle"
"github.com/databricks/bricks/bundle/config" "github.com/databricks/bricks/bundle/config"
@ -14,6 +15,7 @@ import (
"github.com/hashicorp/hc-install/product" "github.com/hashicorp/hc-install/product"
"github.com/hashicorp/hc-install/releases" "github.com/hashicorp/hc-install/releases"
"github.com/hashicorp/terraform-exec/tfexec" "github.com/hashicorp/terraform-exec/tfexec"
"golang.org/x/exp/maps"
) )
type initialize struct{} type initialize struct{}
@ -89,6 +91,18 @@ func (m *initialize) Apply(ctx context.Context, b *bundle.Bundle) ([]bundle.Muta
return nil, err return nil, err
} }
env, err := b.AuthEnv()
if err != nil {
return nil, err
}
// Configure environment variables for auth for Terraform to use.
log.Debugf(ctx, "Environment variables for Terraform: %s", strings.Join(maps.Keys(env), ", "))
err = tf.SetEnv(env)
if err != nil {
return nil, err
}
b.Terraform = tf b.Terraform = tf
return nil, nil return nil, nil
} }