Add PULUMI_BACKEND_URL env var (#5789)

The PULUMI_BACKEND_URL env var allows specifying the backend to use instead of deferring to the project or the ~/.pulumi/credentials.json file to decide on the "current" backend.  This allows for using Pulumi without a dependence on this piece of global filesystem state, so that each `pulumi` invocation can control the exact backend it want's to operate on, without having to do stateful `pulumi login`/`pulumi logout` operations.

This is especially useful for automation scenarios like Automation API generally (and effectively solves https://github.com/pulumi/pulumi/issues/5591), or https://github.com/pulumi/pulumi-kubernetes-operator/issues/83 specifically.

This also makes things like efe7a599e6/dist/actions/entrypoint.sh (L10) less necessary, and possible to accomplish for any containerized `pulumi` execution without the need for this logic to be embedded in bash scripts wrapping the CLI.
This commit is contained in:
Luke Hoban 2020-11-22 15:27:59 -08:00 committed by GitHub
parent 9a707c4e03
commit 4ecd8f9f56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 8 deletions

View file

@ -3,9 +3,12 @@ CHANGELOG
## HEAD (Unreleased)
- Respect PULUMI_PYTHON_CMD in scripts.
- Respect `PULUMI_PYTHON_CMD` in scripts.
[#5782](https://github.com/pulumi/pulumi/pull/5782)
- Add `PULUMI_BACKEND_URL` environment variable to configure the state backend.
[#5789](https://github.com/pulumi/pulumi/pull/5789)
## 2.14.0 (2020-11-18)
- Propagate secretness of provider configuration through to the statefile. This ensures

View file

@ -44,6 +44,8 @@ type Environment struct {
RootPath string
// Current working directory.
CWD string
// Backend to use for commands
Backend string
}
// WriteYarnRCForTest writes a .yarnrc file which sets global configuration for every yarn inovcation. We use this
@ -88,6 +90,11 @@ func NewEnvironment(t *testing.T) *Environment {
}
}
// SetBackend sets the backend to use for commands in this environment.
func (e *Environment) SetBackend(backend string) {
e.Backend = backend
}
// ImportDirectory copies a folder into the test environment.
func (e *Environment) ImportDirectory(path string) {
err := fsutil.CopyFile(e.RootPath, path, nil)
@ -167,6 +174,9 @@ func (e *Environment) GetCommandResults(t *testing.T, command string, args ...st
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", pulumiCredentialsPathEnvVar, e.RootPath))
cmd.Env = append(cmd.Env, "PULUMI_DEBUG_COMMANDS=true")
cmd.Env = append(cmd.Env, "PULUMI_CONFIG_PASSPHRASE=correct horse battery staple")
if e.Backend != "" {
cmd.Env = append(cmd.Env, fmt.Sprintf("PULUMI_BACKEND_URL=%s", e.Backend))
}
runErr := cmd.Run()
return outBuffer.String(), errBuffer.String(), runErr

View file

@ -31,6 +31,10 @@ import (
// credentials or tests interacting with one another
const PulumiCredentialsPathEnvVar = "PULUMI_CREDENTIALS_PATH"
// PulumiBackendURLEnvVar is an environment variable which can be used to set the backend that will be
// used instead of the currently logged in backend or the current projects backend.
const PulumiBackendURLEnvVar = "PULUMI_BACKEND_URL"
// GetAccount returns an account underneath a given key.
//
// Note that the account may not be fully populated: it may only have a valid AccessToken. In that case, it is up to
@ -129,6 +133,12 @@ func getCredsFilePath() (string, error) {
// have not logged in.
func GetCurrentCloudURL() (string, error) {
var url string
// Allow PULUMI_BACKEND_URL to override the current cloud URL selection
if backend := os.Getenv(PulumiBackendURLEnvVar); backend != "" {
url = backend
}
// Try detecting backend from config
projPath, err := DetectProjectPath()
if err == nil && projPath != "" {

View file

@ -50,7 +50,7 @@ func TestStackCommands(t *testing.T) {
}()
integration.CreateBasicPulumiRepo(e)
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", "foo")
stacks, current := integration.GetStacks(e)
@ -79,7 +79,7 @@ func TestStackCommands(t *testing.T) {
}()
integration.CreateBasicPulumiRepo(e)
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", "blighttown")
e.RunCommand("pulumi", "stack", "init", "majula")
e.RunCommand("pulumi", "stack", "init", "lothric")
@ -118,7 +118,7 @@ func TestStackCommands(t *testing.T) {
integration.CreateBasicPulumiRepo(e)
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", "blighttown")
e.RunCommand("pulumi", "stack", "init", "majula")
e.RunCommand("pulumi", "stack", "init", "lothric")
@ -166,7 +166,7 @@ func TestStackCommands(t *testing.T) {
}()
integration.CreateBasicPulumiRepo(e)
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", "the-abyss")
stacks, _ := integration.GetStacks(e)
assert.Equal(t, 1, len(stacks))
@ -214,7 +214,7 @@ func TestStackCommands(t *testing.T) {
stackName := addRandomSuffix("invalid-resources")
integration.CreateBasicPulumiRepo(e)
e.ImportDirectory("integration/stack_dependencies")
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", stackName)
e.RunCommand("yarn", "install")
e.RunCommand("yarn", "link", "@pulumi/pulumi")
@ -298,7 +298,7 @@ func TestStackBackups(t *testing.T) {
}
}()
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", stackName)
// Build the project.
@ -356,7 +356,7 @@ func TestStackRenameAfterCreate(t *testing.T) {
}()
stackName := addRandomSuffix("stack-rename")
integration.CreateBasicPulumiRepo(e)
e.RunCommand("pulumi", "login", "--cloud-url", e.LocalURL())
e.SetBackend(e.LocalURL())
e.RunCommand("pulumi", "stack", "init", stackName)
newName := addRandomSuffix("renamed-stack")