Add configurable workspace prefix for S3 Backend

Fixes #13184
This commit is contained in:
Alex Rowley 2017-06-22 18:17:37 +01:00
parent 2051b286e0
commit db40dc06ab
No known key found for this signature in database
GPG Key ID: C0A11F24C7F74F35
3 changed files with 15 additions and 12 deletions

View File

@ -139,6 +139,13 @@ func New() backend.Backend {
Description: "The permissions applied when assuming a role.", Description: "The permissions applied when assuming a role.",
Default: "", Default: "",
}, },
"workspace_key_prefix": {
Type: schema.TypeString,
Optional: true,
Description: "The prefix applied to the state path inside the bucket",
Default: "env:",
},
}, },
} }
@ -160,6 +167,7 @@ type Backend struct {
acl string acl string
kmsKeyID string kmsKeyID string
ddbTable string ddbTable string
workspaceKeyPrefix string
} }
func (b *Backend) configure(ctx context.Context) error { func (b *Backend) configure(ctx context.Context) error {
@ -175,6 +183,7 @@ func (b *Backend) configure(ctx context.Context) error {
b.serverSideEncryption = data.Get("encrypt").(bool) b.serverSideEncryption = data.Get("encrypt").(bool)
b.acl = data.Get("acl").(string) b.acl = data.Get("acl").(string)
b.kmsKeyID = data.Get("kms_key_id").(string) b.kmsKeyID = data.Get("kms_key_id").(string)
b.workspaceKeyPrefix = data.Get("workspace_key_prefix").(string)
b.ddbTable = data.Get("dynamodb_table").(string) b.ddbTable = data.Get("dynamodb_table").(string)
if b.ddbTable == "" { if b.ddbTable == "" {

View File

@ -14,16 +14,10 @@ import (
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
const (
// This will be used as directory name, the odd looking colon is simply to
// reduce the chance of name conflicts with existing objects.
keyEnvPrefix = "env:"
)
func (b *Backend) States() ([]string, error) { func (b *Backend) States() ([]string, error) {
params := &s3.ListObjectsInput{ params := &s3.ListObjectsInput{
Bucket: &b.bucketName, Bucket: &b.bucketName,
Prefix: aws.String(keyEnvPrefix + "/"), Prefix: aws.String(b.workspaceKeyPrefix + "/"),
} }
resp, err := b.s3Client.ListObjects(params) resp, err := b.s3Client.ListObjects(params)
@ -53,7 +47,7 @@ func (b *Backend) keyEnv(key string) string {
} }
// shouldn't happen since we listed by prefix // shouldn't happen since we listed by prefix
if parts[0] != keyEnvPrefix { if parts[0] != b.workspaceKeyPrefix {
return "" return ""
} }
@ -179,7 +173,7 @@ func (b *Backend) path(name string) string {
return b.keyName return b.keyName
} }
return strings.Join([]string{keyEnvPrefix, name, b.keyName}, "/") return strings.Join([]string{b.workspaceKeyPrefix, name, b.keyName}, "/")
} }
const errStateUnlock = ` const errStateUnlock = `

View File

@ -159,7 +159,7 @@ func TestBackendExtraPaths(t *testing.T) {
} }
// put a state in an env directory name // put a state in an env directory name
client.path = keyEnvPrefix + "/error" client.path = b.workspaceKeyPrefix + "/error"
stateMgr.WriteState(terraform.NewState()) stateMgr.WriteState(terraform.NewState())
if err := stateMgr.PersistState(); err != nil { if err := stateMgr.PersistState(); err != nil {
t.Fatal(err) t.Fatal(err)
@ -169,7 +169,7 @@ func TestBackendExtraPaths(t *testing.T) {
} }
// add state with the wrong key for an existing env // add state with the wrong key for an existing env
client.path = keyEnvPrefix + "/s2/notTestState" client.path = b.workspaceKeyPrefix + "/s2/notTestState"
stateMgr.WriteState(terraform.NewState()) stateMgr.WriteState(terraform.NewState())
if err := stateMgr.PersistState(); err != nil { if err := stateMgr.PersistState(); err != nil {
t.Fatal(err) t.Fatal(err)
@ -202,7 +202,7 @@ func TestBackendExtraPaths(t *testing.T) {
s2 = s2Mgr.State() s2 = s2Mgr.State()
// add a state with a key that matches an existing environment dir name // add a state with a key that matches an existing environment dir name
client.path = keyEnvPrefix + "/s2/" client.path = b.workspaceKeyPrefix + "/s2/"
stateMgr.WriteState(terraform.NewState()) stateMgr.WriteState(terraform.NewState())
if err := stateMgr.PersistState(); err != nil { if err := stateMgr.PersistState(); err != nil {
t.Fatal(err) t.Fatal(err)