diff --git a/cli/cliflag/cliflag_test.go b/cli/cliflag/cliflag_test.go
index 542bb04abfd9d..2228b7e10bbc9 100644
--- a/cli/cliflag/cliflag_test.go
+++ b/cli/cliflag/cliflag_test.go
@@ -16,11 +16,11 @@ import (
 //nolint:paralleltest
 func TestCliflag(t *testing.T) {
 	t.Run("StringDefault", func(t *testing.T) {
-		var p string
+		var ptr string
 		flagset, name, shorthand, env, usage := randomFlag()
 		def, _ := cryptorand.String(10)
 
-		cliflag.StringVarP(flagset, &p, name, shorthand, env, def, usage)
+		cliflag.StringVarP(flagset, &ptr, name, shorthand, env, def, usage)
 		got, err := flagset.GetString(name)
 		require.NoError(t, err)
 		require.Equal(t, def, got)
@@ -29,24 +29,24 @@ func TestCliflag(t *testing.T) {
 	})
 
 	t.Run("StringEnvVar", func(t *testing.T) {
-		var p string
+		var ptr string
 		flagset, name, shorthand, env, usage := randomFlag()
 		envValue, _ := cryptorand.String(10)
 		t.Setenv(env, envValue)
 		def, _ := cryptorand.String(10)
 
-		cliflag.StringVarP(flagset, &p, name, shorthand, env, def, usage)
+		cliflag.StringVarP(flagset, &ptr, name, shorthand, env, def, usage)
 		got, err := flagset.GetString(name)
 		require.NoError(t, err)
 		require.Equal(t, envValue, got)
 	})
 
 	t.Run("EmptyEnvVar", func(t *testing.T) {
-		var p string
+		var ptr string
 		flagset, name, shorthand, _, usage := randomFlag()
 		def, _ := cryptorand.String(10)
 
-		cliflag.StringVarP(flagset, &p, name, shorthand, "", def, usage)
+		cliflag.StringVarP(flagset, &ptr, name, shorthand, "", def, usage)
 		got, err := flagset.GetString(name)
 		require.NoError(t, err)
 		require.Equal(t, def, got)
@@ -55,11 +55,11 @@ func TestCliflag(t *testing.T) {
 	})
 
 	t.Run("IntDefault", func(t *testing.T) {
-		var p uint8
+		var ptr uint8
 		flagset, name, shorthand, env, usage := randomFlag()
 		def, _ := cryptorand.Int63n(10)
 
-		cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
+		cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
 		got, err := flagset.GetUint8(name)
 		require.NoError(t, err)
 		require.Equal(t, uint8(def), got)
@@ -68,37 +68,37 @@ func TestCliflag(t *testing.T) {
 	})
 
 	t.Run("IntEnvVar", func(t *testing.T) {
-		var p uint8
+		var ptr uint8
 		flagset, name, shorthand, env, usage := randomFlag()
 		envValue, _ := cryptorand.Int63n(10)
 		t.Setenv(env, strconv.FormatUint(uint64(envValue), 10))
 		def, _ := cryptorand.Int()
 
-		cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
+		cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
 		got, err := flagset.GetUint8(name)
 		require.NoError(t, err)
 		require.Equal(t, uint8(envValue), got)
 	})
 
 	t.Run("IntFailParse", func(t *testing.T) {
-		var p uint8
+		var ptr uint8
 		flagset, name, shorthand, env, usage := randomFlag()
 		envValue, _ := cryptorand.String(10)
 		t.Setenv(env, envValue)
 		def, _ := cryptorand.Int63n(10)
 
-		cliflag.Uint8VarP(flagset, &p, name, shorthand, env, uint8(def), usage)
+		cliflag.Uint8VarP(flagset, &ptr, name, shorthand, env, uint8(def), usage)
 		got, err := flagset.GetUint8(name)
 		require.NoError(t, err)
 		require.Equal(t, uint8(def), got)
 	})
 
 	t.Run("BoolDefault", func(t *testing.T) {
-		var p bool
+		var ptr bool
 		flagset, name, shorthand, env, usage := randomFlag()
 		def, _ := cryptorand.Bool()
 
-		cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
+		cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
 		got, err := flagset.GetBool(name)
 		require.NoError(t, err)
 		require.Equal(t, def, got)
@@ -107,26 +107,26 @@ func TestCliflag(t *testing.T) {
 	})
 
 	t.Run("BoolEnvVar", func(t *testing.T) {
-		var p bool
+		var ptr bool
 		flagset, name, shorthand, env, usage := randomFlag()
 		envValue, _ := cryptorand.Bool()
 		t.Setenv(env, strconv.FormatBool(envValue))
 		def, _ := cryptorand.Bool()
 
-		cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
+		cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
 		got, err := flagset.GetBool(name)
 		require.NoError(t, err)
 		require.Equal(t, envValue, got)
 	})
 
 	t.Run("BoolFailParse", func(t *testing.T) {
-		var p bool
+		var ptr bool
 		flagset, name, shorthand, env, usage := randomFlag()
 		envValue, _ := cryptorand.String(10)
 		t.Setenv(env, envValue)
 		def, _ := cryptorand.Bool()
 
-		cliflag.BoolVarP(flagset, &p, name, shorthand, env, def, usage)
+		cliflag.BoolVarP(flagset, &ptr, name, shorthand, env, def, usage)
 		got, err := flagset.GetBool(name)
 		require.NoError(t, err)
 		require.Equal(t, def, got)
diff --git a/cli/start.go b/cli/start.go
index 7f7aa6d4c11dc..da0545a79a5b0 100644
--- a/cli/start.go
+++ b/cli/start.go
@@ -13,6 +13,7 @@ import (
 	"net/url"
 	"os"
 	"os/signal"
+	"path/filepath"
 	"time"
 
 	"github.com/briandowns/spinner"
@@ -42,6 +43,7 @@ func start() *cobra.Command {
 	var (
 		accessURL   string
 		address     string
+		cacheDir    string
 		dev         bool
 		postgresURL string
 		// provisionerDaemonCount is a uint8 to ensure a number > 0.
@@ -161,7 +163,7 @@ func start() *cobra.Command {
 
 			provisionerDaemons := make([]*provisionerd.Server, 0)
 			for i := 0; uint8(i) < provisionerDaemonCount; i++ {
-				daemonClose, err := newProvisionerDaemon(cmd.Context(), client, logger)
+				daemonClose, err := newProvisionerDaemon(cmd.Context(), client, logger, cacheDir)
 				if err != nil {
 					return xerrors.Errorf("create provisioner daemon: %w", err)
 				}
@@ -305,6 +307,8 @@ func start() *cobra.Command {
 
 	cliflag.StringVarP(root.Flags(), &accessURL, "access-url", "", "CODER_ACCESS_URL", "", "Specifies the external URL to access Coder")
 	cliflag.StringVarP(root.Flags(), &address, "address", "a", "CODER_ADDRESS", "127.0.0.1:3000", "The address to serve the API and dashboard")
+	// systemd uses the CACHE_DIRECTORY environment variable!
+	cliflag.StringVarP(root.Flags(), &cacheDir, "cache-dir", "", "CACHE_DIRECTORY", filepath.Join(os.TempDir(), ".coder-cache"), "Specifies a directory to cache binaries for provision operations.")
 	cliflag.BoolVarP(root.Flags(), &dev, "dev", "", "CODER_DEV_MODE", false, "Serve Coder in dev mode for tinkering")
 	cliflag.StringVarP(root.Flags(), &postgresURL, "postgres-url", "", "CODER_PG_CONNECTION_URL", "", "URL of a PostgreSQL database to connect to")
 	cliflag.Uint8VarP(root.Flags(), &provisionerDaemonCount, "provisioner-daemons", "", "CODER_PROVISIONER_DAEMONS", 1, "The amount of provisioner daemons to create on start.")
@@ -358,14 +362,15 @@ func createFirstUser(cmd *cobra.Command, client *codersdk.Client, cfg config.Roo
 	return nil
 }
 
-func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger slog.Logger) (*provisionerd.Server, error) {
+func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger slog.Logger, cacheDir string) (*provisionerd.Server, error) {
 	terraformClient, terraformServer := provisionersdk.TransportPipe()
 	go func() {
 		err := terraform.Serve(ctx, &terraform.ServeOptions{
 			ServeOptions: &provisionersdk.ServeOptions{
 				Listener: terraformServer,
 			},
-			Logger: logger,
+			CachePath: cacheDir,
+			Logger:    logger,
 		})
 		if err != nil {
 			panic(err)
diff --git a/coder.service b/coder.service
index 9e1952688b206..3fc9a01f1e588 100644
--- a/coder.service
+++ b/coder.service
@@ -16,6 +16,7 @@ PrivateTmp=yes
 PrivateDevices=yes
 SecureBits=keep-caps
 AmbientCapabilities=CAP_IPC_LOCK
+CacheDirectory=coder
 CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE
 NoNewPrivileges=yes
 ExecStart=/usr/bin/coder start
diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go
index 62ea5ef9b2764..24656c09520b4 100644
--- a/provisioner/terraform/provision.go
+++ b/provisioner/terraform/provision.go
@@ -87,6 +87,14 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
 			})
 		}
 	}()
+	if t.cachePath != "" {
+		err = terraform.SetEnv(map[string]string{
+			"TF_PLUGIN_CACHE_DIR": t.cachePath,
+		})
+		if err != nil {
+			return xerrors.Errorf("set terraform plugin cache dir: %w", err)
+		}
+	}
 	terraform.SetStdout(writer)
 	t.logger.Debug(shutdown, "running initialization")
 	err = terraform.Init(shutdown)
diff --git a/provisioner/terraform/serve.go b/provisioner/terraform/serve.go
index bda2944ea0701..ef8f039d51412 100644
--- a/provisioner/terraform/serve.go
+++ b/provisioner/terraform/serve.go
@@ -34,6 +34,7 @@ type ServeOptions struct {
 	// BinaryPath specifies the "terraform" binary to use.
 	// If omitted, the $PATH will attempt to find it.
 	BinaryPath string
+	CachePath  string
 	Logger     slog.Logger
 }
 
@@ -43,8 +44,9 @@ func Serve(ctx context.Context, options *ServeOptions) error {
 		binaryPath, err := exec.LookPath("terraform")
 		if err != nil {
 			installer := &releases.ExactVersion{
-				Product: product.Terraform,
-				Version: version.Must(version.NewVersion("1.1.7")),
+				InstallDir: options.CachePath,
+				Product:    product.Terraform,
+				Version:    version.Must(version.NewVersion("1.1.7")),
 			}
 
 			execPath, err := installer.Install(ctx)
@@ -58,11 +60,13 @@ func Serve(ctx context.Context, options *ServeOptions) error {
 	}
 	return provisionersdk.Serve(ctx, &terraform{
 		binaryPath: options.BinaryPath,
+		cachePath:  options.CachePath,
 		logger:     options.Logger,
 	}, options.ServeOptions)
 }
 
 type terraform struct {
 	binaryPath string
+	cachePath  string
 	logger     slog.Logger
 }